Profile编写规则
Profile编写规则
简介
在网络渗透测试和红队模拟攻击中,隐藏命令与控制(C2)流量的特征对于成功绕过入侵检测系统至关重要。Cobalt Strike提供了一个强大的工具——Malleable C2 profiles,用于自定义C2流量,从而使其看起来像正常的网络流量。下面我们就一起来学习如何使用和自定义这些profile
基础概念
全局选项:这是一些设置C2服务器的基本参数的选项,比如设置使用的SSL证书文件,设置服务器端口等。
http-stager:这部分设置用于控制使用HTTP或HTTPS协议的stager的行为。比如,可以设置User-Agent、URI、POST请求的数据格式等。
http-get:这部分设置用于控制Beacon从C2服务器获取任务时发送的HTTP GET请求的格式。
http-post:这部分设置用于控制Beacon向C2服务器发送数据时发送的HTTP POST请求的格式。
metadata:这部分设置用于控制Beacon和C2服务器交换的元数据的格式。
基础使用流程
1.创建Profile文件
首先,需要创建一个新的Malleable C2 profile文件,或者修改一个已经存在的profile文件。这个文件是一个纯文本文件,可以使用任何文本编辑器来编辑。一个基本的Profile文件结构如下:
set keystore "/root/cobaltstrike.store";
http-stager {
set uri "/download";
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537";
}
http-get {
set uri "/search";
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537";
}
http-post {
set uri "/submit";
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537";
}
http-malleable {
set uri "/data";
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537";
}2.检验profile文件
profile文件编写完成后,可使用CobaltStrike自带的c2lint来验证profile文件是否正确配置,执行如下命令:

如下图所示即为profile文件配置成功

