内容简介:近来正在学习《漏洞战争》,也是头一回分析二进制漏洞,花了好大一番功夫才搞明白,便想记录下过程。初次分析,若有不正之处,还请多多指教。根据书中给出的信息,漏洞存在于CoolType.dll中,使用IDA Pro反编译CoolType.dll,找到字符串 “SING” ,使用交叉引用功能定位到漏洞代码附近
前言
近来正在学习《漏洞战争》,也是头一回分析二进制漏洞,花了好大一番功夫才搞明白,便想记录下过程。
初次分析,若有不正之处,还请多多指教。
分析环境
Windos XP & Ollydbg & Immunity debugger & IDA Pro & Adobe Reader 9.3.4
分析过程
1.定位漏洞点
根据书中给出的信息,漏洞存在于CoolType.dll中,使用IDA Pro反编译CoolType.dll,找到字符串 “SING” ,使用交叉引用功能定位到漏洞代码附近
但造成漏洞的主要原因是strcat,Adobe Reader在调用strcat时,未对uniqueName字段的字符串长度进行检测,导致可以将任意长度的字符串复制到固定大小的栈空间中,最终导致栈溢出。(摘抄自《漏洞战争》)
2.如何控制EIP
知道从哪可以复制数据到栈中导致栈溢出后,下一步就该考虑该复制多少数据进去才能控制eip。
使用ollydbg附加adobe reader,在0x803DDAB处,也就是call strcat的位置下断点。
使用msf生成样本文件,随后用adobe reader打开,同时触发断点。
执行F8,数据被复制到栈中,目的地址为0x12E4D8
使用immunity debugger的mona插件生成溢出字符串,并复制该字符串到0x12E4D8的位置。
至于为什么是溢出字符串的长度为什么是572字节,其实这里我是抄样本里的数据长度。尝试过用500字节会覆盖函数的返回地址,但并非当前函数,使用600、1000、1200都会触发STACK_BUFFER_OVERRUN异常。主要是想搞明白书中的内容,所以这里也用572字节。
执行F9,触发异常,但此处并未能覆盖EIP
异常信息显示,无法访问[6B413187],为了消除影响,通过计算偏移找到6B413187的位置,然后使用一个可读写的内存地址去替换它。
但如果直接拿6B413187去计算偏移的话是算不出来的,原因在于6B413187并不在我们生成的溢出字符串中。而EAX来源于[ECX+1C],应该拿ECX中的值去计算偏移才对。
找到偏移0×130的位置,将6B41316B替换成一个读写的内存地址,比如0x4A8A08E2,这是书中给出的地址,也可替换成其他的。(0×130也就是十六进制的304)
重新调试,将修改后的溢出字符串再次复制到缓冲区。(缓冲区的起始地址是0x12E4D8,被修改的位置在0x12E608,也就是0x12E4D8+0×130)
执行F9,再次触发异常,且成功覆盖EIP
再次使用immunity debugger的mona插件去计算偏移
重启调试进程,执行完0x803DDAB的call strcat后,在0x12E4D8+0x1F8的位置设置内存断点(0x1F8也就是504的十六进制)
F9继续执行,执行到第三次断点,找到能覆盖EIP的指令。
3.分析ShellCode
知道如何控制EIP后,继续来分析样本中的ShellCode。
重启调试进程,执行完0x803DDAB的call strcat后,在0x12E6D0的位置设置内存断点
多次F9执行到0x808B308,也就是call dword ptr ds:[eax]
F7单步执行call dword ptr ds:[eax],跟入0x4A80CB38
此时的ESP的值为0x12DD24,而溢出字符串的位置在0x12E4D8。shellcode中通过ADD EBP,794; LEAVE;回到原来的栈空间中去。
F7继续执行
而用来绕过DEP的ROP指令和shellcode都存放在堆中,使用POP ESP修改ESP的值为0x0C0C0C0C
F7继续执行到ESP=0x0C0C0C1C,EIP=4A801F90的位置,前面那几条ROP指令暂不清楚作用是什么,尝试过替换掉成其他无意义的指令和去除这几条指令,shellcode依旧能正常运行。
而0x4A801F90正是关键的ROP指令之一,除此之外还有0x4A80B692
EAX中的值指向icucnv36.dll的IAT表,通过提前构造好栈中的参数,再利用POP EAX; JMP DWORD PTR DS:[EAX] 实现函数调用。后面几个函数的调用都是使用这种思路。
第一次调用了Kernel32.CreateFileA函数,其参数为
但后面调用的函数需要用到前一个函数的返回值,shellcode通过以下三条ROP指令将上一个函数的返回值放到下一个函数的参数列表中。
ROP1: XCHG EAX,EDI,此时EAX中存放的正是上一个函数的返回值。
ROP2: POP EBX,EBX中的值将参下一条ROP指令的计算。
ROP3: AND DWORD PTR SS:[EBX*2+ESP],EDI,这里才是将返回值放到参数列表的指令。
第二个调用的函数为Kernel32.CreateFileMappingA,参数列表如下
运用同样的手法调用第三个函数Kernel32.MapViewOfFile,参数列表如下
第四个函数为MSVCR80.memcpy,参数列表如下。位于ESP中的值(0x4F70000)为函数返回地址,也就是Shellcode的位置。
至此,整个shellcode的布局思路也分析得七七八八了。
小结
接下来,讨论下分析过程中的几个问题。
1.为什么ROP指令的地址都在icucnv36.dll的地址空间
这点书中也提到,因为在Adobe Reader的各个版本上这个dll的地址都是不变的。通过对比win7和xp中的icucnv36.dll(同一adobe reader版本),发现只有icucnv36.dll没有开启REBASE,DEP,ASLR,且存在可读可执行的.text段和可读可写的.data段。
2.既然使用500个字节的溢出字符串也能覆盖EIP,那要怎么做才能成功执行shellcode呢?
直接使用POP ESP的地址覆盖返回地址,将ESP设为0x0C0C0C0C即可,后面的都一样了。(测试时并没有发现GS的影子)
3.ROP3中的AND DWORD PTR SS:[EBX*2+ESP],EDI能换成诸如mov、xor吗?
可以,但找不到,尝试过在icucnv36.dll中查找mov、xor、or等指令来替换and,但都找不到。但也许还有其他办法实现该功能。
参考资料
《漏洞战争》 《灰帽黑客》第四版 第12章
*本文作者:wnltc0,转载请注明来自FreeBuf.COM
以上所述就是小编给大家介绍的《小试牛刀之CVE-2010-2883》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。