吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 22616|回复: 91
收起左侧

[漏洞分析] 【Office漏洞 第一弹】CVE-2017-11882及利用样本分析

  [复制链接]
ERFZE 发表于 2020-4-3 09:46

0x01 漏洞描述

  • 成因:Windows的公式编辑器EQNEDT32.EXE读入包含MathType的OLE数据,在拷贝公式字体名称时没有对名称长度进行校验,使得攻击者可以通过刻意构造的数据内容覆盖栈上的函数返回地址,从而劫持程序流程。

  • 影响版本:Microsoft Office 2007 Service Pack 3, Microsoft Office 2010 Service Pack 2, Microsoft Office 2013 Service Pack 1, Microsoft Office 2016

  • POChttps://github.com/Ridter/CVE-2017-11882

0x02 漏洞分析

笔者复现及分析环境:Windows 7 Service Pack 1、Microsoft Office 2010、x32dbg、IDA 7.0

EQUATION.exe存在:

图片1 Equation.exe

设置注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\EQNEDT32.EXE

图片2 regedit.exe

Debugger键值为x32dbg路径。

生成POC:

图片3 POC

打开该文档,于WinExec()函数处设断:

图片4 WinExec

成功断下后,查看栈中返回地址:

图片5 ReturnAdd

继续向上查看栈,发现调用WinExec()的函数:

图片6 Stack

通过IDA分析sub_4115A7功能:

图片7 IDA

跟进sub_41160F查看:

图片8 sub41160F

未校验长度,直接使用strcpy()函数,此处应该就是漏洞触发位置。进一步确定具体位置:

图片9 strcpy

0x411658处设断,重新运行。第二次成功断下后,查看ESI寄存器指向内存内容:

图片10 ESI

此时ECX寄存器值为0xC,即复制48个字节到EDI寄存器指向内存,而var_28实际大小只有36个字节:

图片11 EDI

到达函数结束处:

图片12 FunEnd

leave指令执行完毕后,栈顶0x18F1D0处值为0x430C12,即调用WinExec()。而传递参数正是0x18F350指向内存中的cmd指令:

图片13 shellcode

成功弹出计算器:

图片14 calc.exe


下面对使用到的POC进行简要分析。各变量含义由命名可知,RTF文档格式并非本文重点,如读者此前对RTF文档格式没有了解,建议先阅读文末参考链接中有关RTF文档格式的文章后再看POC源码。

图片15 RTF

首先判断命令长度是否小于43,而43这个数字是因为:

图片16 CmdLen

上图选中部分是插入命令处,具体偏移由POC中COMMAND_OFFSET(0x949*2)变量给出。

将命令插入到构造数据中之后,函数返回拼接好的OLE。下面将OLE嵌入到RTF文档中:

图片17 OLE

0x03 摩诃草(APT-C-09)组织某样本分析

MD5:0D38ADC0B048BAB3BD91861D42CD39DF

0x411658处设断,在第二次断下时,各寄存器值如下:

图片18 register

继续执行到函数结束处leave指令:

图片19 leave

0x18F230地址处值0x430C47即覆盖后的函数返回地址:

图片20 FunReturn

而该地址处指令是ret,有些出乎意料。继续向下执行,来到0x18F3B0处,正是0x18F234地址处值:

图片21 ret

这方才是构造者意欲执行的指令。经过蓝色方框中的一系列运算后,EBX指向是真正的Shellcode:

图片22 shellcode

上述内容均可在OLE中查看(路径\xl\embeddings):

图片23 OLE

图片24 OLE

将OLE0x10000x1520中数据复制到一bin文件后,通过IDA查看。sub_247功能如下:

图片25 IDA

该函数接受的第二个参数即上文提到的EBX指向地址,于OLE中位置是0x1040,而0x1040+0x558处内容如下:

图片26 PE

故该函数第一个功能是修正PE文件头。第二个功能流程如下:

图片27 PEWrite

图片28 PEWrite

图片29 PEWrite

图片30 PEWrite

0x1040+0x558后的PE文件数据写入到%APPDATA%\MSBuild.exe中。第三个功能流程如下:

图片31 RegeditWrite

图片32 RegeditWrite

图片33 RegeditWrite

%APPDATA%\MSBuild.exe写入注册表run项键值lollipop中。

