Bundle的序列化细节看上去还是有些复杂的,在之前已经讨论过,一般我们使用Parcel的时候,都是严格的write和read相对应。一些疏漏,不对应,竟然就可以成为漏洞,
https://xz.aliyun.com/t/2364 里介绍了Bundle漏洞的情况,详情可以去查看,
这里补充一些理解,
引用里面的原理图,
Bundle可以存储map键值对,存储 key-value数量 key1 value1 key2 value2 ...
根据key-value数量来控制读的次数,来进行反序列化。
当恶意bundle中存的data有
第一个key-value存储的是有bug的对象,这里是PeriodicAdvertisingReport
@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeInt(syncHandle);dest.writeLong(txPower);dest.writeInt(rssi);dest.writeInt(dataStatus);if (data != null) {dest.writeInt(1);dest.writeByteArray(data.getBytes());} else {dest.writeInt(0);}}private void readFromParcel(Parcel in) {syncHandle = in.readInt();txPower = in.readInt();rssi = in.readInt();dataStatus = in.readInt();if (in.readInt() == 1) {data = ScanRecord.parseFromBytes(in.createByteArray());}}
txPower的读写类型不一致,会造成错位。
系统中的这样有漏洞的Parcelable对象会被这样利用起来作为错位工具。
构造恶意Bundle,使用了特意的组装,而不是调用Parcelable对象里定义的构造方法。
pcelData.writeString("mismatch");pcelData.writeInt(4); // VAL_PACELABLEpcelData.writeString("android.bluetooth.le.PeriodicAdvertisingReport"); // name of Class LoaderpcelData.writeInt(1);//syncHandlepcelData.writeInt(1);//txPowerpcelData.writeInt(1);//rssipcelData.writeInt(1);//dataStatuspcelData.writeInt(1);// flag for data
就这样,错位后的结构中,原内容里的
如同这样一个命令字串,
aaaabb'2.cccc
dddd
第一条数据是aaaabb'2.cccc
第二条数据是dddd
当解析错位,以为2.cccc 是第二行,就会以为第二条数据是cccc
这个和sql注入有些相似。
一些不经意的漏洞,就会被别有用心的人利用,甚至做出更加卑劣的行为。
这里可以看出,Parce的读写要规范,不遵守规范,各种机缘巧合或者机关算尽下,就会出现匪夷所思的问题,如下面这个汽车上树。
参考资料
https://xz.aliyun.com/t/2364
https://blog.csdn.net/u010206565/article/details/129020951
上一篇:2.线性表的顺序表示