3.加载Profile文件
在启动Cobalt Strike team server时,可执行如下命令指定Malleable C2 profile文件
其中,[yourip]和[password]是你的C2服务器的IP地址和密码,myprofile.profile是你的Malleable C2 profile文件的路径
4.生成并部署beacon
在Cobalt Strike中,例如你可以使用"Attacks"->"Packages"->"Windows Executable (S)"菜单项来生成包含了你的Malleable C2 profile的Beacon。然后,你可以将这个Beacon部署到你的目标机器上
常用关键字
数据编码方式
以下表格是一些CobaltStrike在profile配置中用于数据编码的常用关键字,你可以根据需要组合使用这些关键字,来实现对数据的编码、附加额外字符串等操作
例如,你可以选择先使用base64编码,然后再添加一个特定的字符串,以此来创建更复杂的数据编码模式
append "string"
将指定字符串附加在末尾
base64
使用Base64编码
base64url
一种变异的Base64编码,编码后的数据不会含有可能破坏URL完整性的字符,如"+"、"/"等
mask
使用XOR编码,key是随机的
netbios
使用NetBIOS编码,产生的编码字符为小写 ('a'-'p')
netbiosu
使用NetBIOS编码,产生的编码字符为大写 ('A'-'P')
prepend "string"
将指定字符串附加在头部
用于将输入打印为字符串,通常用于输出操作中
strrep "s1" "s2"
将字符串中所有的s1替换为s2
netbios_decode
对数据进行NetBIOS解码
base64_decode
对数据进行Base64解码
mask_decode
对使用随机key进行XOR编码的数据进行解码
Strings转义字符
以下是可在profile文件中使用的转义字符:
值
含义
"\n"
换行符
"\r"
回车
"\t"
tab键
"\u####"
表示一个unicode字符
"\x##"
十六进制(shellcode知道吧就是那东西的写法\x90\x90)
如下代码的作用是,当Cobalt Strike的Beacon与C2服务器通信时,服务器响应的HTTP消息头中的Content-Type被设定为"image/gif",并且在消息体中插入了一段特定的十六进制编码的数据,这些数据在传输过程中会被解析为一个GIF图像。这样可以在网络流量中掩盖Beacon的通信数据,使其看起来像是正常的图像数据,从而避开了网络监控的检测
终止关键字(指定数据存放位置)
在设置完数据编码规则后,我们需要使用终止关键字来标记编码规则的结束,并指定数据的存放位置。
声明方式
数据存放位置
header "header"
将数据存储在指定的HTTP头部。
parameter "key"
将数据存储在指定的URI参数中。("parameter"这个终止关键字在"id"代码块中和其他地方的含义是不同的,在id代码块中是代表beacon的session id)
将数据存储在HTTP body中。
uri-append
将数据直接附加到URI后面。当使用此终止语句时,建议使用base64url而非base64进行编码,因为普通的base64编码可能会包含"+"号,而在URL中这可能会被转义。
在
http-get.server.output,http-post.server.output和http-stager.server.output这三个代码块中,只能使用print作为终止关键字,因为这些区块的数据应原样输出,不能存储在其他位置。在
http-get.client.metadata中不能使用print作为终止关键字,这是由于HTTP GET请求的特性决定的,它并未设计为在请求体(body)中传递参数。
另外,如果在http-post.client.output中使用header,parameter或uri-append,Beacon会将数据分块到合理的长度后进行发送,以避免因数据长度过长而导致的问题。
常用代码块
http-get
这部分配置信标发送到服务器的 HTTP GET 请求。这通常用于信标的 "check-in" 操作,即信标定期联系服务器以获取指令。http-get 配置可以包括请求的URI、请求头、请求参数等,以及服务器响应中应该包含的数据。这使得通信看起来像是正常的网络流量,帮助信标躲避入侵检测系统的侦测
如下代码定义了CS的HTTP GET请求的配置,分为两部分,client部分描述了Beacon发出的请求,server部分描述了C2服务器的响应
在metadata块中,base64url表示Beacon将元数据进行Base64编码;prepend "__cfduid="表示在编码后的元数据前添加字符串"__cfduid=";header "Cookie";表示将元数据放入"Cookie"头部字段发送
http-post
这部分配置beacon发送到服务器的 HTTP POST 请求。beacon使用 POST 请求来发送数据回 C2 服务器,例如搜集到的信息、命令执行结果等
与http-get不同的是,http-post多了个id参数,id部分定义了如何传输session id
session id是CS用来标识不同的beacon实例的唯一标识符。为了与C2服务器进行有效通信,每个Beacon必须在其请求中包含这个标识符,以便C2服务器可以识别和处理每个请求。例如,如果session id是1234,那么Beacon发送的POST请求uri会是/submit.php?id=1234。
下述代码定义了Cobalt Strike Beacon与C2服务器之间进行HTTP POST请求通信的规则。要注意的是,uri不能设置的和http-get一样
http-stager
C2与Beacon之间有两种通信方式:stager(分阶段)与stagerless(无阶段)。这两种类型的Payload的主要区别在于它们的大小,以及它们如何被传递和执行
stager:Stager是一个小型的引导程序,其主要任务是连接到攻击者的服务器(或者某个中间节点),下载剩余的Payload(即Stage部分),然后执行它
stagerless:这种Payload在被传递到目标系统时就已经完整,没有分为Stager和Stage两部分。一旦Payload到达目标系统,它就可以立即执行
Cobalt Strike提供了http-stager代码块,使我们可以控制stage(即Beacon的核心代码)的发送过程,下面是一个http-stager的示例
set uri_x86 "/jquery-3.3.1.slim.min.js"; 和 set uri_x64 "/jquery-3.3.2.slim.min.js";: 这两行设置了32位和64位stager在HTTP请求中使用的URI。
server 部分设置了C2服务器在HTTP响应中使用的参数。
header关键字设置了响应头的参数。例如header "Server" "NetDNA-cache/2.2";设置了"Server"响应头为"NetDNA-cache/2.2"。output部分设置了响应体的内容。prepend和append分别添加了一些数据到响应体的开始和结束。在这种情况下,数据被设计成看起来像一个jQuery文件,这有助于掩盖stager的真实内容。
client 部分设置了stager在HTTP请求中使用的参数。
header 关键字设置了请求头的参数。例如,header "Accept" "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
总的来说,这段配置为Cobalt Strike设置了一个伪装成jQuery文件的HTTP载荷分发机制,有助于绕过某些安全检测
http-config
http-config允许你定义http通信的全局特性,会影响所有HTTP相应
https-certificate
Cobalt Strike的Malleable C2 profile提供了两种方式来设置SSL证书:使用预生成的证书和生成自签名证书
使用预生成的证书
如果你已经有一个预生成的PEM格式的SSL证书(包括公钥和私钥),你可以直接在profile文件的http-certificate代码块中来指定它
在下述例子中,set keystore命令指定了证书文件的路径,而set password指定了证书文件的密码。
生成自签名证书
如果你没有证书,Cobalt Strike可以为你生成一个自签名证书。在profile文件中,可以使用https-certificate代码块来定义证书的各个部分,在下述例子中,set CN、set O等命令定义了证书的各种属性
.pem转.store
首先使用openssl命令将PEM格式的证书和私钥合并为一个PKCS12 (.p12)格式的文件
-in和-inkey:填写你的证书和私钥文件
-out:填写你希望创建的PKCS12文件
-name:填写你证书的别名(自定义)
-password:填写PKCS12文件的密码,后面转换为Java Keystore文件要用到

使用keytool命令将PKCS12格式的文件转换为Java KeyStore (.store)格式:
-deststorepass:Java KeyStore文件的密码
-destkeystore:你希望创建的Java KeyStore文件
-srckeystore:前面创建的PKCS12文件
-srcstorepass:前面设置的PKCS12文件的密码

