记一次VMware的瓦解调试剖析历程
宣布时间 2020-08-111.研究配景
使用WinDbg-I指令将WinDbg设置为即时调试器,,,,,,VMware-vmx.exe程序瓦解后自转动出WinDbg。。。。。。客栈信息如下:
调试信息显示stack buffer overrun异常,,,,,,最初推断可能是缓冲区溢出误差。。。。。。

通过盘问资料后发明,,,,,,从Windows 8最先,,,,,,Windows设计了一个新的中止INT 29H,,,,,,用以快速抛出失败,,,,,,在sdk中被声明为__fastfail,,,,,, __fastfail内部函数不会返回。。。。。。
在上图中,,,,,,程序终止于int 29h,,,,,,而它的参数为0xa,,,,,,对应FAST_FAIL_GUARD_ICALL_CHECK_FAILURE,,,,,,由此推断问题可能泛起在CFG的检查历程中。。。。。。
从函数挪用栈中vmware_vmx+0x58b21地点向上追溯,,,,,,动态调试程序,,,,,,较量程序正常运行与异常瓦解的函数挪用区别,,,,,,定位到与程序瓦解相关的函数sub_1400965A0。。。。。。
使用Windbg Attach vmware-vmx.exe程序,,,,,,在sub_1400965A0函数设置断点,,,,,,最先动态调试。。。。。。从7z翻开的压缩文件中拖拽cdp.pcapng的文件,,,,,,程序在断点处停下。。。。。。通过动态调试可知该函数中calloc分派了三个堆空间,,,,,,划分用于存放:主机暂时文件路径temp_path、目的文件名file_name以及VMware中的缓存目录名vm_cache_dir_name。。。。。。
可是翻开主机Temp目录下却没有发明该文件,,,,,,于是起源断定这是程序瓦解缘故原由。。。。。。继续往下看,,,,,,3个文件相关参数全都传入了sub_140579b30函数。。。。。。
进入函数sub_140579b30,,,,,,定位temp_path参数的处置惩罚。。。。。。其中,,,,,,sub_14057FF90函数对传入的temp_path举行了逐一遍历,,,,,,sub_1405B2080函数对传入的temp_path举行了不法性检查。。。。。。下面重点剖析sub_140576460函数。。。。。。
sub_140576460函数将路径参数temp_path传入了sub_14049DA50。。。。。。
首先,,,,,,函数sub_14049DA50通过sub_140477C70对字符串举行了处置惩罚。。。。。。然后,,,,,,挪用wstat64获取响应路径的文件状态,,,,,,若是乐成获取则生涯到一个结构体中,,,,,,不然返回0xffffffff。。。。。。由于Temp目录下并未发明备份文件,,,,,,导致获取状态失败,,,,,,从而返回0xffffffff。。。。。。
返回0xffffffff后,,,,,,重新回到sub_140579b30函数中,,,,,,程序跳出while循环抵达如下位置,,,,,,输蜕化误信息并跳转至sub_140572A70。。。。。。
从sub_140572A70最终执行到sub_1400960C0,,,,,,抵达如下位置将vmware_vmx+0xb1ed90处的值赋给了rsi,,,,,,即为0。。。。。。
继续往下执行,,,,,,将rsi中0值赋值到rax中,,,,,,然后挪用0x7ff8fab0c510处,,,,,,即ntdll!LdrpDispatchUserCallTarget。。。。。。
此处与静态下的历程有一点差别,,,,,,静态下该处挪用如下:
若是凭证静态历程执行,,,,,,应当抵达sub_1407C7650,即如下位置:
在ntdll.dll被加载之前,,,,,,该处数据依旧为上图所示地点:
厥后在ntdll.dll中实验CFG(ControlFlowGuard)保唬护机制,,,,,,将vmware_vmx+0x7c9668地点处数据举行了改写,,,,,,从而执行到ntdll!LdrpDispatchUserCallTarget中。。。。。。
在ntdll!LdrpDispatchUserCallTarget函数中,,,,,,取r11+r10*8处的值赋值给r11时泛起了问题,,,,,,该地点为空,,,,,,就造成了空指针引用,,,,,,从而执行了int 29h,,,,,,造成异常。。。。。。然而,,,,,,纵然没有CFG机制,,,,,,程序也会在执行“jmp rax”处瓦解,,,,,,通过下图可以看出,,,,,,CFG机制仅仅是在原本程序跳转指令前添加了一些检查。。。。。。
至此,,,,,,VMware瓦解的缘故原由基天职析清晰了。。。。。。另一个疑问是,,,,,,为什么7zip已经在系统Temp下天生了文件,,,,,,并且VMware也已经获取到了路径参数,,,,,,却在移动前自动删除了文件呢。。。。。。这就需要从7zip中寻找谜底。。。。。。
由上一节剖析可知,,,,,,Vmware crash缘故原由是Temp目录下文件被删除。。。。。。阅读7zip源码,,,,,,锁定了CPP/Windows/FileDir.cpp中的文件删除函数。。。。。。
使用WinDbg加载7zip,,,,,,然后在Remove函数位置举行下断,,,,,,程序运行后举行拖拽操作,,,,,,在Remove函数中止后对应的挪用客栈如下所示。。。。。。
客栈中7zFM+0x5b212地点位于函数CPanel::OnDrag中,,,,,,该函数为鼠标拖拽操作函数。。。。。。当检测到对7zip翻开的目录举行操作时,,,,,,便会在Temp目录下天生一个以7zE开头的随机命名文件夹。。。。。。
然后,,,,,,将该文件夹设置为目的目录,,,,,,并且设置了一些数据及IpDropSourse结构体。。。。。。
继续往下可以看到一个DoDragDrop函数,,,,,,该函数功效是举行OLE拖放相关操作,,,,,,通过检测光标的行为划分挪用一些要领并返回对应的数值。。。。。。
然后,,,,,,凭证DoDragDrop函数的返回值来判断光标的拖拽是否有用,,,,,,从而执行对应的操作。。。。。。
从7zip中拖拽文件到虚拟机,,,,,,由于无法获知文件拖拽的目的路径,,,,,,因此DoDragDrop会返回DRAGDROP_S_CANCEL(0x40101),,,,,,不会执行拷贝操作的分支,,,,,,而是直接将Temp目录下天生的暂时目录删除。。。。。。
7zip压缩包中文件拖拽操作会触发DoDragDrop函数挪用,,,,,,该函数会获取文件数据及光标阻止的位置。。。。。。可是将文件拖拽到VMware窗口时,,,,,,DoDragDrop函数不可获取准确的目的路径,,,,,,因此无法将文件拷贝到目的位置,,,,,,从而直接删除暂时文件,,,,,,最终导致VMware无法获取文件状态造成瓦解。。。。。。
参考链接:
[1]https://0cch.com/2016/12/13/int29h/
[2]https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-dodragdrop
[3]https://github.com/kornelski/7z/tree/20e38032e62bd6bb3a176d51bce0558b16dd51e2
凯旋国际游戏起劲防御实验室(ADLab)
ADLab建设于1999年,,,,,,是中国清静行业最早建设的攻防手艺研究实验室之一,,,,,,微软MAPP妄想焦点成员,,,,,,“黑雀攻击”看法首推者。。。。。。阻止现在,,,,,,ADLab已通过CVE累计宣布清静误差近1100个,,,,,,通过 CNVD/CNNVD累计宣布清静误差900余个,,,,,,一连坚持国际网络清静领域一流水准。。。。。。实验室研究偏向涵盖操作系统与应用系统清静研究、移动智能终端清静研究、物联网智能装备清静研究、Web清静研究、工控系统清静研究、云清静研究。。。。。。研究效果应用于产品焦点手艺研究、国家重点科技项目攻关、专业清静效劳等。。。。。。