[原创]CVE-2012-3569 VMWare OVF Tools 格式化字符串漏洞分析
CVE-2012-3569 VMWare OVF Tools 格式化字符串漏洞很多人都不陌生,是一个典型的win32平台格式化字符串漏洞。在本文分析中,通过一个触发异常的样本,分析了格式化字符串漏洞利用的技巧,在此基础上实现了漏洞的成功利用。
0x01实验环境
推荐使用环境 | 备注 |
Windows xp | 简体中文版 |
VM VirtualBox | 版本号:4.2.6 r82870 |
OllyDbg | 版本号:V1.10 |
VMware OVF TooL | 版本号:2.1.0-467744 |
0x02调试过程
运行OllDbg,并加载ovftool.exe,点击菜单”Debug-Arguments”,在弹出命令行参数对话框中,填写与ovftool.exe位于同一目录下的poc.ovf样本文件,让后重新开始调试程序。按F9运行,程序出现访问违例异常。
从异常信息可以看出,产生异常的原因是执行0x00000000处的指令出现访问违例。
在0x0057EAE7和0x0057EAF5处设置断点,重新运行该程序。在0x0057EAE7处中断,单步执行,观察寄存器中的值,发现在执行完0x0057EAE7处的MOV EAX,DWORD PTR DS:[EAX+EDI*8]后,EAX的值为0012FF50。执行完0x0057EAEA处的MOV CX,WORD PTR SS:[EBP-B4]后,CX的值为0x0345。

执行完0x0057EAF5处的MOV WORD PTR DS:[EAX],CX后,0x0012FF50处的值为0x00120345。

继续F8单步执行,一直执行到0x00580327处的retn指令,返回上一层调用的函数。


继续F8单步执行,直到执行完0x004186F8处的MOV ESP,EBP指令,此时ESP的值为0x00120345。观察栈中0x00120345附近的值为0x00000000。
继续单步依次执行0x004186FA处的POP EBP指令,此时ESP的值为0x00120349,当执行0x004186FB处的RETN指令后,EIP寄存器指向0x00000000,出现访问异常。
在上面的调试过程中,单步执行到0x0057CBBA处的retn时,EAX保存着提示错误的字符串。
继续回溯,执行完0x0056B684处的CALL ovftool.0056B5F0后,控制台显示提示错误字符串。
打开样本poc.ovf,观察ovf:capacityAllocationUnits的值。
ovf:capacityAllocationUnits的值中共有26个‘A’和98个‘%08x’,决定了输出字符串中从字符‘A’开始共810(26+98*8=810)个字符。在控制台输出的字符中,“ Line 14: Invalid value ’”字符串恰好是27个字符,控制台输出的字符串共837个字符。在MOV WORD PTR DS:[EAX],CX中,CX=0x0345=837(十进制),EAX=0x0012FF50。从而得出结论:‘A’和‘%08x’的个数决定了输出字符串的长度,CX保存着输出字符串的长度。经过实验发现%08x的个数决定了EAX(这里是0x0012FF50)的值,这是格式化字符漏洞的核心。MOV WORD PTR DS:[EAX],CX后,0x0012FF50处的值变为0x00120345,而0x00120345附近的值为0x00000000,后续的函数回溯过程中的RETN操作,恰好使EIP指向0x00000000,产生访问异常。
以上调试过程分析了异常产生的原因,可以设想通过覆盖0x004186FB处RETN指令执行前栈帧中的返回地址,劫持秩序执行流程,从而实现漏洞利用。因此,可以构造一个典型的格式化字符串漏洞利用exploit。
下面,分析exploit的构造过程。经过上面的分析得知,可以通过覆盖0x004186FB处RETN指令执行前栈帧中的返回地址,劫持秩序执行流程,这里采用call esp 指令的地址覆盖返回地址。用shellcode覆盖poc.ovf样本中的AAAA…字符串,整个exploit布局为:填充字符串+call esp 地址+shellcode+98个%08x+%hn。
shellcode写入栈中时,确保写入到内存低址(抬高栈顶),一是防止写入数据破坏原有栈帧,二是防止出栈入栈操作破坏shellcode。
通过分析得知,ovftool在处理字符串时是以0x1000为单位分组进行的。在栈中利用二进制串查找功能,确定capacityAllocationUnits值字符串复制到栈中的起始位置位置为0x00116B48,通过增加填充字符使 call esp 地址0x7852753D位于栈中0x00121004处,填充字符个数为0x00121004-0x00116B48=0x0000A4BC=40172(十进制)。
所以exploit布局为:40172个填充字符+call esp 地址+shellcode+98个%08x+%hx,其中shellcode后半部分与98个%08x合起来总的字符数是0x1000。

可以看出, CX=0x1000,表示最后一组输出字符的个数为0x1000,即shellcode后半部分与98个%08x合起来总的字符数为0x1000。

0x00121004处保存着call esp地址0x7852753D(对应的ASCII为=uRx)。

可以看出已经成功覆盖0x004186FB处RETN指令执行前栈帧中的返回地址。

成功劫持程序执行流程。
0x03 总结
该漏洞是典型的格式化字符串漏洞,本次成功利用的关键有三点:一是通过回溯确定要覆盖的函数返回地址,该地址由输出的字符个数决定(0x1000);二是要覆盖函数返回地址保存在EAX中(EAX=0x0012FF50),而EAX的值由%08x的个数决定。三是确定了覆盖的返回地址0x00121004后(retn之前有pop ebp操作,使得call esp 要覆盖的地址为0x00121004),要确定在内存中如何布局exploit。
此外,由于ovftool处理的都是ASCII字符串,要实现特定功能的exploit,就要实现shellcode的 ASCII编码。





