作者:風起
本文為作者投稿,Seebug Paper 期待你的分享,凡經采用即有禮品相送! 投稿郵箱:paper@seebug.org
基于JARM指紋的C2識別
JARM的工作原理是主動向目標TLS服務器發送10個特殊構造的TLS Client Hello包,以在TLS服務器中提取獨特的響應,并捕獲TLS Server Hello響應的特定屬性,然后以特定的方式對聚合的TLS服務器響應進行散列,產生JARM指紋。
因為Client Hello中的參數不同,最終返回的Server Hello都是不相同的,通過發送特殊構造的Client Hello握手包,以獲取與之對應的特殊Server Hello響應,以此作為依據,最終產生TLS Server指紋。
JARM以不同的順序發送不同的TLS版本、密碼和擴展,以收集唯一的響應。
- 服務器是否支持TLS 1.3協議?
- 它會用1.2個密碼來協商TLS 1.3嗎?
- 如果我們將密碼從弱到強排序,它會選擇哪個密碼?
這些是JARM本質上要求服務器提取最獨特響應的異常問題類型。然后對這10個響應進行哈希處理以產生JARM指紋。
TLS Client Hello請求流量
Wireshark Filter:
ssl.handshake.type == 1

TLS Server Hello響應

多數情況下JARM指紋都是用以佐證TLS服務并進行標記,從而關聯服務。當然,最理想的狀態下,我們能夠通過JARM指紋唯一的指向目標C2設施,但是實際來講JARM指紋對于不同服務器部署的C2設施并不是唯一的,有很多因素都會對其掃描的結果造成影響。所以我們并不能作為行為測繪的指紋直接關聯到某個C2的服務,僅能作為佐證的效果。
在開發RedGuard的過程中我發現,因為本身來講RG的作用就是進行前置流量的控制,從而實現后端C2服務的隱匿性,在藍隊對流量交互進行分析的時候,針對RG的JARM指紋掃描結果在多數差異的環境下都是相同的,也就是說,在分析的過程中,這個指紋是可以起到佐證攻擊設施的作用,從而破壞我們想要預期達到的隱匿性。
基礎設施的更改(例如,IP 地址、托管平臺)不會影響JARM簽名,這使得常規的方式難以對其進行規避。
影響服務端JARM指紋的因素:
- 操作系統及版本
- 使用的庫及版本
- 調用庫的順序
- 自定義配置
- ........
也就是說,如果我們想要影響最終針對服務端的JARM指紋掃描結果,我們就要從上面的幾個因素入手去做,目前的解決方案共有兩種:
一、重播TLS Server Hello響應
二、更改TLS Server配置CipherSuites加密套件
第一種方式也就是在監聽特定客戶端 Hello 的 TCP 服務器,然后在C2服務器上捕獲這些特定的Client Hello(每個請求都有重復的字節,使用這些字節來識別每個特定的Client Hello握手包),穩定的對這10個特殊構造的Client Hello的響應進行重播,從而實現改變真實JARM指紋的效果。
if bytes.Contains(request, [] byte {
0x00, 0x8c, 0x1a, 0x1a, 0x00, 0x16, 0x00, 0x33, 0x00,
0x67, 0xc0, 0x9e, 0xc0, 0xa2, 0x00, 0x9e, 0x00, 0x39
, 0x , 0xc0, 0x9f, 0xc0, 0xa3, 0x00, 0x9f, 0x00,
0x45, 0x00, 0xbe, 0x00, 0x88, 0x00, 0xc4, 0x00, 0x9a,
... ...
}) {
fmt.Println("replaying: tls12Forward ")
conn.Write([] byte {
0x16, 0x03, 0x03, 0x00, 0x5a, 0x02, 0x00, 0x00,
0x56, 0x03, 0x03, 0x17, 0xa6, 0xa3, 0x84, 0x80,
0x0b, 3,d, 0xbb, 0x 0xe9, 0x3e, 0x92, 0x65,
0x9a, 0x68, 0x7d, 0x70, 0xda, 0x00, 0xe9, 0x7c,
... ...
})
}
在對所有十個不同的請求實施回復后,可以偽造完整的簽名。

這是一種比較懶惰的辦法了,最終的效果確實能夠對JARM掃描的結果進行混淆,但是我認為太過單調,需要注意的是ServerHello的原始響應他不能進行任意修改,因為在工具開發中流量的正常交互才是最重要的,任意修改上述一些影響 JARM掃描的因素可能導致無法正常通信的問題出現。也就是說他所重播的這些ServerHello數據包是需要監聽某個正常的服務的JARM掃描響應來實現的,并不適合我們應用到工具去實現混淆的效果,我們需要一種簡單而又穩定的方法。
當然,這種方式還有一種延伸,就是首先隨機獲取正常站點的列表進行JARM指紋掃描,從而獲取其ServerHello響應然后,直接作為識別到JARM掃描握手包的響應包進行重播,這樣是最合理的一種方式。
第二種也就是阿姆斯特丹2021 HITB議題《COMMSEC: JARM Randomizer: Evading JARM Fingerprinting》中提到的一種方式,作者在github上對衍生工具 JARM Randomizer進行了部分開源,通過閱讀它的代碼不難看出,其實與我最初想到的方式非常相像,最終影響JARM的因素使用的是CipherSuites加密套件(加密算法套件 CipherSuite 由各類基礎加密算法組成)
實現代碼:

如上圖,針對反向代理的TLS Config CipherSuites的設置,我提供了15種不同的加密套件方式,1/2/3....個不同組合的加密套件最終得到的JARM指紋結果都不是相同的(加密套件過多會導致無法正常通信的玄學問題),這里我對這15種加密套件進行隨機組合的方式,1-2個隨機取值進行組合這些CipherSuites,大概會有幾十種不同的隨機JARM指紋產生。
最終效果如下:

可以看到,最終應用在工具的效果就是在每次啟動RG的時候,它的JARM指紋都不是相同的,會自動根據上述的混淆方式產生一個全新的JARM指紋,可以防止空間測繪的掃描,以此關聯公網上RG基礎設施的部署情況。目前市面上多數測繪平臺都會進行集成并默認進行JARM指紋的掃描,可能也是因為其掃描效率快,掃描資源成本低、同時又對C2設施有著一定的佐證指向性的原因吧。
RedGuard是一款C2基礎設施前置流量控制設施,可以規避Blue Teams、AVs、EDRs檢查。
參考鏈接:
https://github.com/wikiZ/RedGuard
https://github.com/netskopeoss/jarm_randomizer
https://grimminck.medium.com/spoofing-jarm-signatures-i-am-the-cobalt-strike-server-now-a27bd549fc6b
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1934/
暫無評論