0x04 响尾蛇(SideWinder)组织某样本分析

将文档拖进WinHex查看:

图片34 WinHex

可以看出该文档实质是一RTF格式文档。

rtfobj.py分析如下:

图片35 rtfobj

Package后文会提到,先来看其CVE-2017-11882利用部分。

同样是第二次断下时:

图片36 break

其后的执行流程与上一样本相似:

图片37 leave

图片38 ret

经过绿色方框中的一系列运算后,调用GlobalLock()函数,传递参数如下:

图片39 GlobalLock

接下来跳转到GlobalLock()函数返回内存区域中:

图片40 jmp

经过两次call调用:

图片41 call

图片42 call

修正内存中的字符串:

图片43 EditString

接下来寻址kernel32.dll

图片44 kernel32

其所调用的函数功能如下:

图片45 sub298

两次call调用之后:

图片46 call

图片47 call

其功能为返回某函数调用地址,此次是LoadLibrayW()

图片48 LoadLibrary

图片49 Loadlibrary

接下来,返回GetProcAddress()调用地址:

图片50 GetProcAddress

图片51 GetProcAddress

继续call调用:

图片52 call

其后流程如图所示:

图片53 GetCommandLine

图片54 GetCommandLine

图片55 call

下面将字符串解密,并覆盖原CommandLine内容:

图片56 DecryptStr

图片57 DecryptStr

执行完结果如下:

图片58 StrResult

最后实际执行部分:

