|
0x01 漏洞形貌
- 成因:EQNEDT32.exe在解析Matrix record时,并未检查长度,从而造成栈溢出。无论打不打CVE-2017-11882补丁都可以成功触发,使得攻击者可以通过刻意构造的数据内容及长度覆盖栈上的函数返回地址,从而劫持程序流程。
- 影响版本:Microsoft Office 2007, Microsoft Office 2010, Microsoft Office 2013,Microsoft Office 2016
- POC:CVE-2018-0798
0x02 漏洞分析
笔者复现及分析环境:Windows 7 Service Pack 1、Microsoft Office 2010、x64Dbg、IDA 7.0(EQNEDT32.exe已打CVE-2017-11882补丁,但笔者分析时关闭了ASLR)
0x02.1 静态分析
漏洞位于sub_443E34内:

其调用了两次sub_443F6C,但sub_443F6C在复制数据时并未检查传递进来的参数:

此中的数据长度可通过a1控制,具体盘算方法是(2 * a1 + 9) >> 3,而其目的地址是由sub_443E34传递过来位于其开辟栈空间内的局部变量(int型):

如此一来,便可通过精心构造的数据,覆盖sub_443E34函数的返回地址,进而控制执行流。
0x02.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公式编辑器内的第三个漏洞
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
|