type
status
date
slug
summary
tags
category
icon
password
 
 

0x01 引言

这道题目利用的是Parcel MisMatch进行漏洞利用,和直接在系统上通过AddAcount利用造成LaunchAnyWhere原理一样,但是有些细节还是不太一样,需要记录一下。

0x02 题目分析

1. Parcel MisMatch

存在Parcel MisMatch 问题的Parcelable 位于MainActivity类中,作为一个子类存在,这个点需要注意,因为如果是这种情况,在构造序列化数据时parcelable数据的数据类名应当为com.de1ta.broadcasttest.MainActivity$Message 而不能将$改为.
问题主要出在this.rttSpread = in.readLong();dest.writeInt((int) this.rttSpread); 类型不匹配,导致在两次序列化和两次反序列化过程中出现问题。

2. 三个广播接收器

题目中有三个继承自BroadcastReceiver 的接收器,其中只有MyReceiver1 是导出的,并且actioncom.de1ta.receiver1 ,另外两个均为非导出,仅能构造恶意序列化数据,构成MyReceiver1.onReceive->MyReceiver2.onReceive->MyReceiver3.onReceive 的调用顺序,在MyReceiver2.onReceive 中绕过对command的检测,在MyReceiver3.onReceive 中使得command = getflag从而拿到flag。
 

3. 两次序列化两次反序列化

这里需要格外注意题目中关于序列化和反序列化点的分析
  • 第一次序列化是攻击者构造恶意Bundle并且将其序列化的过程,实际上可以直接简化为构造parcel序列化数据的过程,构造完成后通过base64传入第一个广播接收器
  • 第一次反序列化 是在MyReceiver2String command = bundle.getString("command"); 时进行的,而非在MyReceiver1 的时进行 bundle.readFromParcel(dest); ,实际上在readFromParcel时仅仅将序列化数据放入Bundle实例的mParcelledData 中,直到此时序列化数据并未被反序列化,而当getString 时需要读取实际的数据而非序列化数据,所以才会取出mParcelledData 中数据反序列化并且将反序列化结果(一个map数据结构) 放入Bundle实例的mMap 中。
  • 第二次序列化 是在MyReceiver2sendBroadcast 时进行,因为在MyReceiver2 通过command校验后需要再次将数据广播,但是实际上在进程间传递的信息只能是序列化数据,所以此时需要进行序列化操作,将mMap中的数据再次进行序列化以进行信息传递。
  • 第二次反序列化 是在MyReceiver3getString 时进行,和第一次反序列化类似。
 

0x03 解题

关于这种漏洞的利用方法,之前已经写blog记录过了,详细的方法和细节请看之前的文章Android反序列化漏洞-Bundle风水因此在这里不再赘述,直接给出poc原理就是第一次反序列化时会读取两个四字节Long,但是第二次序列化会写入一个四字节Int,第二次反序列化又会读取两个四字节Long,中间有四个字节的差,造成偏移后能够隐藏后面的数据。
给出第一次反序列化时被攻击APP的视角,发现第二个键值对中隐藏了command,第三个键值对给了假的command绕过,第二个键值对通过字节数组类型绕过
notion image
给出第二次反序列化时被攻击APP的视角,发现第三个键值对中出现了command = getflag,第四个键值对不再读取,因为mapSize = 3 ,和上面的图对比发现就是0xD8位置的07 00 00 00 被吞掉,造成解析偏移。
notion image
 

0x04 总结

其实关键点还是分析两次序列化两次反序列化的具体位置信息,分析出来然后配合着调试就很容易做。构造方法不止一种,可以自己尝试。
 

0x05 题目

官方在Github上传了题目原件和对应的Docker环境以及WP,有兴趣可以复现
 
CVE-2021-0928漏洞分析CVE-2022-20452-LeakValue
  • Twikoo