不知道大家留意没有,昨天的xteam blog中的crash,其实隐含着一个然并卵的0day。这个“0day”,算是我们在构造样本中的副产物。
先看看原始漏洞的情况:在处理mpeg tx3g tag时,chunk_size是64位uint,与size之和溢出,导致实际分配比size小的内存。而后面的memcpy会导致heap overflow,写入的data应该是来自文件内容可控的。
如下是代码:
platform/frameworks/av/+/android-5.1.1_r8/media/libstagefright/MPEG4Extractor.cpp
了解了原理后,我们构造了一个POC,简单地将某个mp4文件中的一个“顺眼的”tag:trak修改为tx3g,于是触发了内存异常。当时还要忙着继续分析就没细看。等到写好文章后发现,这个异常不对啊!怎么还没memcpy就异常了?
于是打开IDA调试一下,结果发现这里的错误实际是一个空指针错误,异常出现在下面text:00063558处,R0=0,读取[R0,#4]发生异常
具体在代码层看,在处理tx3g这个tag时,调用mLastTrack->meta->findData时,meta为NULL
原因是meta初始化发生在trak这个tag处理过程中,所以将trak修改为tx3g,恰好就造成一个这个漏洞。
Libstagefright的代码质量有待加强啊。分析patch构造的POC也能变成一个新的0day!虽然看上去很难利用,但请参考下面的链接的猥琐思路:
http://blog.trendmicro.com/trendlabs-security-intelligence/trend-micro-discovers-vulnerability-that-renders-android-devices-silent/
我们也可以构造类似的网页,引入上述mp4,用户一旦访问下面的网页,锁屏后会发现手机几乎无响应,无法点亮屏幕:
<html> <body onload="setInterval('Crash()',100);"> <video id="crash" src="bw4.mp4" controls="controls"> </video> <script> function Crash(){ var crash = document.getElementById("crash"); crash.load(); crash.play(); } </script> </body> </html>
而要构造原始的libstagefright的这个漏洞中实际分析的POC,可以按照下面的步骤:
首先要让size>0,否则不会进入后面的memcpy流程,这可以通过两个tx3g来构造。第一个tx3g得到size,第二个tx3g,就可以修改之前的size为FFFFFF了。
如下图所示,有个trak,然后是两个tx3g,第一个tx3g前面的size正常,第二个tx3g前面的size为FF FF FF F0,这就造成了溢出。
最终看到的这个异常如下:dlfree已经探测到heap被破坏。
最后给一个利用这个“0day”的视频,这个演示攻击网页还好,要是一个随着开机启动就启动的APP,想想就很开心了…