首页
论坛
课程
招聘
雪    币: 14285
活跃值: 活跃值 (93)
能力值: (RANK:327 )
在线值:
发帖
回帖
粉丝

[调试逆向] [病毒木马] [.NET平台] [原创]CVE-2017-11882理论以及实战样本分析

2019-12-27 14:36 2652

[调试逆向] [病毒木马] [.NET平台] [原创]CVE-2017-11882理论以及实战样本分析

2019-12-27 14:36
2652

0x00 前言

最近看了一点非PE的样本,发现CVE-2017-11882这个漏洞在实战中的使用非常频繁,有很多在活的APT组织都还在使用,之前都是直接去捕获利用该洞释放的文件,最近有时间,就对11882进行一个完善一点的跟踪。
11882属于Office Equation类型的漏洞,2017年底发现,目前使用较多的有11882,0802,0798三个漏洞,今天先分析一下11882的漏洞原理,以及实战中遇到的两个样本。

0x01 POC复现

这个漏洞的poc有很多,这里使用的是https://github.com/Ridter/CVE-2017-11882/
通过python Command_CVE-2017-11882.py -c "cmd.exe /c calc.exe" -o test.doc命令生成test.doc
然后在安装了office2013上的机器打开,弹出了计算器。
图片描述

调试样本

在调试这个样本之前
先以一个简单的例子说明一下程序是如何利用esp和ebp实现函数调用的
下面是一段很简单的汇编代码,如下图所示,目前eip指向0040108E,指令是call 999.00401005
esp指向0012FF20(当前函数栈顶)
ebp指向0012FF80(当前函数栈底)
图片描述

 

F7跟进到call里面之后,ebp没变,esp-4变成了0012FF1C
0012FF1C地址存放了00401093地址,该地址是当前函数的调用完之后应该继续执行的地址
所以我们大多数情况下可以将call执行理解为push 返回地址 然后jmp 到函数起始地址的两条指令的集合
图片描述

 

然后程序通过
push ebp
mov ebp,esp
sub esp,0x44
首先保存之前的ebp,然后把esp的值赋值给ebp,现在esp和ebp就指向同一个地方了
再通过对esp的sub运算开辟出当前函数使用的新堆栈
图片描述
可以看到,现在ebp指向0012FF18,该地址里面存的的值是0012FF80,是之前的ebp,该地址后面就是函数的返回地址

 

程序最后通过
mov esp,ebp
pop ebp
retn
的组合指令作为返回
因为ebp后面就是函数的返回地址,所以这里先通过mov指令,将ebp的值赋值给esp,然后pop ebp,这pop指令执行完之后,esp的值就会+4,esp就会指向之前的返回地址
再通过ret指令就可以成功返回
图片描述

 

好,现在来看看这个样本。
首先直接打开word程序:
图片描述

 

在插入选项下,选择对象,然后插入Microsoft公式3.0
图片描述

 

现在启动x32dbg,选择文件->附加:
图片描述

 

因为我们这里知道文档运行之后会打开计算器,所以附加上EQNEDT32.exe之后通过分别给CreateProcessA和CreateProcessW设置断点
图片描述

 

F9跑起来,然后使用word打开poc生成的test.doc文档,打开之后成功断下来:
图片描述

 

在返回地址处设置断点,返回回去发现计算器已经弹出了,这里可以通过ebp查看一下CreateProcess的调用
图片描述

 

返回回来发现是WinExec函数调用的
图片描述

 

所以重新按照上面的方法,对WinExec函数下断:
图片描述

 

此时的00430C12是用户态地址,按道理来讲,ebp应该存放了当前函数的返回地址,但是这里是41414141,很明显ebp已经被破坏了。
图片描述
所以我们向上看看,ebp是在哪儿被破坏的。

 

由于ebp被淹没,我们这里往上看,找找其他的返回地址:
图片描述

 

这里最近的一个返回地址是在00411837,返回回去,往上翻,找到00411837所在函数的起始地址,设置一个断点,重新运行,让程序断在这个函数里面。
图片描述

 

往下走几步在00411658的地方发现这样一条指令:
rep movsd dword ptr es:[edi], dword ptr [esi]
该指令执行完之后,ebp就被41414141覆盖
而该指令的功能是将esi的值传送到edi所指的位置。
我们分别查看一下esi和edi的值:
ESI:
图片描述

 

EDI:
图片描述

 

值得注意的是,此时ebp的值是0018F1D0
很明显该地址在EDI所指的地址后面
图片描述

 

rep movsd dword ptr es:[edi], dword ptr [esi]执行完之后,EDI被成功赋值,可以看到,此时ebp所在的值已经从0018F214变成了41414141
ebp后面的返回地址已经从004115d8更改为了00430c12
图片描述

 

查看一下00430C12地址:
图片描述

 

