深藍(lán)實驗室@lz520520
介紹
https等協(xié)議通過tls加密傳輸,大家可能覺得數(shù)據(jù)被全加密了應(yīng)該可以保證無惡意流量特征,流量側(cè)通信不會被發(fā)現(xiàn),但在加密前,會有一個tls協(xié)商過程,client和server協(xié)商交互才會生成最后加密用的密鑰,而這個協(xié)商過程就可以切切實實進(jìn)行指紋提取。這就是tls指紋。
JA3是一種創(chuàng)建SSL/TLS客戶端指紋的方法,它易于在任何平臺上生成,并且可以輕松共享以獲取威脅情報。JA3 由三位 Salesforce 成員(John Althouse、Jeff Atkinson 和 Josh Atkins)開發(fā),是一種用于根據(jù) ClientHello 數(shù)據(jù)包生成 SSL 指紋以識別建立加密連接的客戶端的技術(shù)。相同的客戶端工具所產(chǎn)生的JA3指紋總是一致的。JA3 指紋從一開始就是為了證明客戶端應(yīng)用程序是否存在惡意。
我們在使用burpsuite等工具時,經(jīng)常會遇到網(wǎng)站無法打開,去掉代理又變正常的情況,很可能是網(wǎng)站的WAF使用了JA3指紋識別到了代理工具。常見的如cloudfare waf就使用了該指紋技術(shù)。
go默認(rèn)ja3指紋89be98bbd4f065fe510fca4893cf8d9b
chromeja3指紋cd08e31494f9531f560d64c695473da9
分析
ja3
tls指紋生成過程
JA3方法用于收集Client Hello數(shù)據(jù)包中以下字段的十進(jìn)制字節(jié)值:版本、可接受的密碼、擴(kuò)展列表、橢圓曲線密碼和橢圓曲線密碼格式。然后,它將這些值串聯(lián)在一起,使用“,”來分隔各個字段,同時,使用“-”來分隔各個字段中的各個值。
版本、可接受的密碼、擴(kuò)展列表、橢圓曲線密碼和橢圓曲線密碼格式 SSLVersion,Cipher-Suites,SSLExtension,EllipticCurve,EllipticCurvePointFormat
例子
769,47-53-5-10-49161-49162-49171-49172-50-56-19-4,0-10-11,23-24-25,0
然后使用MD5 hash生成指紋
ada70206e40642a3e4461f35503241d5
具體分析
這里以go開發(fā)的frp為例
Client Hello數(shù)據(jù)包如下,ja3就是由以下圈出來的部分生成的
SSLVersion
這里顯示是 TLS1.2,對應(yīng)實際值是0x0303
轉(zhuǎn)換成十進(jìn)制為
771
Cipher-Suites
如下加密算法套件有19個,根據(jù)ja3規(guī)則,每個之間用"-"連接
轉(zhuǎn)換成果如下
49199-49200-49195-49196-52392-52393-49171-49161-49172-49162-156-157-47-53-49170-10-4865-4867-4866
SSLExtension
這個擴(kuò)展列表是由所有擴(kuò)展類型值組成,如下擴(kuò)展類型值有8個
生成結(jié)果為
5-10-11-13-65281-18-43-51
EllipticCurve
橢圓曲線密碼
即擴(kuò)展type值為10對應(yīng)的數(shù)據(jù),這里寫的是supported_group
生成結(jié)果為
29-23-24-25
EllipticCurvePointFormat
橢圓曲線格式
即擴(kuò)展type只為11對應(yīng)的數(shù)據(jù),這里數(shù)據(jù)值為0
生成結(jié)果為
0
最后將上面所有部分用","拼接組成最終需要hash的字符串
771,49199-49200-49195-49196-52392-52393-49171-49161-49172-49162-156-157-47-53-49170-10-4865-4867-4866,5-10-11-13-65281-18-43-51,29-23-24-25,0
進(jìn)行hash計算如下
通過ja3工具解析數(shù)據(jù)包結(jié)果,可以看到和我們計算結(jié)果一致
ja3s
JA3S方法會收集Server Hello數(shù)據(jù)包中以下各個字段的十進(jìn)制字節(jié)值:版本、可接受的加密算法和擴(kuò)展列表。然后,它將這些值串聯(lián)在一起,使用“,”來分隔各個字段,并通過“-”來分隔每個字段中的各個值。
SSLVersion,Cipher,SSLExtension 769,47,65281–0–11–35–5–16
PS: 因為Server Hello會因為Client Hello不同和不同,所以只能做一個參考。
計算
FRP的Server Hello數(shù)據(jù)包如下,計算需要的三部分如下
SSLVersion
版本
生成結(jié)果
771
Cipher
可接受的加密算法,只有一個
生成結(jié)果
4865
SSLExtension
擴(kuò)展列表,擴(kuò)展列表只有兩個
根據(jù)類型值,生成結(jié)果
43-51
將上述拼接起來
771,4865,43-51
但ja3s工具生成,加密套件這塊額外添加了參數(shù)實際算法名稱
如下,但實際表示意義也是唯一的
771,CipherSuite(0x1301, TLS_AES_128_GCM_SHA256),43-51
繞過
文章
https://mp.weixin.qq.com/s/og2IKo8lcydh8PROUPD7jQhttps://segmentfault.com/a/1190000041699815
庫
https://github.com/refraction-networking/utls
這個庫是基于crypto/tls進(jìn)行開發(fā)的,可以模擬絕大部分情況下的ja3指紋。
和官方庫差不多的用法,如下在封裝時除了conn連接和config配置以外,需要傳入ClientHelloID,這個ID是有一些內(nèi)置的指紋可以直接調(diào)用,或者也可以自定義。
conn,?_?:=?net.DialTimeout("tcp",?"121.14.77.201:443",?10*time.Second) uConn?:=?tls.UClient(conn,?&tls.Config{ServerName:?"www.qq.com",?InsecureSkipVerify:?true},?tls.HelloChrome_102) uConn.Write([]byte("aaa"))
這是官方庫
u_common.go,如下有非常全的現(xiàn)成指紋信息可以用。
這些ID最終對應(yīng)到這個函數(shù)utlsIdToSpec里
后續(xù)可參考這里編寫實現(xiàn)自己的。
并且該庫還支持解析數(shù)據(jù)包中的client hello信息,來自動化構(gòu)建一個自定義參數(shù),實現(xiàn)模擬各種ja3指紋
瀏覽器訪問,然后抓包找到client hello包,選中tls層的數(shù)據(jù),然后復(fù)制成hex stream即可。
將tls的hex數(shù)據(jù)粘貼到以下位置,通過fingerprinter.FingerprintClientHello即可解析生成一個自定義spec,封裝到tlsConn里直接使用。
要注意的是ClientHelloID還設(shè)置成HelloCustom即自定義
conn,?_?:=?net.DialTimeout("tcp",?"121.14.77.201:443",?10*time.Second) rawCapturedClientHelloBytes,?_?:=?hex.DecodeString("1603010200010001fc03037741eebedfb7afbcfcd0f49f9b59d7a9c13eb3ccd8f207b8c692ffb1b9b9f5c22017bd40c3ec96ca8c21df97de564ce5e4e88bc945ca902d7d4260f77fb980631400221a1a1301130213021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035010001918a8a000000000012001000000d7370312e62616964752e636f6d00170000ff01000100000a000a0008dada001d00170018000b00020100002300a00efd73f80bf561e25ea122de025cb65678ebfcd201e8c49325fbabe586918cdb8cfdeaac64d4798b351295c62d94aa3c48a8f4181bee25d4202025cbf7eaf074233d576018c8adfe0d4527daa496e1b05162c0490a00fb108522a31e0bf369482a97a77d62f147f1657e927b45223545e7ad54f99239d820ed81b41c172a15dc3762f5d8fd1d333e082f55daca4e38ae11456fa4caf6be4419b56e5ed36a08580010000e000c02683208687474702f312e31000500050100000000000d0012001004030804040105030805050108060601001200000033002b0029dada000100001d0020ecb49f62fef0dc89ff3e6084d99e39b27820e68d9c4d8bf24b6d367e286ce05a002d00020101002b000706baba03040303001b0003020002446900050003026832caca0001000015002800000000000000000000000000000000000000000000000000000000000000000000000000000000") uConn?:=?tls.UClient(conn,?&tls.Config{ServerName:?"www.qq.com",?InsecureSkipVerify:?true},?tls.HelloCustom) fingerprinter?:=?&tls.Fingerprinter{} generatedSpec,?err?:=?fingerprinter.FingerprintClientHello(rawCapturedClientHelloBytes) if?err?!=?nil?{ t.Fatalf("fingerprinting failed: %v",?err) } if?err?:=?uConn.ApplyPreset(generatedSpec);?err?!=?nil?{ t.Fatalf("applying generated spec failed: %v",?err) } uConn.Write([]byte("aaa"))
可以看到完全一致(wireshark好像3.6以上就支持ja3的指紋生成了)
PS: 要注意一點,SNI也會參與計算,如果ServerName為空會不插入Extension里,導(dǎo)致ja3指紋計算結(jié)果不一樣
這個庫還有些其他玩法,可以自行參考文檔或者他的example.go文章來源:http://www.zghlxwxcb.cn/news/detail-453911.html
存在小bug,如果自動握手,可能會出現(xiàn)握手失敗的問題,建議手動握手文章來源地址http://www.zghlxwxcb.cn/news/detail-453911.html
uConn?:=?tls.UClient(c,?tlsConfig,?tls.HelloChrome_Auto) // 錯誤姿勢,如此可能會報錯 uConn.Write([]byte("a")) // 正確姿勢 err?:=?uConn.Handshake()
到了這里,關(guān)于TLS指紋模擬的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!