偶然看到一篇介紹JARM工具的文章,用於識別TLS指紋,其中還可以用於Cobalt Strike識別。
關於JARM
工具介紹
一個TLS服務器指紋識別工具 https://codeload.github.com/salesforce/jarm/zip/refs/heads/master
通過生成特定的TLS Client Hello數據包,獲取服務器響應
收到響應后解析TLS Server Hello數據包,拼接為
服務器返回的加密套件 | 服務器返回選擇使用的TLS協議版本 | TLS擴展ALPN協議信息 | TLS擴展列表
python jarm.py -v ipaddr -p port
Resolved IP: xxxx
JARM: 07d14d16d21d21d07c42d41d00041d24a458a375eef0c576d23a7bab9a9fb1
Scan 1: 0033|0303||0001-0017-ff01,
Scan 2: 009d|0303||0001-0017-ff01,
Scan 3: 009f|0303||0001-0017-ff01,
Scan 4: c013|0303||0001-0017-ff01,
Scan 5: c013|0303||0001-0017-ff01,
Scan 6: 0033|0302||0001-0017-ff01,
Scan 7: 1302|0303||002b-002c-0033,
Scan 8: 1301|0303||002b-002c-0033,
Scan 9: |||,
Scan 10: 1301|0303||002b-002c-0033
通過發送10次TLS Client Hello並解析為以上格式,將10次解析的結果拼接以后最終調用jarm_hash算出最終的結果。
jarm_hash前30個字符由加密套件和TLS協議版本分別使用cipher_bytes、version_byte函數計算拼接而來,其余的32個字符是由TLS擴展ALPN協議信息和TLS擴展列表通過sha256哈希並截取而來。
[1]360 QUAKE 利用JARM指紋進行TLS服務端標記
識別Cobalt Strike HTTPS
利用JARM指紋識別Cobalt Strike不是很准確,在查資料中發現了以下幾種方法:
1.Cobalt Strike默認證書
2.Response響應特征
3.利用stager獲取CobaltStrike Beacon configurations配置信息(也就是Fofa/ZoomEye等Banner)
4.JARM指紋
Cobalt Strike默認證書
參考鏈接
[2]關於Cobalt Strike檢測方法與去特征的思考
根據這篇文章 里面提到了CS的默認證書攜帶了明顯特征,這是teamserver服務器主控端的特征
O=cobaltstrike, OU=AdvancedPenTesting, CN=Major Cobalt Strike
在TLS協商過程中這個數據包是明文的,可以通過流量進行檢測
第二種是HTTPS上線時使用的證書,默認證書如下:
隨機挑了部分IP測試,確認存在這個特征
curl URL -v -k
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: C=; ST=; L=; O=; OU=; CN=
* start date: May 20 18:26:24 2015 GMT
* expire date: May 17 18:26:24 2025 GMT
* issuer: C=; ST=; L=; O=; OU=; CN=
* SSL certificate verify result: self signed certificate (18), continuing anyway.
其中還提到了一個特征需要再確認
73:6B:5E:DB:CF:C9:19:1D:5B:D0:1F:8C:E3:AB:56:38:18:9F:02:4F
Response 響應
[3]大海撈“幀”:Cobalt Strike服務器識別與staging beacon掃描
1.NanoHTTPD響應 (適用於3.x)
NanoHTTPD服務器響應中包含一個額外的空字節:"HTTP/1.1"后面是一個空字節(0x20),而在其他web服務器響應中不存在這個空字節
2.
知道創宇報告稱,構建Cobalt Strike的開源NanoHTTPD代碼響應方式如下:
HTTP/1.1 404 Not Found
Content-Type: text/plain
Date: Day, DD Mmm YYYY HH:MM:SS GMT
Content-Length: 0
知道創宇的檢測邏輯就是基於這一發現。然而他們隨后還觀察到HTTP響應中的順序實際上可能不同,在一些Cobalt Strike系統的響應中"Content-Type"在"Date"之后顯示。
利用stager獲取CobaltStrike Beacon configurations配置信息
在fofa中 發現存在如下Banner
這些信息既不在響應包中,也不在TLS協商過程中。實際上是利用CobaltStrikeParser得到的
流程如下:
首先通過投遞一個被稱為stager的小巧的payload,然后去Beacon staging server下載體積較大更復雜的stage,並且訪問stage的URL通過checksum8進行校驗。
利用這段代碼,可獲取對應的checksum8,拼接在URL之后進行下載Stage文件
import random
def generate_checksum(input):
trial = ""
total = 0
while total != input:
total = 0
trial = ''.join(random.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
for i in range(4))
for i in range(4):
total = (total + ord(trial[i:i+1])) % 256
return trial
if __name__ == '__main__':
uri_x86 = generate_checksum(92) # 32位的payload
uri_x64 = generate_checksum(93) # 64位的payload
print(uri_x86)
print(uri_x64)
利用CobaltStrikeParser進行解析
python .\parse_beacon_config.py https://xx/qO1k
BeaconType - HTTPS
Port - 443
SleepTime - 10000
MaxGetSize - 1048576
Jitter - 20
MaxDNS - Not Found
PublicKey_MD5 - b943cb16be7ac6b4db0b559dea797dd9
C2Server - 47.106.88.225,/c/msdownload/update/others/2021/03/29136388_
UserAgent - Windows-Update-Agent/10.0.10011.16384 Client-Protocol/1.40
HttpPostUri - /c/msdownload/update/others/2020/10/28986731_
Malleable_C2_Instructions - Empty
HttpGet_Metadata - ConstHeaders
Accept: */*
Host: download.windowsupdate.com
Metadata
base64
prepend "SESSION="
header "Cookie"
HttpPost_Metadata - ConstHeaders
Accept: */*
Host: download.windowsupdate.com
SessionId
parameter "update_id"
Output
base64
print
PipeName - Not Found
DNS_Idle - Not Found
DNS_Sleep - Not Found
SSH_Host - Not Found
SSH_Port - Not Found
SSH_Username - Not Found
SSH_Password_Plaintext - Not Found
SSH_Password_Pubkey - Not Found
SSH_Banner -
HttpGet_Verb - GET
HttpPost_Verb - POST
HttpPostChunk - 0
Spawnto_x86 - %windir%\syswow64\notepad.exe
Spawnto_x64 - %windir%\sysnative\notepad.exe
CryptoScheme - 0
Proxy_Config - Not Found
Proxy_User - Not Found
Proxy_Password - Not Found
Proxy_Behavior - Use IE settings
Watermark - 1234567890
bStageCleanup - True
bCFGCaution - False
KillDate - 0
bProcInject_StartRWX - False
bProcInject_UseRWX - False
bProcInject_MinAllocSize - 18500
ProcInject_PrependAppend_x86 - b'\x90\x90\x90\x90'
b'\x90\x90\x90\x90'
ProcInject_PrependAppend_x64 - b'\x90\x90\x90\x90'
b'\x90\x90\x90\x90'
ProcInject_Execute - ntdll:RtlUserThreadStart
CreateThread
NtQueueApcThread-s
CreateRemoteThread
RtlCreateUserThread
ProcInject_AllocationMethod - NtMapViewOfSection
bUsesCookies - True
HostHeader -
headersToRemove - Not Found
DNS_Beaconing - Not Found
DNS_get_TypeA - Not Found
DNS_get_TypeAAAA - Not Found
DNS_get_TypeTXT - Not Found
DNS_put_metadata - Not Found
DNS_put_output - Not Found
DNS_resolver - Not Found
DNS_strategy - round-robin
DNS_strategy_rotate_seconds - -1
DNS_strategy_fail_x - -1
DNS_strategy_fail_seconds - -1
JARM指紋
07d14d16d21d21d07c42d41d00041d24a458a375eef0c576d23a7bab9a9fb1
在8月份阿里雲環境 443開放的50個IP中出現11次