12.1、概述
Malleable C2 文件不仅仅是通信指标。Malleable C2 配置文件还能控制 Beacon 的内存特性,决定 Beacon 如何进行进程注入,并影响 Cobalt Strike 的后渗透工作。本章将介绍 Malleable C2 语言的这些扩展。
# 12.2、PE和内存指标
Malleable C2
配置文件中的 stage
块控制如何将 Beacon
加载到内存中并编辑 Beacon DLL 的内容。
stage {set userwx "false";set compile_time "14 Jul 2009 8:14:00";set image_size_x86 "512000";set image_size_x64 "512000"; set obfuscate "true";transform-x86 {prepend "\x90\x90";strrep "ReflectiveLoader" "DoLegitStuff";}transform-x64 {# transform the x64 rDLL stage}stringw "I am not Beacon";
}
stage
块接受将字符串添加到 Beacon DLL
的.rdata
节的命令。 string
命令添加以零结尾的字符串。 stringw
命令添加一个宽(UTF-16LE 编码的)字符串。 data
命令按原样添加你的字符串。
transform-x86
和transform-x64
块对 Beacon
的反射 DLL stage
进行填充和转换。这些代码块支持三种命令:prepend
、append
和 strrep
。
prepend
命令会在 Beacon 的反射 DLL 之前插入一个字符串。append
命令会在 Beacon 反射 DLL 之后添加一个字符串。确保前置数据是stage
架构(x86、x64)的有效代码。c2lint
程序对这方面没有检查。strrep
命令会替换 Beacon
的反射DLL
中的字符串。
stage
块接受多个选项来控制 Beacon DLL 内容并提供更改 Beacon 反射加载器行为的提示:
Option | Example | Description |
---|---|---|
allocator | HeapAlloc | Set how Beacon's Reflective Loader allocates memory for the agent. Options are: HeapAlloc, MapViewOfFile, and VirtualAlloc.(设置 Beacon 的反射加载器如何为代理分配内存。选项有:HeapAlloc、MapViewOfFile 和 VirtualAlloc。) |
cleanup | false | Ask Beacon to attempt to free memory associated with the Reflective DLL package that initialized it.(要求 Beacon 尝试释放与初始化它的反射 DLL 包关联的内存。) |
data_store_size | 16 | Set how many entries can be stored in Beacon Data Store.(设置 Beacon 数据存储中可存储的条目数量。) |
magic_mz_x86 | MZRE | Override the first bytes (MZ header included) of Beacon's Reflective DLL. Valid x86 instructions are required. Follow instructions that change CPU state with instructions that undo the change.(覆盖 Beacon 反射 DLL 的第一个字节(包括 MZ 标头)。需要有效的 x86 指令。在更改 CPU 状态的指令之后,应执行撤销更改的指令。) |
magic_mz_x64 | MZAR | Same as magic_mz_x86; affects x64 DLL(与 magic_mz_x86 相同;影响 x64 DLL) |
magic_pe | PE | Override the PE character marker used by Beacon's Reflective Loader with another value.(用其他值覆盖 Beacon 的反射加载器使用的 PE 字符标记。) |
module_x86<sup>1</sup> | xpsservices.dll | Ask the x86 ReflectiveLoader to load the specified library and overwrite its space instead of allocating memory with VirtualAlloc.(要求 x86 反射加载器加载指定库并覆盖其空间,而不是使用 VirtualAlloc 分配内存。) |
module_x64<sup>1</sup> | xpsservices.dll | Same as module_x86; affects x64 loader(与 module_x86 相同;影响 x64加载器) |
obfuscate | false | Obfuscate the Reflective DLL’s import table, overwrite unused header content, and ask ReflectiveLoader to copy Beacon to new memory without its DLL headers.(混淆反射DLL 的导入表,覆盖未使用的标头内容,并要求反射加载器将 Beacon 复制到新内存,但不包含其 DLL 标头。) |
sleep_mask | false | Obfuscate Beacon and it's heap, in-memory, prior to sleeping.(在睡眠前混淆 Beacon 及其内存堆。) |
smartinject | false | Use embedded function pointer hints to bootstrap Beacon agent without walking kernel32 EAT(使用嵌入式函数指针提示来引导 Beacon 代理,而无需遍历 kernel32 EAT) |
stomppe | true | Ask ReflectiveLoader to stomp MZ, PE, and e_lfanew values after it loads Beacon payload(要求反射加载器在加载 Beacon payload后破坏 MZ、PE 和 e_lfanew 值) |
syscall_method | None | Set the system call method to use on initial beacon execution. Options are None, Direct, Indirect. See section System Calls for additional information.(设置初始beacon执行时使用的系统调用方法。选项包括 “无”、“直接”、“间接”。有关更多信息,请参阅系统调用一节。) |
userwx | false | Ask ReflectiveLoader to use or avoid RWX permissions for Beacon DLL in memory(要求反射加载器使用或避免内存中 Beacon DLL 的 RWX 权限) |
1 -
module_x86
和module_x64
设置现在支持指定搜索导出函数的起始序号值。可选的0x###
部分是以整数形式指定的起始序号值。如果设置了一个库,但 Beacon 并未将自身覆盖到内存空间,那么该库很可能没有序号值为 1 至 15 的导出函数。要解决这个问题,应确定一个有效的序号值,并使用可选语法指定该值,例如:set module_x64 “libtemp.dll+0x90”
(设置 module_x64 为 libtemp.dll+0x90)
# 12.2.1、克隆PE头
stage
块有几个选项,可以改变 Beacon 反射DLL 的特性,使其在内存中看起来像其他东西。这些选项旨在创建支持分析练习和威胁模拟场景的指标。
Option | Example | Description |
---|---|---|
checksum | 0 | The CheckSum value in Beacon’s PE header(Beacon PE 标头中的校验和值) |
compile_time | 14 July 2009 8:14:00 | The build time in Beacon’s PE header(Beacon PE 标头中的构建时间) |
entry_point | 92145 | The EntryPoint value in Beacon’s PE header(Beacon PE 标头中的 EntryPoint 值) |
image_size_x64 | 512000 | SizeOfImage value in x64 Beacon’s PE header(x64 Beacon PE 标头中的 SizeOfImage 值) |
image_size_x86 | 512000 | SizeOfImage value in x86 Beacon’s PE header(x86 Beacon PE 标头中的 SizeOfImage 值) |
name | beacon.x64.dll | The Exported name of the Beacon DLL(Beacon DLL 的导出名称) |
rich_header | Meta-information inserted by the compiler(编译器插入的元信息) |
Cobalt Strike 的 Linux 软件包中包含一个工具 peclone
,用于从 DLL 中提取头文件,并将其显示为可立即使用的stage
块:
./peclone [/path/to/sample.dll]
# 12.2.2、内存中的规避和混淆
使用stage
块的 prepend
命令可阻止一些扫描内存段前几个字节以查找注入 DLL 迹象的分析。如果目标的安全分析系统使用特定于工具的字符串来检测你的 agent
(代理),请使用 strrep
命令对这些工具特定的字符串进行更改。
如果 strrep
还不够,请将 sleep_mask
设置为 true
。这会指示 Beacon
在进入睡眠状态之前对自身和内存中的堆进行混淆。休眠后,Beacon 将对自身进行去混淆处理以请求和处理任务。 SMB 和 TCP Beacon在等待新连接或等待来自其父会话的数据时会混淆自身。
这取决在多大程度上希望在内存中看起来像一个 DLL。如果你想让 Beacon DLL
更容易被检测到,请将 stomppe
设置为 false
。如果想在内存中对 Beacon DLL
进行轻度混淆,则将 stomppe
设置为 true
。如果高度混淆,请将 obfuscate
设置为 true
。该选项将采取更多步骤来混淆 Beacon stage和 DLL 在内存中的最终状态。
查找内存注入的 DLL 之一方法是检查 MZ 和 PE 魔术字节,它们在各自的预期位置相对出现。 这些值通常不会被混淆,因为反射加载过程依赖于它们。 混淆选项不会影响这些值。 将 magic_pe
设置为两个字母或字节,标记 PE 头部的开始位置。 将 magic_mz_x86
设置为更改 x86 Beacon DLL
中的这些魔术字节。 将 magic_mz_x64
设置为更改x64 Beacon DLL
中的这些字节。 按照更改 CPU 状态的指令后,使用可撤销该更改的指令。 例如,MZ 是容易识别的头部序列,但它也是有效的 x86 和 x64 指令。 后续的 RE(x86)和 AR(x64)是有效的 x86 和 x64 指令,能够撤销 MZ 的更改。 这些提示将改变 Beacon 反射式 DLL 包中的魔术值,并使反射加载过程使用新的值。
默认 module_mz_x86 值的反汇编:
将 userwx
设置为 false
,以要求 Beacon
的加载程序避免 RWX 权限。具有这些权限的内存段会引起分析师和安全产品的额外关注。
默认情况下,Beacon
的加载器使用 VirtualAlloc
分配内存。可以通过allocator
选项来更改此行为。HeapAlloc
选项为 Beacon
分配带有RWX
权限的堆内存。MapViewOfFile
分配器通过在当前进程中创建一个匿名内存映射文件区域来为 Beacon 分配内存。模块stomping
是这些选项的替代方法,也是通过受控制的镜像内存执行 Beacon 的一种方式。将 module_x86
设置为一个大约是 Beacon payload
两倍大小的 DLL。Beacon
的 x86 加载器将加载指定的 DLL,找到它在内存中的位置并覆盖它。这是一种将 Beacon 放在内存中的方法,Windows 会将其与磁盘上的文件关联起来。需要注意的是,所选择的 DLL 不应被你打算驻留的应用程序所依赖。module_x64
选项与此类似,但它影响的是 x64 Beacon
。
如果担心 Beacon stage
会在内存中初始化 Beacon DLL
,请将cleanup
设置为 true
。当不再需要时,该选项将释放与 Beacon stage
相关的内存。
# 12.3、进程注入
Malleable C2 配置文件中的process-inject
块配置注入内容并控制 Beaco payload的进程注入行为。它还控制当前beacon
内beacon
对象文件 (BOF) 执行的行为。
process-inject {# set how memory is allocated in a remote process for injected contentset allocator "VirtualAllocEx";# set how memory is allocated in the current process for BOF contentset bof_allocator "VirtualAlloc";set bof_reuse_memory "true";# shape the memory characteristics for injected and BOF contentset min_alloc "16384";set startrwx "true";set userwx "false";# transform x86 injected contenttransform-x86 {prepend "\x90\x90";}# transform x64 injected contenttransform-x64 {append "\x90\x90";}# determine how to execute the injected codeexecute {CreateThread "ntdll.dll!RtlUserThreadStart";SetThreadContext;RtlCreateUserThread;}
}
process-inject
块接受几个选项来控制Beacon
中的进程注入过程:
Option | Example | Description |
---|---|---|
allocator | VirtualAllocEx | The preferred method to allocate memory in the remote process. Specify VirtualAllocEx or NtMapViewOfSection. The NtMapViewOfSection option is for same-architecture injection only. VirtualAllocEx is always used for cross-arch memory allocations.(在远程进程中分配内存的首选方法。指定 VirtualAllocEx 或 NtMapViewOfSection。NtMapViewOfSection 选项仅用于同架构注入。VirtualAllocEx 始终用于跨架构内存分配。) |
bof_allocator | VirtualAlloc | The preferred method to allocate memory in the current process to execute a BOF. Specify VirtualAlloc, MapViewOfFile, or HeapAlloc.(在当前进程中分配内存以执行 BOF 的首选方法。请指定 VirtualAlloc、MapViewOfFile 或 HeapAlloc。) |
bof_reuse_memory | true | Reuse the allocated memory for subsequent BOF executions otherwise release the memory. Memory will be cleared when not in use. If the available amount of memory is not large enough it will be released and allocated with the larger size.(为后续 BOF 执行重用分配的内存,否则释放内存。不使用时内存将被清除。如果可用内存量不够大,它将被释放并分配更大的大小。) |
min_alloc | 4096 | Minimum amount of memory to request for injected or BOF content.(为注入或 BOF 内容申请的最小内存量。) |
startrwx | false | Use RWX as initial permissions for injected or BOF content. Alternative is RW. When BOF memory is not in use the permissions will be set based on this setting.(使用 RWX 作为注入或 BOF 内容的初始权限。另一种选择是 RW。当未使用 BOF 内存时,将根据此设置设置权限。) |
userwx | false | Use RWX as final permissions for injected or BOF content. Alternative is RX for code and RW for data.(使用 RWX 作为注入或 BOF 内容的最终权限。另一种方法是 RX 用于代码,RW 用于数据。) |
transform-x86
和 transform-x64
块用于填充Beacon
注入的内容。这些区块支持两种命令:prepend
和 append
。
prepend
命令会在注入内容之前插入一个字符串。append
命令会在注入内容后添加一个字符串。确保前置数据是符合注入内容架构(x86、x64)的有效代码。c2lint
不会对这方面进行检查。
execute
块控制 Beacon
在需要将代码注入进程时将使用的方法。 Beacon 检查execute
块中的每个选项,确定该选项是否可用于当前上下文,在可用时尝试该方法,如果代码未执行,则继续执行下一个选项。execute
选项包括:
Option | x86->x64 | x64->x86 | Notes |
---|---|---|---|
CreateThread | Current process only(仅限当前进程) | ||
CreateRemoteThread | Yes | No cross-session(是否跨会话) | |
NtQueueApcThread | |||
NtQueueApcThread-s | This is the “Early Bird” injection technique. Suspended processes (e.g., post-ex jobs) only.(这就是“Early Bird”注入技术。仅暂停的流程(例如,后期作业)。) | ||
RtlCreateUserThread | Yes | Yes | Risky on XP-era targets; uses RWX shellcode for x86 -> x64 injection.(对 XP 时代的目标存在风险;使用 RWX shellcode 进行 x86 -> x64 注入。) |
SetThreadContext | Yes | Suspended processes (e.g., post-ex jobs) only.(仅暂停进程(例如,后期作业)。) |
CreateThread
和CreateRemoteThread
选项有一些变量,这些变量使用另一个函数的地址生成挂起的线程,更新挂起的线程以执行注入的代码,并恢复该线程。使用 [function] “module!function+0x##”
指定要欺骗的起始地址。对于远程进程,ntdll
和kernel32
是唯一推荐从中提取的模块。可选的 0x##
部分是添加到起始地址的偏移量。这些变量仅适用于 x86 -> x86
和 x64 -> x64
。
你选择的execure
选项必须涵盖各种极端情况。这些极端情况包括自注入、注入挂起的临时进程、跨会话远程进程注入、x86 -> x64
注入、x64 -> x86
注入以及带有或不带有参数的注入。c2lint
工具会对execute
块未涵盖的上下文情况发出警告。
# 12.3.1、控制进程注入
从Cobalt Strike 4.5
开始新增了一项支持,允许用户定义自己的进程注入技术,而不是使用内置技术。这是通过 PROCESS_INJECT_SPAWN
和 PROCESS_INJECT_EXPLICIT
钩子函数实现的。Cobalt Strike
会在执行后渗透命令时调用其中一个钩子函数。有关支持的命令列表,请参阅 “hook”部分。
这两个钩子将涵盖大部分后渗透利用命令。但是,有一些例外情况不会使用这些钩子,而是继续使用内置技术。
Beacon Command | Aggressor Script function |
---|---|
&bdllspawn | |
shell | &bshell |
execute-assembly | &bexecute_assembly |
要实施你自己的注入技术,你需要提供一个 Beacon Object File
(BOF) 文件,其中包含你在 x86
和/或 x64
架构下的可执行代码,以及一个包含钩子函数的 Aggressor
脚本文件。请参阅社区工具包中的进程注入钩子示例。
由于你实施的是自己的注入技术,除非你的 BOF
调用 Beacon API
函数 BeaconInjectProcess
或 BeaconInjectTemporaryProcess
,否则不会使用 Malleable C2
配置文件中的进程注入设置。这些函数实现了默认注入,除非是为了实现默认技术的回退,否则很可能不会使用。
进程注入派生
PROCESS_INJECT_SPAWN
钩子用于定义 fork&run
进程注入技术。下表列出的下列beacon
命令、aggressor
脚本函数和UI接口将调用该钩子,用户可以实现自己的技术或使用内置技术。
请注意以下几点:
elevate、runasadmin、&belevate、&brunasadmin 和 [beacon] -> Access -> Elevate 命令只有在指定的漏洞利用程序使用了表中列出的aggressor脚本函数之一(例如 &bpowerpick)时,才会使用 PROCESS_INJECT_SPAWN 钩子。
对于 net 和 &bnet 命令,“domain”命令不会使用钩子。
“(use a hash)”注释表示选择引用哈希的凭证。
作业类型
Command | Aggressor Script | UI |
---|---|---|
chromedump | ||
dcsync | &bdcsync | |
elevate | &belevate | [beacon] -> Access -> Elevate |
[beacon] -> Access -> Golden Ticket | ||
hashdump | &bhashdump | [beacon] -> Access -> Dump Hashes |
keylogger | &bkeylogger | |
logonpasswords | &blogonpasswords | [beacon] -> Access -> Run Mimikatz |
[beacon] -> Access -> Make Token (use a hash) | ||
mimikatz | &bmimikatz | |
&bmimikatz_small | ||
net | &bnet | [beacon] -> Explore -> Net View |
portscan | &bportscan | [beacon] -> Explore -> Port Scan |
postex_kit | beacon_execute_postex_job() | |
powerpick | &bpowerpick | |
printscreen | &bprintscreen | |
pth | &bpassthehash | |
runasadmin | &brunasadmin | |
[target] -> Scan | ||
screenshot | &bscreenshot | [beacon] -> Explore -> Screenshot |
screenwatch | &bscreenwatch | |
ssh | &bssh | [target] -> Jump -> ssh |
ssh-key | &bssh_key | [target] -> Jump -> ssh-key |
[target] -> Jump -> [exploit] (use a hash) |
显式进程注入
PROCESS_INJECT_EXPLICIT
钩子用于定义显式进程注入技术。下表列出的下列beacon
命令、aggressor
脚本函数和UI接口将调用该钩子,用户可以实现自己的技术或使用内置技术。
请注意以下几点:
通过[beacon] -> Explore -> Process List 访问[进程浏览器]界面。该界面还有一个多版本,可以通过选择多个会话并使用相同的 UI 菜单来访问。在进程浏览器中时,使用按钮对所选进程执行其他命令。
chromedump、dcsync、hashdump、keylogger、logonpasswords、mimikatz、net、portscan、printscreen、pth、screenshot、screenwatch、ssh 和 ssh-key 命令也有 fork&run 版本。使用显式版本需要 pid 和架构参数。
对于 net 和 &bnet 命令,“domain”命令不会使用钩子。
作业类型
Command | Aggressor Script | UI |
---|---|---|
browserpivot | &bbrowserpivot | [beacon] -> Explore -> Browser Pivot |
chromedump | ||
dcsync | &bdcsync | |
dllinject | &bdllinject | |
hashdump | &bhashdump | |
inject | &binject | [Process Browser] -> Inject |
keylogger | &bkeylogger | [Process Browser] -> Log Keystrokes |
logonpasswords | &blogonpasswords | |
mimikatz | &bmimikatz | |
&bmimikatz_small | ||
net | &bnet | |
portscan | &bportscan | |
postex kit | beacon_execute_postex_job() | |
printscreen | &bprintscreen | |
psinject | &bpsinject | |
pth | &bpassthehash | |
screenshot | &bscreenshot | [Process Browser] -> Screenshot (Yes) |
screenwatch | &bscreenwatch | [Process Browser] -> Screenshot (No) |
shinject | &bshinject | |
ssh | &bssh | |
ssh-key | &bssh_key |
# 12.4、控制后渗透
更大的 Cobalt Strike
后渗透功能(例如屏幕截图、键盘记录器、哈希转储等)是以 Windows DLL
的形式实现的。为了执行这些功能,Cobalt Strike
会派生一个临时进程,并将该功能注入其中。process-inject
块控制进程注入步骤。post-exe
块控制 Cobalt Strike
后渗透利用功能特有的内容和行为。在 4.5 以后续版本中,这些后渗透功能支持使用 [pid]
和 [arch]
参数显式注入现有进程。
post-ex {# control the temporary process we spawn toset spawnto_x86 "%windir%\\syswow64\\rundll32.exe";set spawnto_x64 "%windir%\\sysnative\\rundll32.exe";# change the permissions and content of our post-ex DLLsset obfuscate "true";# change our post-ex output named pipe names...set pipename "evil_####, stuff\\not_##_ev#l";# pass key function pointers from Beacon to its child jobsset smartinject "true";# disable AMSI in powerpick, execute-assembly, and psinjectset amsi_disable "true";
}
spawnto_x86
和spawnto_x64
选项控制Beacon
用于派生后渗透功能的默认临时进程。以下是有关这些值的一些提示:
- 始终指定你希望 Beacon 派生的程序的完整路径
- 可以在路径中使用环境变量(例如
%windir%
) - 不要直接指定
%windir%\system32
或c:\windows\system32
。始终使用syswow64 (x86)
和sysnative (x64)
。Beacon
会在必要时将这些值调整为system32
。 - 对于
x86 spawnto
值,必须指定一个x86
程序。对于x64 spawnto
值,必须指定一个x64
程序。 - 你指定的路径(减去自动的
syswow64/sysnative
调整)必须存在于文件系统的x64
(本机)和x86 (wow64)
视图中。
obfuscate
(混淆)选项会扰乱post-ex
DLL 的内容,并以更安全的方式将post-ex
功能植入内存。这与 Beacon
通过 stage
区块提供的 obfuscate
和 userwx
选项非常相似。设置该选项后,一些长期运行的 post-ex
动态链接库会根据需要屏蔽或解除屏蔽其字符串表。
使用 pipename
可更改 post-ex
DLL 发送输出到 Beacon
时使用的管道名称。该选项接受一个以逗号分隔的管道名称列表。Cobalt Strike
会在设置后渗透任务时从该选项中随机选择一个管道名称。管道名称中的每个 #
会被替换为一个有效的十六进制字符。
smartinject
选项指示Beacon
将 GetProcAddress
和LoadLibrary
等关键函数指针嵌入其相同架构的post-ex
DLL 中。 使 post-ex DLL
可以在新进程中进行自我引导,而无需通过监视对 PEB
和 kernel32.dll
的内存访问来检测和缓解类似shellcode
的行为。
thread_hint
选项允许多线程 post-ex
DLL 使用欺骗的起始地址生成线程。将线程提示指为“module!function+0x##”以指定要欺骗的起始地址。可选的 0x##
部分是添加到起始地址的偏移量。
amsi_disable
选项指示 powerpick
、execute-assembly
和 psinject
在加载 .NET
或 PowerShell
代码之前修补 AmsiScanBuffer
函数。这将限制反恶意软件扫描界面对这些功能的可见性。
设置keylogger
选项,以配置Cobalt Strike
的键盘记录器。GetAsyncKeyState
选项(默认)使用GetAsyncKeyState API
来记录击键情况。SetWindowsHookEx
选项使用 SetWindowsHookEx
来记录按键。
# 12.5、用户定义的反射 DLL 加载器
从Cobalt Strike 4.4
版本开始增加了对Beacon payload
使用自定义反射加载器的支持。用户自定义反射加载器(UDRL)工具包是 UDRL 示例的源代码。请访问Help
-> Arsenal
并下载 UDRL
工具包(需要你的许可证密钥)。
注意:反射式加载器的可执行代码是从用户提供的编译对象文件中提取的
.text
部分。提取的可执行代码必须小于 100KB。
# 12.5.1、实现
提供以下Aggressor
脚本钩子以允许实现用户定义的反射加载器:
Function | Description |
---|---|
BEACON_RDLL_GENERATE | Hook used to implement basic Reflective Loader replacement.(用于实现基本的 Reflective Loader 替换。) |
BEACON_RDLL_SIZE | This hook is called when preparing beacons and allows the user to configure more than 5 KB space for their reflective loader (up to 100KB). This hook can also be used to remove the entire space for the reflective loader.(该钩子在准备Beacon时被调用,并允许用户为其反射加载器配置超过 5 KB 的空间(最多 100KB)。该钩子还可用于移除反射加载器的整个空间。) |
BEACON_RDLL_GENERATE_LOCAL | Hook used to implement advanced Reflective Loader replacement. Additional arguments provided include Beacon ID, GetModuleHandleA address, and GetProcAddress address.(该钩子用于实现高级 Reflective Loader 替换。提供的其他参数包括 Beacon ID、GetModuleHandleA 地址和 GetProcAddress 地址。) |
提供了以下Aggressor
脚本函数,用于从编译的对象文件中提取 Reflective Loader
可执行代码(.text
部分),并将可执行代码插入Beacon payload
中:
Function | Description |
---|---|
extract_reflective_loader | Extracts the Reflective Loader executable code from a byte array containing a compiled object file.(从包含编译对象文件的字节数组中提取反射加载器可执行代码。) |
setup_reflective_loader | Inserts the Reflective Loader executable code into the beacon payload.(将反射加载器可执行代码插入beacon payload 中。) |
提供以下Aggressor
脚本函数来使用来自 Malleable C2
配置文件的信息修改Beacon payload
:
Function | Description |
---|---|
setup_strings | Apply the strings defined in the Malleable C2 profile to the beacon payload.(将 Malleable C2 配置文件中定义的字符串应用于Beacon payload。) |
setup_transformations | Apply the transformation rules defined in the Malleable C2 profile to the beacon payload.(将 Malleable C2 配置文件中定义的转换规则应用于Beacon payload。) |
提供了以下 Aggressor
脚本函数来获取有关Beacon payload
的信息,以帮助对payload
进行自定义修改:
Function | Description |
---|---|
pedump | Loads a map of information about the beacon payload. This map information is similar to the output of the "peclone" command with the "dump" argument.(加载Beacon payload的信息映射。该映射信息类似于带有 “dump ”参数的 “peclone ”命令的输出。) |
提供以下 Aggressor
脚本函数来对beacon payload
进行自定义修改:
注意:根据所做的自定义修改(混淆、屏蔽等),反射加载器在加载时可能必须反转这些修改。
Function | Description |
---|---|
pe_insert_rich_header | Insert rich header data into Beacon DLL Content. If there is existing rich header information, it will be replaced.(将富标头数据插入 Beacon DLL 内容。如果已有富标头信息,则会被替换。) |
pe_mask | Mask data in the Beacon DLL Content based on position and length.(根据位置和长度屏蔽 Beacon DLL 内容中的数据。) |
pe_mask_section | Mask data in the Beacon DLL Content based on position and length.(根据位置和长度屏蔽 Beacon DLL 内容中的数据。) |
pe_mask_string | Mask a string in the Beacon DLL Content based on position.(根据位置屏蔽 Beacon DLL 内容中的字符串。) |
pe_patch_code | Patch code in the Beacon DLL Content based on find/replace in '.text' section'.(基于“.text”部分中的查找/替换来修补 Beacon DLL 内容中的代码。) |
pe_remove_rich_header | Remove the rich header from Beacon DLL Content.(从 Beacon DLL 内容中移除富标头。) |
pe_set_compile_time_with_long | Set the compile time in the Beacon DLL Content.(在 Beacon DLL 内容中设置编译时间。) |
pe_set_compile_time_with_string | Set the compile time in the Beacon DLL Content.(在 Beacon DLL 内容中设置编译时间。) |
pe_set_export_name | Set the export name in the Beacon DLL Content.(在 Beacon DLL 内容中设置导出名称。) |
pe_set_long | Places a long value at a specified location.(将长整型值放置在指定位置。) |
pe_set_short | Places a short value at a specified location.(将短整型值放置在指定位置。) |
pe_set_string | Places a string value at a specified location.(将字符串值放置在指定位置。) |
pe_set_stringz | Places a string value at a specified location and adds a zero terminator.(将字符串值放置在指定位置并添加零终止符。) |
pe_set_value_at | Sets a long value based on the location resolved by a name from the PE Map (see pedump).(根据 PE 映射中的名称解析的位置设置一个长整型值(请参阅 pedump)。) |
pe_stomp | Set a string to null characters. Start at a specified location and sets all characters to null until a null string terminator is reached.(将字符串设置为空字符。从指定位置开始并将所有字符设置为空,直到到达空字符串终止符。) |
pe_update_checksum | Update the checksum in the Beacon DLL Content.(更新 Beacon DLL 内容中的校验和。) |
# 12.5.2、使用用户定义的反射 DLL 加载器
创建/编译你的反射加载器
用户自定义反射加载器(UDRL)工具包是 UDRL 示例的源代码。请访问Help
-> Arsenal
并下载 UDRL
工具包(需要许可证密钥)。
以下是准备Beacon
的 Cobalt Strike
流程:
-
准备
Beacon
时会调用BEACON_RDLL_SIZE
钩子。- 这使用户有机会表明其反射加载程序需要超过 5 KB 的空间。
- 用户在使用
Beacon
时,可为反射加载器预留最多 100 KB 的空间。 - 当覆盖
beacon
中的可用反射加载器空间时,beacon
将变得更大。事实上,它们对于Cobalt Strike
提供的标准可执行程序来说太大了。用户将需要更新他们的流程,以使用具有更大预留空间的定制可执行程序来容纳更大的beacon
。 - 这可用于从 Beacon DLL 中删除反射加载器空间。
-
Beacon
使用所需的设置作为payload
数据进行修补。-
以下内容已被修补到用于 UDRL 的 Beacons 中
-
监听器设置
-
一些 Malleable C2 设置
使用
sleepmask
和userwx
需要一个反射加载器能够为具有RWX
权限的.text
可执行代码创建内存,否则当屏蔽/取消屏蔽写保护内存时,Beacon
将崩溃。默认的反射加载器通常会处理这个问题。
-
-
以下内容未修补到用于 UDRL 的 Beacons 中
- PE修改
-
-
BEACON_RDLL_GENERATE
通常被调用。BEACON_RDLL_GENERATE_LOCAL
钩子在以下情况下被调用:- 下面确定哪个被调用
- Malleable C2 已设置“.stage.smartinject”
- 使用
extract_reflective_loader
函数提取反射加载器。 - 使用
setup_reflective_loader
函数将提取的反射加载器修补到Beacon
中的反射加载器空间中。- 如果加载程序对于所选Beacon来说太大,你将看到类似这样的消息:
- Reflective DLL Content length (123456) exceeds available space (5120).
- 使用“BEACON_RDLL_SIZE”来使用具有较大反射加载器的Beacon。
- 如果加载程序对于所选Beacon来说太大,你将看到类似这样的消息:
- 还有一些额外的功能可供使用,以便根据反射加载器的能力检查并修改 Beacons。例如:
- 提供混淆功能
- 修补地址以支持智能注入
- 下面确定哪个被调用
-
信标被修补成可执行文件。
- 使用较大反射加载器空间(根据上面的“BEACON_RDLL_SIZE”)构建的
beacon
将需要加载到具有容纳大型beacon
空间的自定义artifact中。 - 从获得许可的 Cobalt Strike 中前往
Help
>Arsenal
下载Artifact Kit
。 - 请参阅 Cobalt Strike 提供的这些工具包文件中的 “stagesize ”参考资料:
- 请参阅artifact 构建脚本中的“stagesize”参考。
- 请参阅“script.example”中的“stagesize”参考
- 使用较大反射加载器空间(根据上面的“BEACON_RDLL_SIZE”)构建的
# 说明
本文由笔者在Cobalt Strike官方用户指南原文(https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/welcome_main.htm)基础上编译,如需转载请注明来源。