查看原文
其他

CVE-2018-0798及利用样本分析

看雪学院 2021-03-07

The following article is from Gcow安全团队 Author 复眼小组

本文为看雪论坛精华文章
看雪论坛作者ID:erfze


0x01 漏洞描述


成因:EQNEDT32.exe在解析Matrix record时,并未检查长度,从而造成栈溢出。无论打不打CVE-2017-11882补丁都可以成功触发,使得攻击者可以通过刻意构造的数据内容及长度覆盖栈上的函数返回地址,从而劫持程序流程。

影响版本:Microsoft Office 2007、Microsoft Office 2010、Microsoft Office 2013、Microsoft Office 2016

POC:CVE-2018-0798(https://github.com/houjingyi233/office-exploit-case-study/blob/master/CVE-2017-11882%26CVE-2018-0802%26CVE-2018-0798/cve-2018-0802%20poc%20with%20comments.rtf)


0x02 漏洞分析


笔者复现及分析环境:Windows 7 Service Pack 1、Microsoft Office 2010、x64Dbg、IDA 7.0(EQNEDT32.exe已打CVE-2017-11882补丁,但笔者分析时关闭了ASLR)

>>>>

1、静态分析


漏洞位于sub_443E34内:
 
 
其调用了两次sub_443F6C,但sub_443F6C在复制数据时并未检查传递进来的参数:
 
 
其中的数据长度可通过a1控制,具体计算方法是(2 * a1 + 9) >> 3,而其目的地址是由sub_443E34传递过来位于其开辟栈空间内的局部变量(int型):
 
 
如此一来,便可通过精心构造的数据,覆盖sub_443E34函数的返回地址,进而控制执行流。

>>>>

2、动态调试


POC地址已于上文给出。直接于sub_443E34处设断,成功断下后,直接执行到调用sub_443F6C前查看其传递参数:
 
 
跟进查看,可以看到其计算后的实际复制数据长度:
 
 
跟进其调用的sub_416352可以查看要复制数据:
 
 
直接执行到sub_443F6C结束处,可以看到:
 
 
sub_443E34再次调用sub_443F6C,其执行流程同上:
 
 
 
 
可以看到,已经覆盖栈上sub_443E34的返回地址,劫持了执行流:
 
 
回到sub_443E34,直接执行到结束处:
 
 
通过ROP跳转到WinExec():
 
 
成功弹出计算器:
 


0x03 Bitter组织某样本分析


样本名称:Urgent Action.docx

样本MD5:02C2A68CE9A35F5F0E1B3456E09D6CC9

通过远程模板注入的方式下载一RTF格式文档:
 
 
使用WinHex查看,确为RTF格式:
 
 
添加.rtf后缀后打开文档。直接来到sub_443E34调用sub_443F6C处:
 
 
此次调用sub_443F6C并未发生溢出,其复制数据长度如下:
 
 
复制内容:
 
 
其第二次调用sub_443F6C,发生溢出:
 
 
复制内容:
 
 
接下来直接执行到sub_443E34结束处,可以看到其劫持执行流:
 
 
通过ROP跳转到Shellcode:
 
 
Shellcode如下:
 
 
下面开始分析其功能。首先是计算跳转地址:
 
 
跳转之后,通过与计算出的EAX值比较的方式移动指针指向要复制的Shellcode,复制后跳转到Shellcode上执行:
 
 
通过PEB手动符号解析定位到kernel32.dll:
 
 
定位kernel32.dll中的GetProcAddress()函数:
 
 
跳转后执行GetProcAddress():
 
 
 
之后通过call调用的形式给CreateDirectory()传递参数:
 
 
于C盘创建一名为Temp的文件夹。获取LoadLibrary()调用地址:
 
 
之后在call调用的同时传递参数:
 
 
 
接着再次call调用,先修正内存中的字符串,接着获取URLDownloadToFile()函数调用地址:
 
 
 
通过两次call调用来给URLDownloadToFile()函数传递参数:
 
 
 
 
之后调用URLDownloadToFile()函数从http://maq[.]com[.]pk/wehs下载文件到创建的Temp文件夹内,文件名为smss:
 
 
call调用的同时向GetProcAddress()传递参数,获取MoveFile()调用地址:
 
 
两处call调用向MoveFile()传递参数:
 
 
将smss重新命名为smss.exe。之后获取LoadLibrary()调用地址:
 
 
call调用的同时传递参数:
 
 
获取ShellExecute()调用地址:
 
 
通过三次call调用来给ShellExecute()传递参数,最后调用之:
 
 
接下来执行的smss.exe,非本文重点,故不分析。


0x04 xx组织某样本分析


写文章截图的时候中途断过两次,故前后文某些地址(使用这些地址只是为了方便说明)不对应,望读者谅解。

另,此样本在打了CVE-2017-11882补丁的机器上无法被成功利用。
 
直接定位到漏洞触发点:
 
 
 
 
第二次调用sub_443F6过程如下:
 
 
 
 
可以看到,栈上函数返回地址已经被覆盖:
 
 
但其并未直接执行到sub_443E34结束处,而是通过给其后调用的函数传参,再次执行sub_443E34(其调用函数的具体功能可结合IDA进行分析):
 
 
 
 
 
 
下面来看第二次执行sub_443E34时调用sub_443F6的情况:
 
 
 
 
 
 
 
直接执行到sub_443E34结束处:
 
 
其后执行流程:
 
 
此处的jmp 2911D4值得说明一下,2911D4后20字节是在调用sub_4428F0时由qmemcpy((void *)(v5 + 50), a4, 20u);复制而来,其中源地址是0x18F3EC(可见图片54)。
 
计算接下来的跳转地址:
 
 
跳转到解密Shellcode部分:
 
 
解密Shellcode:
 
 
其后执行流程见下图(图中序号仅为表明顺序,并无他意):
 
 
手动符号解析定位msvcrt.dll(由cmp语句比较的ASCII码可计算出)。
 
 
手动符号解析定位kerner32.dll(图中序号接上一张图片)
 
之后其调用的sub_299122如下:
 
 
通过遍历msvcrt.dll的输入表查找GetProcAddress,它并非调用kernel32.dll的GetProcAddress(),而是ntdll.dll的LdrGetProcedureAddress():
 
 
再一次调用sub_299122,此次查找的是VirtualProtect():
 
 
 
 
调用GetProcAddress()返回msvcrt.clearerr的地址:
 
 
调用VirtualProtect()修改msvcrt.clearerr页属性为0x40(PAGE_EXECUTE_READWRITE),大小是0x50:
 
 
对msvcrt.clearerr进行Inline Hook,修改指令长度为0x50,这解释了之前的修改页属性操作:
 
 
其实msvcrt.clearerr要实现的功能与sub_6492C6相同(详见图片77、78):
 
 
调用VirtualProtect()修改msvcrt.clearerr页属性为0x20(PAGE_EXECUTE_READ),大小是0x50。
 
 
将返回的调用地址加5后,通过遍历msvcrt.dll的输入表查找CreateFile:
 
 
 
此次是查找VirtualAlloc:
 
 
接下来所查找函数不一一截图,依次是ReadFile、WriteFile、CloseHandle、CreateProcess、GetModuleFileName、ResumeThread、TerminateProcess。
 
 
其后传递给GetProcess的参数不再一一截图,依次是ReadProcessMemory、VirtualQueryEx、VirtualProtectEx、GetModuleHandle、VirtualAllocEx、WriteProcessMemory、SetThreadContext、ZwUnmapViewOfSection。
 
调用GetTempPath():
 
 
之后将其于临时文件夹内释放的文件名拼接到路径后:
 
 
打开该文件:
 
 
其后行为不再一一截图,依次是GetFileSize(获取该大小)、VirtualAlloc(0,0x3E000,0x3000,0x40)(分配空间)、ReadFile(读取文件到分配的空间内)。
 
解密内存中的文件内容:
 
 
遍历文件句柄,找到符合下列条件的文件:
 
 
 
调用VirtualAlloc分配空间并写入内容(并非解密后的文件内容):
 
 
 
 
复制解密后的文件内容:
 
 
之后创建一同名进程:
 
 
 
其后的部分行为见下图:
 
 
 
 
将解密后的文件内容写入创建的进程:
 
 
最终,结束原进程:
 
 
解密后的文件会在临时目录释放两个文件("白加黑")并运行之:
 


0x05 参考链接


手把手教你复现office公式编辑器内的第三个漏洞(https://www.anquanke.com/post/id/94841)



- End -





看雪ID:erfze

https://bbs.pediy.com/user-817966.htm 

*这里由看雪论坛 erfze 原创,转载请注明来自看雪社区。


推荐文章++++

*  手把手教你入门V8突破利用

*  Android微信逆向-实现发朋友圈动态

*  病毒样本半感染型分析的方法

*  对宝马车载apps协议的逆向分析研究

*  x86_64架构下的函数调用及栈帧原理


好书推荐







公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com



“阅读原文一起来充电吧!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存