JA3 JA3S JARM学习
偶然看到一篇介绍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次