OK原来是这样跳过来的,过来执行WinExec函数之后,又在里面调用了CreateProcess函数,函数的参数为:
图片描述
所以成功弹出计算器。

eqnedt32.exe

我们把EQNEDT32.exe拷贝出来,先查看下属性,可以看到,这是一个2000年发布的程序,一直没有被更新过。
图片描述

 

通过对上面样本的分析,我们已经知道该漏洞的触发点是在00411658处
我们通过IDA打开eqnedt32.exe并跳转到该地址处
图片描述

 

F5看一下
图片描述
漏洞的原理很简单,漏洞的导致原因是strcpy函数在使用的时候,未对参数的长度进行判断和限制,从而导致栈溢出。
而至于流程到底是怎么过来的,以及文档格式的其他分析之后再单独写一个文章介绍。

实战样本分析

原始样本

样本hash:14F28BD8361AE90DBFABCB31767A356B
VT上搜索该样本,可以发现样本已经被打上了11882的标签:
图片描述

 

我们来调试一下,看看这个到底是不是11882的利用。
winhex打开,该文档的确是rtf:
图片描述

 

我们通过上面的分析已经知道,11882的漏洞触发点在0041160F函数中,具体的位置应该是00411658
就还是通过之前的方法附加EQNEDT32.exe,然后在0041160F函数设置一个断点:
图片描述

 

F7进入到函数内部,堆栈初始化之后正常:
图片描述

 

往下走,来到触发漏洞的地方:
图片描述

 

通过之前的分析可以知道,这里是会将ESI地址所指的值赋值给EDI所指的值,而EDI所指的值后面就是EBP的地址,如果没有对ESI所指的值长度进行限制,这里拷贝过去之后就会覆盖掉EBP的地址
EDI的地址为0018F1A8,目前内容如下
图片描述

 

执行语句后EDI内容如下:
图片描述

 

这里的0018F1A8一看就是shellcode
我们跳转过来看一下,代码如下:
图片描述

 

代码解密出来之后,会尝试通过 URLDownloadToFileA.函数从短网址http://bit.ly/33fuZgy 下载文件到本地并通过WinExec执行
短网址解析出来为:http://gessuae.ae/wp-includes/fonts/lav.jpg
图片描述

 

保存路径为:%LOCALAPPDATA%\X098765432198.exe
图片描述

 

通过WinExec执行下载的文件
图片描述

 

执行之后调用ExitProcess退出EQNEDT32.exe
图片描述

后续payload

在vt上查找下载地址:http://gessuae.ae/wp-includes/fonts/lav.jpg
图片描述

 

成功找到名为lav.jpg的攻击文件,且这里可以看到该文件是.net平台的
图片描述

 

下载到本地查壳可以发现,样本由C#编写
图片描述

 

该样本结构如下:
图片描述

 

通过对main函数的分析可以得知:

  1. 程序首先会尝试通过 Assembly.GetExecutingAssembly().GetManifestResourceStream函数获取名为compressed的资源
  2. 成功获取之后会复制资源到arrany
  3. 将arrany传入到Decompress函数
  4. 创建新线程,start参数为经过Decompress函数处理过的array
    图片描述

我们查看一下Decompress函数的内容可以发现该函数是一个解密函数:
图片描述

 

在调用Decompress函数处设置断点:
图片描述

 

查看一下当前array,是一个大的字节流
图片描述

 

F10单步往下走,得到返回值
图片描述

 

展开返回值,很明显解密出来的内容是个PE文件
图片描述

 

此时可以选中该变量,然后鼠标右键->在内存窗口中显示:
图片描述

 

内存如下:
图片描述

 

保存为dump.exe,可以看到该文件依旧是由C#编写:
图片描述

 

dump.exe的入口如下:
图片描述

 

可以看到这里dump.exe是经过混淆的,尝试使用de4dot去混淆:
去混淆之后函数结构如下,比之前好了一点点,然后尝试在main函数设置断点:
图片描述

 

提示异常
图片描述

 

这里其实不应该直接在main函数设置断点的,我偷了个懒,尝试直接在main函数设置断点
但其实在main函数之前,可能还会运行其他的内容,比如 public static 属性的变量赋值,比如下面的代码:
图片描述

 

这里可以看到,main函数中只有一个输出语句
在最后声明了一个static的变量str1,但是并未引用过str1
但是运行代码之后可以发现,由于static变量str1的声明,会导致str1的赋值会在main函数之前执行,这是由C#的编译顺序决定的。

 

所以在该样本中,应该也是有类似的操作,导致代码还没有跑到main函数就抛出异常了。
终于在4970处找到了异常的原因
图片描述

 

