通過進程內存提取密鑰解密Cobalt Strike流量
如前文所述,Cobalt Strike 網絡流量可以使用正確的 AES 和 HMAC 密鑰進行解密。之前也講述了如何通過解密 Cobalt Strike 元數據的方法獲取密鑰,本文將會重點描述從內存 Dump 中提取密鑰的方法。
通過共享密鑰解密 Cobalt Strike 流量
Avenger,公眾號:威脅棱鏡破解版密鑰相同,部分CobaltStrike加密流量可解
如果發現了正在運行的 Beacon 進程,可以使用 Sysinternals 的 procdump 來生成內存 Dump。并不需要完整的內存 Dump,只使用 procdump.exe -mp pid dump 可寫進程內存即可。其中, -mp 是獲取可寫內存 dump 的參數, pid 是正在運行的 Beacon 進程的 PID。
對于 Cobalt Strike 3.x 的 Beacon,未加密的元數據頭通常可以使用 0x0000BEEF 作為特征在內存中檢索。獲取內存 Dump 的時間越早,也就越有可能包含未加密的元數據。

進而可以使用 cs-extract-key.py 查找并解碼元數據:

元數據中包含 16 字節的隨機密鑰,通過對該密鑰計算 SHA256。 SHA256 的前半部分作為 HMAC 密鑰,后半部分作為 AES 密鑰。
得到了密鑰和原來描述的使用方式基本類似,也可以通過 cs-parse-http-traffic.py 來解密流量。
值得注意的是,cs-extract-key.py可能存在誤報。發現以0x0000BEEF開頭的字節序列并不都是元數據。上篇文中的示例就是好例子,第一個例子包含機器名稱和用戶的確實是有效的元數據,這些元數據也可以在進程內存的其他位置中發現。但是第二個例子實際上沒有得到可識別的名稱,在其他位置也找不到 AES 和 HMAC 密鑰,這就是一個誤報。
對于 Cobalt Strike 4.x 的 Beacon,通過內存直接提取未加密元數據的可能性變得極低了。因為 此時已經沒有數據頭來進行標識了,單純的 16 字節長序列沒有可區分的特征。只能通過在進程內存中找到所有可能的 16 字節長非空序列作為密鑰字典,不斷嘗試解密 C&C 通信,碰撞成功就找到了密鑰。
提取方式例如 cs-parse-http-traffic.py -k unknown capture.pcapng, -k 表示密鑰未知,該工具嘗試提取加密數據流量:

數據包 103 是對數據包 97 的 GET 請求的 HTTP 響應,響應數據長 64 字節(d12c14aa698a6b85a8ed3c3c33774fe79acadd0e95fa88f45b66d8751682db734472b2c9c874ccc70afa426fb2f510654df7042aa7d2384229518f26d1e044bd)。
這應該就是 Team Server 發送給 Beacon 的加密數據,通過 cs-extract-key.py -t d12c14aa698a6b85a8ed3c3c33774fe79acadd0e95fa88f45b66d8751682db734472b2c9c874ccc70afa426fb2f510654df7042aa7d2384229518f26d1e044bd rundll32.exe_211028_205047.dmp 嘗試提取密鑰:

之后就可以使用提取的 AES 和 HMAC 密鑰解密流量(-k HMACkey:AESkey):

可以看到解密后的命令是 DATA_JITTER,該命令表示服務器向 Beacon 發送可以忽略的隨機數據。使用默認配置文件的 Cobalt Strike 不會發送隨機數據,也不會使用 Malleable 進行處理。這表示,只要沒有需要 Beacon 執行的命令,就不會向 Beacon 發送數據,HTTP 響應長度為 0。這樣即使流量是加密的,也可以確定 Beacon 是否收到了命令。
為了避免這種明顯的特征,Cobalt Strike 支持交換隨機數據,使數據包保持唯一性。不過這反而對防御者有用:如果不發送隨機數據,觀測不到加密數據,也就不能識別進程內存中的加密密鑰了。
Beacon 回傳給 Team Server 的數據通過 POST 請求發送,該數據也可以用于查找解密密鑰。使用方式類似,區別在于使用 -c 而不是 -t 參數,原因在于 Team Server 的加密方式和 Beacon 的加密方式略有不同。
一些注意事項
- 較大的內存 Dump 需要較長的時間來進行密鑰字典碰撞。
- 使用完整內存 Dump 需要的時間更長
- 4.x 版本的方法也適用于 3.x 版本
NVISO 的研究人員正在開發能夠解析 Dump 文件的數據結構,提取最可能包含密鑰的內存部分,加快密鑰提取過程的工具。
cs-analyze-processdump.py
https://github.com/DidierStevens/Beta/blob/master/cs-analyze-processdump.py
Beacon 可以配置為在不活動時對其可寫內存進行編碼,來進行保護。此時,AES 和 MHAC 密鑰也會被編碼,且無法使用上述的方法進行恢復。
思考
想要解密 Cobalt Strike 流量,最好是存在相對應的 RAS 私鑰。如果沒有,也可以使用內存 Dump 來恢復 HMAC 和 AES 密鑰。
防御者對 Cobalt Strike 的理解應該更加深入,只有在技術原理和實際實現的層面深入理解,才能發現更有效的檢測方式。以不斷地深入研究總結經驗,應對千變萬化的攻擊形式。實際上不僅是防御者,Cobalt Strike 一路走來的不斷更新都是攻防對抗不斷升級的結果,從旁觀到親歷的視角轉變也許可以讓每一個攻擊者來主動思考 Cobalt Strike 之所以成功的原因。