坐在飞往温哥华的飞机上,这是我去东京Pwn2Own的第一站,我决定打开笔记本分析我们之前在另一个Pwn2Own上收到的漏洞,屏幕上的JavaScript代码似乎吸引到了旁边座位的人,他问我这是JavaScript语言吗,我说是的。他问我是在读代码吗,我回复说我正在学习JavaScript,不得不说一定程度上这是一个挑衅的回答。完成一个函数的注释后,我合上笔记本准备休息一下。我想到了我刚才“我正在学习”的回复,我确实是在学习,不过我是在学习其他人在写漏洞利用时是如何思考的。
我准备分析的漏洞利用是360 Codesafe团队在2017年写的Adobe Reader PDF的一个漏洞利用,选择分析这个exploit有几个原因:首先,它利用了JPEG2000解析过程中的一个堆溢出漏洞(ZDI-17-280),其次,它缺乏相关文档和注释。实际上,甚至用来触发或利用bug的JavaScript代码也没有被清楚地描述,我不得不从他们提供给我们的PDF漏洞中提取代码。最后一个理由,我是Adobe Reader的超级粉丝,还不错吧。
在这篇博文中,我将介绍360利用Adobe Reader中基于堆的缓冲区溢出漏洞的技术。在他们最初的提交中,他们使用了一个内核的漏洞来做沙箱逃逸,这篇文章对不会涉及内核漏洞部分,只关注Adobe Reader相关部分
相关细节
我用来分析这个漏洞的Reader版本是2015.023.20070,可以从Adobe的FTP服务器上获取。
很明显,进行漏洞分析的第一步是从PDF中提取用于利用漏洞的JavaScript代码。这步操作有很多种方法可以实现,去编写一个Python脚本来达到目的并不是很复杂,额,实际上这个脚本效果很好。如果你对脚本和Python不怎么感兴趣,你可以使用Foxit Phantom PDF工具来提取。
提取代码结束后,我们就获得了超量的JavaScript代码,我尝试把shellcode剥离出来以增加可读性,代码由以下指令开始:
这里没什么特别的,设置了几个变量然后调用memory1函数,之后又设置了几个变量然后调用memory2。
那么memory1和memory2函数是什么东西呢,我们先来看看memory1:
该函数分配一个大小为len2的数组,并将第一个元素(我称之为标记元素)设置为0x11223344,之后用大小为len1的arraybuffer填充数组,最后进入另一个循环,在数组中delete一些元素,像是在数组上戳洞,看起来很像下面的场景: