记一次VMware的瓦解调试剖析历程

宣布时间 2020-08-11

1.研究配景


VMware Workstation是一款主流的虚拟机软件 ,近期酷游官网ADLab清静研究员在使用VMware虚拟机的历程中遇到虚拟机异常瓦解的问题 ,当从7zip中直接将文件拖拽到VMware虚拟机中 ,会造成虚拟机异常关闭。现在已测试过VMware 15.5.0、15.5.2、15.5.5 以及7zip 19.0、20.02等版本。本文将通过对VMware和7zip程序举行跟踪剖析 ,最终定位虚拟机异常关闭缘故原由。

2.VMware端调试剖析

使用WinDbg-I指令将WinDbg设置为即时调试器 ,VMware-vmx.exe程序瓦解后自转动出WinDbg。客栈信息如下:



调试信息显示stack buffer overrun异常 ,最初推断可能是缓冲区溢出误差。



通过盘问资料后发明 ,从Windows 8最先 ,Windows设计了一个新的中止INT 29H ,用以快速抛出失败 ,在sdk中被声明为__fastfail , __fastfail内部函数不会返回。


系统结构
指令
代码参数的位置
x86
int 0x29
ecx
x64
int 0x29
rcx
ARM
操作码 0xDEFB
r0


在上图中 ,程序终止于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中寻找谜底。


3.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目录下天生的暂时目录删除。



4.小 结


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清静研究、工控系统清静研究、云清静研究。研究效果应用于产品焦点手艺研究、国家重点科技项目攻关、专业清静服务等。


lab.jpg