javascript:eval("sa=ActiveXObject;ab=new sa(\"Scripting.FileSystemObject\");
eval(ab.OpenTextFile(ab.GetSpecialFolder(2)+\"\\\\1.a\",1).ReadAll());windowclose()")

其后调用RunHTMLApplication()

图片59 RunHTMLApplicaton

图片60 RunHTMLApplicaton

图片61 RunHTMLApplicaton

图片62 RunHTMLApplicaton

图片63 RunHTMLApplicaton

1.a就是之前提到RTF文档中的Package,其实质是一JS文件:

图片64 JS

图片65 JS

最后,其执行结果大体如下图所示:

图片66 result

0x05 蔓灵花(Bitter)组织某样本分析

通过远程模板注入的方式下载一RTF格式文档:

图片67 downloadRTF

拖进WinHex查看,可以确认其格式为RTF文档格式:

图片68 Winhex

添加文件扩展名后,打开该文档。同样是于于0x411658处第二次断下时:

图片69 breakpoint

图片70 ret

图片71 shellcode

跳转之后经过绿色方框中一系列计算,接着跳转:

图片72 jmp

fldpi将π的值加载到FPU堆栈:

图片73 fldpi

执行完后fpu_instruction_pointer指向fldpi指令,其后的fnstenv指令将FpuSaveState结构体保存到esp-0xC处:

图片74 fnstenv

如此一来,pop ebp后EBP寄存器的值是fpu_instruction_pointer——fldpi指令位置:

图片75 EBP

由EBP计算出需要解密的数据起始位置,EDX中存储的是数据长度(0x315):

图片76 Decrypt

接着执行解密后的指令:

图片77 Execute

图片78 Execute

跳转后,执行相应指令,接下来call调用:

图片79 call

sub_562B2F功能是获取指定的系统函数调用地址,此次是kernel32.VirtualAlloc()

图片80 ReturnVirtualAddr

图片81 ReturnVirtualAddr

之后调用VirtualAlloc()申请内存空间:

图片82 VirtualAlloc

向申请的内存空间中写入数据:

图片83 WriteMem

调用sub_562B2F获取kernel32.Wow64DisableWow64FsRedirection()调用地址:

图片84 ReturnWow64DisableWow64FsRedirectionAddr

LoadLibrary(shell32)

图片85 LoadLibrary(shell32)

传递参数给sub_562B2F,获取shell32.ShellExcute()调用地址:

图片86 ReturnShellExcuteAddr

图片87 ReturnShellExcuteAddr

LoadLibrary(urlmon)

图片88 LoadLibrary(urlmon)

获取urlmon.URLDownloadToFile()调用地址:

图片89 ReturnURLDownloadToFileAddr
图片90 ReturnURLDownloadToFileAddr

调用URLDownloadToFile(),其传递参数如图:

图片91 URLDownloadToFile

图片92 URLDownloadToFile

读取文件:

图片93 CreateFile

图片94 ReadFile

由于没有获取到文件,计算出的EBX值错误:

图片95 End

故至此结束。

0x06 参考链接

免费评分

参与人数 43吾爱币 +38 热心值 +39 收起 理由
chased + 1 用心讨论,共获提升!
C至简 + 1 + 1 我很赞同!
guazi1990 + 1 我很赞同!
丨FaceFake + 1 + 1 我很赞同!
19936040638 + 1 + 1 我很赞同!
生而为人. + 1 + 1 我很赞同!
yi025 + 1 + 1 谢谢@Thanks!
wonder2020 + 1 + 1 用心讨论,共获提升!
zhoustar2020 + 1 + 1 我很赞同!
Ghostman66 + 1 + 1 谢谢@Thanks!
ftg512 + 1 + 1 热心回复!
噗pu + 1 用心讨论,共获提升!
Siri丶 + 1 太细了
xiong_online + 1 + 1 用心讨论,共获提升!
海蓝浪花 + 1 + 1 我很赞同!
我忘多 + 1 我很赞同!
柳飘十月 + 1 + 1 我很赞同!
JohnSmith2333 + 1 + 1 用心讨论,共获提升!
jFae + 1 + 1 我很赞同!
chenjingyes + 1 + 1 谢谢@Thanks!
Benteoort + 1 我很赞同!
吹冷风 + 1 久仰大佬
yixi + 1 + 1 谢谢@Thanks!
我爱上这里 + 1 用心讨论,共获提升!
七个涨停一倍 + 1 谢谢@Thanks!
啃一把葱 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Cheremace + 1 + 1 用心讨论,共获提升!
xiayingyu + 1 + 1 用心讨论,共获提升!
dnldnl + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
jayame + 1 + 1 你写这么详细就以为我能看懂?
nexusrao + 1 + 1 只是来发表下赞叹的,牛逼!!!!
fxwl + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
seadragon05 + 1 + 1 我很赞同!
sunptf + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
单程线 + 1 + 1 自信点,把‘感觉’去掉,好厉害啊
basfan + 1 + 1 这种级别的大佬只能仰望了
大叔来了 + 1 + 1 用心讨论,共获提升!
风敲竹 + 1 + 1 谢谢@Thanks!
blindcat + 1 + 1 看不懂,但感觉好厉害
Anekys + 1 + 1 这种级别的大佬只能仰望了
牛逼烘烘~ + 2 + 1 用心讨论,共获提升!
wjooxx + 1 + 1 用心讨论,共获提升!
dliwj + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

JXP98 发表于 2022-9-23 11:00
JXP98 发表于 2022-9-23 10:02
太奇怪了,也是在Win7下x32dbg调的 office 2010,同样的脚本和方法生成的样本。不挂调试器可以弹出计算器, ...

唔..不对用的是2016的,换成2010然后关闭aslr之后可以调出来了..还是很奇怪 没搞清楚哪里出的问题,留坑回头琢磨琢磨
JXP98 发表于 2022-9-23 10:02
太奇怪了,也是在Win7下x32dbg调的 office 2010,同样的脚本和方法生成的样本。不挂调试器可以弹出计算器,挂了调试器之后就弹不出来了...  唉..太菜了 等回头再看看吧
sleony 发表于 2020-4-3 10:06
头像被屏蔽
庞晓晓 发表于 2020-4-3 10:09
最开始学c语言用scanf(),我就以为scanf_s()是多此一举。
IBinary 发表于 2020-4-3 10:30
经典漏洞,分析的不能再分析了.哈哈.  公式编辑器.  栈溢出到Winexec 执行一小段ShellCode
blindcat 发表于 2020-4-3 10:49
看不懂,但感觉好厉害
头像被屏蔽
hsldyx 发表于 2020-4-3 11:09
好吧。我承认我不是专业人士。
sxp3468 发表于 2020-4-3 11:10
外行看热闹
skyfxf 发表于 2020-4-3 11:40
现在还看不懂,希望以后某一天能看懂
大叔来了 发表于 2020-4-3 11:53
膜拜&学习
chishingchan 发表于 2020-4-3 11:57
没仔细看!就算仔细看也没看懂!楼主是世外高人!膜拜!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 22:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表