可使用 Java 的 keytool 工具来检查生成的 .store 文件,填写你的.store文件路径以及密码,如果你的文件有效,那么此命令会显示你的证书的详细信息,如证书的所有者、发行者、序列号、有效期等,否则返回错误消息

后面你就可以在Profile文件使用新生成的Java KeyStore文件了,在Profile文件中你可以这样设置:
stage
之前说过的无阶段payload会远程加载并执行stage,其实这个stage就是一个反射dll(Beacon Dll),通过修改stage块的内容可以扩展Beacon Dll的功能,以此达到一定的免杀效果
以下是一个stage代码块的例子:
在 stage 部分,我们可以使用不同的命令来绕过一些防御机制和检测策略,如下表格所示:
命令/选项
描述
prepend
用于避免某些扫描内存段的前几个字节以查找注入的 DLL 的痕迹的检测。
strrep
用于替换指定的字符串,如默认的 "ReflectiveLoader" 字符串。
sleep_mask
用于启用内存混淆,使 Beacon 在每次 sleep 之前都混淆自己所在的内存区域,并在 sleep 结束后解混淆。此功能专门绕过内存扫描的杀软(比如卡巴)
userwx
控制 Beacon 的反射加载器是否使用 RWX 权限来分配内存,设置为 false 可以避免引发警告和关注。
allocator
用于改变默认的内存分配器 VirtualAlloc,可以选择使用 HeapAlloc 或 MapViewOfFile 来替代。
module_(x64,x86)
1是 allocator 选项的一部分,用于指定不同架构下的分配器。
cleanup
控制是否在 Beacon stage 初始化完成后释放 stage 所占用的内存,设置为 true 可以避免留下内存痕迹。
process-inject
process-inject 代码块是用于控制 Beacon 在注入到远程进程时的行为。在进行攻击时,攻击者可能会尝试将 Beacon 注入到一个正在运行的进程中以实现持久化和隐藏
以下代码是Cobalt Strike配置中进程注入部分的设置,它定义了Cobalt Strike如何在远程进程中注入和执行代码。特别的,它设置了使用"VirtualAllocEx"为远程进程分配内存,内存分配的最小值设为7814字节。它指定了新分配的内存区域不应该具有读、写和执行(RWX)权限,也就是不允许在分配和写入载荷之前,内存区域具有这样的权限。为了避免某些防御机制的检测,它还在注入的代码前添加了几个NOP(无操作)指令。此外,它定义了多种在远程进程中执行代码的方法,包括使用CreateThread,NtQueueApcThread-s,SetThreadContext,CreateRemoteThread和RtlCreateUserThread等函数,这提供了进程注入的灵活性和多样性,使得攻击更难被防御措施检测到。
注:transform-x86和transform-x64代码块用于对注入的代码进行转换,可以向Beacon注入的内容添加东西,你可以使用append和prepend命令来向注入的代码前或后添加额外的代码,又或者使用replace-str和replace-all-str命令在注入的代码中替换字符串
post-ex
post-ex代码块在Cobalt Strike的Beacon payload中是用来配置后期执行(post-exploitation)阶段的一些参数。这些参数主要影响和控制如何创建新的进程、怎样注入和执行代码、如何混淆和隐藏行为以及如何收集和传输数据等。
在如上代码中,使用spawnto_x86和spawnto_x64设置来定义在32位和64位系统上新创建的进程的名称,可以使用obfuscate设置来决定是否对Beacon用于后期执行任务的DLL进行混淆以避免被检测,还可以通过amsi_disable设置来决定是否禁用目标系统的AMSI(防恶意软件扫描接口)来避免被反恶意软件工具检测等等。
pipename参数用于定义或改变在后期执行阶段使用的命名管道(命名管道是一种在本地或网络上的不同进程之间进行通信的机制。在Windows系统中,它们通常用于在不同的进程或者系统之间共享和传输数据。它们的名字通常以\\.\pipe\开始,然后是任意你选择的名称)。特别地,pipename中的#符号会被替换为一个随机的数字,这样每次创建新的命名管道时都会使用一个不同的名称,从而进一步提高了隐蔽性
例如,set pipename "srvsvc-1-5-5-0####";设置将创建一个名为srvsvc-1-5-5-0后面跟四个随机数字的命名管道,例如srvsvc-1-5-5-01234。这个名字看起来像一个正常的Windows服务,可能不会引起安全人员的注意
参考链接
https://wbglil.gitbook.io/cobalt-strike/cobalt-strikekuo-zhan/malleable-c2#malleable-c2-ji-ben-yu-fa
https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2_profile-language.htm#_Toc65482837
最后更新于