并且在一个长语句中,代码多次调用了smethod_0函数:
这里可以看到smethod_0函数是ECB模式AES的解密函数,参数1是base64编码的字符串,参数2是AES解密所使用到的key
图片描述

 

现在在4970行地方设置断点,代码成功断下来:
图片描述

 

往后跟两步之后定位到了异常原因,原来是因为我这个虚拟机卸载了网卡,所以在GetExternalIP的时候导致异常
图片描述

 

尝试通过DownloadString函数访问"http://ifconfig.me/ip"
这里应该是通过该地址获取本机出口IP地址。
这里直接将DowinloadString方法替换试试:
图片描述

 

过了之后直接F10运行,组装出来变量如下:
"+------------- Client INFO -------------+\r\nIP: 192.168.1.1\r\nHWID: 0F8BXXXXXX0906EA\r\nOwner Name: WIN-IHXXXXXXIMB\r\nFull OS Name: Microsoft Windows 7 家庭普通版 \r\nOS Platform: Win32NTOS Version: 6.1.7601.65536\r\nSystem Boot Mode: Normal\r\nPhysical Memory: 2.80 GB Available Of 4.09 GB \r\nVirtual Memory: 1.90 GB Available Of 2.04 GB \r\nDate: 2019/12/27 12:01:46\r\n-----------------------------------------"

 

可以看到,样本首先会获取的信息有:

  1. 计算机出网IP
  2. 计算机HWID
  3. OwnerName
  4. Full OS Name
  5. OS Platform
  6. OS version
  7. System Boot Mode
  8. Physical Memory
  9. Virtual Memory

接着就会运行到Main函数:
图片描述

 

Smethod_14用于获取Chrome浏览器的隐私信息:
图片描述

 

Smethod_16用于获取"C:\Users\Shyt\AppData\Roaming.purple\accounts.xml"的信息,通过查询可以的知,该目录对应程序pidgin
图片描述

 

Smethod_4用于获取@"C:\Users\Shyt\AppData\Local\Vivaldi\User Data\Default\login data"
也就是Vivaldi软件
图片描述

 

后面的内容都差不多,就不截图了,样本还会获取的信息有:
FTP凭证
Opera浏览器隐私信息
Outlook隐私信息
UC浏览器隐私信息
360浏览器隐私信息
猎豹浏览器隐私信息
Firefox隐私信息

 

最后会将收集到的信息打包,通过FTP或者SMTP的形式上传
图片描述



[公告]看雪论坛2020激励机制上线了!多多参与讨论可以获得积分快速升级?

最后于 2019-12-27 15:10 被顾何编辑 ,原因:
最新回复 (9)
雪    币: 3700
活跃值: 活跃值 (61)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
MsScotch 活跃值 2019-12-27 15:07
2
0
很好的分析,赞~
雪    币: 6477
活跃值: 活跃值 (85)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
HadesW 活跃值 1 2019-12-28 11:56
3
0
感谢分享,期待下一篇!
PS:实际上外边都是卖这些东西的




>
最后于 2019-12-28 13:10 被HadesW编辑 ,原因:
雪    币: 229
活跃值: 活跃值 (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
苏啊树 活跃值 2020-1-14 19:12
4
0
@顾何  楼主能提供下这漏洞利用的样本么,在www.virustotal.com上找了半天,好像没有提供样本下载。
雪    币: 14285
活跃值: 活跃值 (93)
能力值: (RANK:327 )
在线值:
发帖
回帖
粉丝
顾何 活跃值 6 2020-1-14 21:39
5
0
苏啊树 @顾何 楼主能提供下这漏洞利用的样本么,在www.virustotal.com上找了半天,好像没有提供样本下载。
文章中提到的样本在https://app.any.run/tasks/88d4e58b-038f-45ad-b095-fdbb5a6811a3/   就可以下载到哈,在这个页面右上角有Sample按钮,单击即可下载,解压密码为infected
雪    币: 229
活跃值: 活跃值 (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
苏啊树 活跃值 2020-1-15 09:17
6
0
顾何 文章中提到的样本在https://app.any.run/tasks/88d4e58b-038f-45ad-b095-fdbb5a6811a3/ 就可以下载到哈,在这个页面右上角有Sample按钮 ...
谢谢大佬
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
A_尘埃 活跃值 2020-5-25 16:47
7
0
大佬,写的很好,很仔细,关于那部分shellcode分析想请教下?
雪    币: 256
活跃值: 活跃值 (141)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ZwCopyAll 活跃值 2020-5-26 09:44
8
0
666
雪    币: 191
活跃值: 活跃值 (46)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xiaozhu头 活跃值 2020-5-26 23:22
9
0
学习了,期待下篇。
雪    币: 265
活跃值: 活跃值 (58)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
niuzuoquan 活跃值 2020-5-26 23:28
10
0
mark
游客
登录 | 注册 方可回帖
返回