深度剖析ja3指紋及完美突破 js逆向之猿人學第十九題突破ja3指紋驗證

前言

 

其實才沒幾天發過ja3相關的文章:js逆向之猿人學第十九題突破ja3指紋驗證  ,原本是沒打算寫後續的,由於蔡老闆很仗義地幫我推了一波(蔡老闆這無處安放的魅力啊),使得我寫得不太專業的文章被很多大佬關注到了,加上有很多東西沒有闡述清楚,同時我由於對寫公衆號文章經驗不足導致出現一些影響閱讀體驗的問題,本着更深入理解ja3指紋的目的,所以催生出了當前這篇文章。

 

注:本篇文章略長,如果趕時間的朋友,可以直接跳過接下來的理論概念介紹,可以直接從後面的【如何突破ja3】開始看

 

到底什麼是ja3

簡介

 

git:https://github.com/salesforce/ja3

 

官方解釋+谷歌翻譯:

JA3 是一種創建 SSL/TLS 客戶端指紋的方法,它應該易於在任何平臺上生成,並且可以輕鬆共享以用於威脅情報

 

 

更權威的介紹文章:TLS Fingerprinting with JA3 and JA3S

 

濃縮一下大概意思就是:

JA3 是一種對傳輸層安全應用程序進行指紋識別的方法。它於 2017 年 6 月首次發佈在 GitHub 上,是 Salesforce 研究人員 John Althouse、Jeff Atkinson 和 Josh Atkins 的作品。創建的 JA3 TLS/SSL 指紋可以在應用程序之間重疊,但仍然是一個很好的妥協指標 (IoC)。指紋識別是通過創建客戶端問候消息的 5 個十進制字段的哈希來實現的,該消息在 TLS/SSL 會話的初始階段發送。

 

這.....,2017年就有了,我是今年才通過閱讀青南大佬的文章知道有這麼個東西。

 

然後我猜,ja3名字的由來,是因爲有3個研究人員,且他們的姓名縮寫都是ja

 

ja3的由來

 

其實,John Althouse 自己說過,官方解釋+谷歌翻譯:

對這個 TLS 客戶端進行指紋識別的主要概念來自 Lee Brotherston 2015 年的研究(https://blog.squarelemon.com/tls-fingerprinting/)和他的 DerbyCon 演講(https://www.youtube.com/watch?v=XX0FRAy2Mec)。如果不是 Lee ,就不會有JA3的出現

 

 

ja3如何工作的

 

原文解釋的很好了,官方解釋+谷歌翻譯:

TLS 及其前身 SSL 用於爲常見應用程序和惡意軟件加密通信,以確保數據安全,因此可以隱藏在噪音中。要啓動 TLS 會話,客戶端將在 TCP 3 次握手之後發送 TLS 客戶端 Hello 數據包。此數據包及其生成方式取決於構建客戶端應用程序時使用的包和方法。服務器如果接受 TLS 連接,將使用基於服務器端庫和配置以及 Client Hello 中的詳細信息制定的 TLS Server Hello 數據包進行響應。由於 TLS 協商以明文形式傳輸,因此可以使用 TLS Client Hello 數據包中的詳細信息來指紋和識別客戶端應用程序

 

更多更專業的,如果很感興趣,勞煩移步John Althouse發表的文章:Open Sourcing JA3

 

感覺看了上面的話,是不是有點似懂非懂的感覺,沒事,聽我慢慢說,來個圖吧,要來圖的話,先來個三次握手的吧,老圖了,相信各位朋友也都看煩了,我也看煩了,因爲這圖都傳包漿了

 

 

 詳細的三次握手流程解釋我就不說了,網上能查到的太多了,我就不獻醜解釋了,本篇文章的重點也不是它

 

那麼按照ja開發者自述,是在三次握手之後,客戶端向服務端發起client hello包,這個包裏帶了客戶端這邊的一些特徵發給服務端,服務端拿來解析數據包,然後回發一個hello給客戶端,之後再進行ssl數據交互,下面這個圖,就是John Althouse自己畫的

 

 

 

 

怎麼說?畫的很傳神很易懂對吧?

 

更多原文解釋,請看這裏:TLS Fingerprinting with JA3 and JA3S

John Althouse有關ja3的ppt講義,上面的動圖就是ppt文件裏的,費了老大勁搞到的:鏈接: https://pan.baidu.com/s/1pfQwRwg3tbOT2Y2nQZYoAA 提取碼: ptj6 (鏈接失效了可以聯繫我)

 

 

識別原理

 

以下也都是John Althouse的文章裏的+谷歌翻譯:

 

1.JA3 不是簡單地查看使用的證書,而是解析在 SSL 握手期間發送的 TLS 客戶端 hello 數據包中設置的多個字段。然後可以使用生成的指紋來識別、記錄、警報和/或阻止特定流量。

2.JA3 在 SSL 握手中查看客戶端 hello 數據包以收集 SSL 版本和支持的密碼列表。如果客戶端支持,它還將使用所有支持的 SSL 擴展、所有支持的橢圓曲線,最後是橢圓曲線點格式。這些字段以逗號分隔,多個值用短劃線分隔(例如,每個支持的密碼將在它們之間用短劃線列出)

 

3. JA3 方法用於收集 Client Hello 數據包中以下字段的字節的十進制值:版本、接受的密碼、擴展列表、橢圓曲線和橢圓曲線格式。然後按順序將這些值連接在一起,使用“,”分隔每個字段,使用“-”分隔每個字段中的每個值

 

其中第一條,也解釋了我前一篇請求時嘗試提交一個ssl證書爲啥沒有用的

第二條,服務端會在3次握手之後,收到客戶端過來的hello包,然後解包,收集版本、接受的密碼、擴展列表、橢圓曲線和橢圓曲線格式,在這時候就可以拿着ja3指紋去比對,哪些是限制了,哪些沒有限制的,當確實有在限制名單裏,就針對處理,當沒有在限制名單裏也返回一個hello,接着再繼續ssl

 

 

ja3已收錄指紋/黑名單

 

 

我猜測,ja3er.com裏的十幾萬ja3指紋,就是所有人訪問過該網站的客戶端(瀏覽器或者語言請求庫)的指紋,有一條算一條的收集

 

 

案例解釋

前面說了一堆理論概念,我們做開發的,如果只有概念沒有實操或者例子解釋是不夠的,所以,來個案例,還是猿人學19題,同時繼續祭出wireshark方便分析,先瀏覽器訪問網站,拿到ip,提示一下,你們可別拿着ip去幹人網站哈,挺好的一個爬蟲練習平臺,否則後果自負

 

 

這邊wireshark顯示:

 

 

 

 

此時你會看到很多的數據數據包,過濾一下,直接在過濾器位置輸入ip.,就會有很多指令提示和歷史記錄

 

全部的命令是啥意思這裏就不多說了,更多的可以百度,只介紹幾個這裏會用到的命令:

 

ip.dst_host就是目標地址,這裏你可以理解爲就是訪問網站的服務端地址

ip.src_host就是源地址,這裏你可以理解爲就是你正在操作的電腦的ip,這個ip大多是局域網ip

ip.host 跟上面一樣,但是不會區分是src還是dst,只要有指定地址的都會過濾出來

 

 

給定過濾指令,回車,此時有可能你輸入過濾命令之後,看不到有任何數據包,小問題,可能你打開wireshark完了,沒抓到包,重新刷新下網頁就行了,此時就看到如下的數據:

 

 

 注意看,最開始的5個數據包就是上面說的流程,前三個是三次握手,第四個開始到第6個就是ja3的hello數據包,個人感覺這段過程也很像三次握手,再後續的數據包就是實質的ssl數據交互了,

 

 

有了這個,看看ja3指紋到底是啥樣的,雙擊這個client hello,然後服務端返回的sever hello就不看了,此時不需要看,忘掉它吧

 

 展開client hello:

 

 

 

 

 

滑倒最後,就能看到ja3指紋了

 

 

然後,看JA3 Fullstring :

771,43690-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,64250-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-51914-21,51914-29-23-24,0

對應:

TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats

 

以【,】分割,第一個數,771,根據官方解釋,就是ssl/tls版本,也就是這個:

 

 python終端跑一下,0x0303就是771,對上了

, 

 

 

 

後續的就不細說了,直接看

 

 

 

 ja3圖1

 

 

細心的你發現了,我截圖這裏是沒有第四個數相關的套件, 但是ja自己的文章裏是有第四個數EllipticCurves相關的:

 

 

其實不是沒有的,是現在第四個參數由EllipticCurves改成了supported_groups

 

ja3圖2

注:ja3圖1是公司電腦,ja3圖2是家裏電腦,所以看着ja3字段有點不一樣,tls版本也不一樣

 

說到版本,糾正下我前一篇給的說明,ja3指紋不是一定在tls1.3上支持的,上面的截圖各位朋友應該也看得到,tls1.2也支持的,不過也確實是需要wireshark的最新版才能看到ja3指紋

有關第三個數Extensions擴展列表,感興趣的可以看看更詳細的解釋:https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml

所以,實際的案例作爲ja3概念解釋就到這裏了

 

 

如何突破ja3

 

終於到了大家都很感興趣的環節,怎麼破它了

 

python半突破

在上一篇的解決方案裏,修改cipher裏的加密算法即可,也就是TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats裏的【Ciphers】,

有關ciphers相關套接字的,可以看看openssl的官方解釋:https://www.openssl.org/docs/man1.1.1/man1/ciphers.html,並且華爲官網的waf介紹裏也有不同tls版本對應的套接字:

https://support.huaweicloud.com/bestpractice-waf/waf_06_0012.html

 

 

也就是說,我們要想改,可以直接複製上面的套件覆蓋下即可,例如:

 

urllib3.util.ssl_.DEFAULT_CIPHERS = 'EECDH+AESGCMEDH+AESGCM'

 

但是,相信對這個tls有過相關經驗的大佬來說,其實在調試requests請求時,調試到這個http/client.py文件庫裏時,就能看到,在開始connect 時 http版本直接寫死成了1.0,還有這個建立連接的tunnel_headers,代碼給了個空值

 

 

 

 

 

 

如果你再配上fiddler或者charles抓包看的時候,明顯能看到,在python發送實際請求前的CONNECT請求如下:

 

 

而瀏覽器的這個CONNECT請求是http1.1,且headers是有值的,如下:

 

 

所以,這很明顯的差異好嗎?是很容易被識別到的

 

而且根據我多方查閱,加上諮詢了各位大佬之後,python目前只能改Ciphers裏面的算法套件,來生成非默認的ja3指紋,然後可以騙過檢測不是太高的反爬機制。

但是其他的Extensions,EllipticCurves,EllipticCurvePointFormats是沒法改的,原因是  python跟openssl沒有很直接的聯繫,python發https請求最後還是藉助openssl庫暴露出來的方法,也就是前面提到的ssl創建context的ssl_create_context),因爲openssl庫對外提供的方法或者接口是沒辦法這麼高度自定義的,Ciphers部分也最多能改改算法,都不能給個自己定義的算法進去的,而chrome可以訪問是因爲chrome有自己的ssl,且chrome肯定是不會被禁止的(鬧呢,禁止了瀏覽器正常用戶怎麼訪問?)

也就是可以說這是python自身的缺陷了?所以,我之前測試時不管用requests,httpx,還是aiohttp都不行,因爲這三個庫底層都藉助了openssl庫發請求。

假如這種反爬手段滿天飛的時候,python層面還沒有成型的方案解決怎麼辦?

 

python的業務方向中引以爲傲的爬蟲居然有缺陷?而且這個問題非常致命啊,感覺被降維打擊了,傷心的是目前還沒法改變局面,你說焦慮不焦慮?

 

那有朋友估計會想問,“那爲啥之前猿人學19題可以過?” ,那是因爲19題檢測的不嚴,只要ja3指紋長度小於等於瀏覽器的指紋長度都可以過,但其實還有很多特徵的可以檢測到的,來,看圖,還是上次的圖,看最後一個數有很大區別的,這個我在上一篇的結尾裏也把這個問題拋出來了

 

 

這麼明顯的特徵,如果是一個實際的網站案例,你覺得他會放過你嗎?

 

說到這裏,有朋友可能不信,口說無憑,這次來個實際的案例,一個大佬給我的,由於他給我的囑咐,這個接口設計到了很多商業層面的問題,我就不能直接給接口地址了,你們也別問我了,看出來了的朋友也勞煩你不要說出去,自己知道就行了,主要是這個影響有點大,另外此時也沒找到一個合適的網站作爲案例舉證,所以得用一下子

 

瀏覽器打開(抱歉,我必須馬賽克馬到位),正常訪問是這樣的

 

 

 

 

python代碼,這裏我用之前介紹的簡寫形式了,只加這兩行,其他地方不用改就行的

 

 

 

 

眼尖的朋友應該看到cookies有_abck字段了,別激動,什麼axxai的,沒聽過,不知道哈,我真不知道,而且這裏的場景我也沒有涉及相關的對抗的哈。

 

運行時發現程序卡住且一直沒有響應的狀態,測試得知原因是這個網站強制驗證了http2.0的問題,requests暫不支持http2被該服務器識別一直不響應結果導致卡住。

 

那換成httpx,(有關httpx詳細的代碼如何突破ja3的,可以看我之前寫的這篇:python爬蟲- requests、httpx、aiohttp、scrapy突破ja3指紋識別 裏的httpx)

 

發現運行還是不行的。

 

 

怎麼改都不成功的,這個就是實際例子說明了,這是python語言層面的問題啊,難道python真的有缺陷?

 

golang 之ja3transport庫突破ja3

 

之後在蔡老闆朋友圈裏,青南大佬評論中說了是可以替換ja3指紋的,我請教青南大佬之後,他給了我一個方案,用golang突破,原文鏈接:一日一技:Golang 如何突破 JA3?

核心就是,代碼里加了第三方庫,ja3transport,這個庫可以直接僞造ja3,刺不刺激?

 

一執行,一看,就發現真的改變了ja3指紋,驚呆!激動!刺激!興奮!

 

大概的看了下ja3transport的介紹,它在發起請求的時候,會將請求的client hello數據包裏的ja3指紋修改爲我們自己的給定的,這樣就達到了修改 JA3指紋的目的,妙啊

 

ja3transport簡介

 

這個大佬給了一段解釋+谷歌翻譯:

JA3 的問題在於它僅比基於用戶代理字符串的指紋識別客戶端好一點。到目前爲止,用戶代理字符串比 TLS ClientHello 數據包更容易更改。JA3 簽名的參數仍由 TLS 客戶端控制,因此不能作爲可信的信息來源。在 Jeff 和 John 的 ShmooCon 談話中,他們提到 JA3 不是靈丹妙藥他們提出的顛覆 JA3 檢測的方法是使用操作系統的 HTTPS 客戶端繞過 TLS 客戶端特定的 JA3 簽名。我們提出了另一種通過製作與其他 TLS 客戶端(如瀏覽器)匹配的 ClientHello 數據包來破壞 JA3 檢測的方法

 

 

ja3transport突破原理

官方解釋+谷歌翻譯:

要想顛覆JA3,需要修改5個JA3參數,可以在Refraction Networking的utls項目ClientHelloSpec提供的struct中修改。該包允許用戶構建和執行 ClientHello 握手。第一個參數,TLS 版本,可以用和成員修改。第二個參數,可用密碼套件,可以通過更新成員來更改。第三個參數 TLS 擴展可以通過更新成員來更改。參數的一個問題是所有參數都必須遵循 TLSVersionMinTLSVersionMaxCipherSuitesExtensionsExtensionsTLSExtension界面。第四個和第五個參數,橢圓曲線和橢圓曲線點格式,分別是 TLS 擴展SupportedCurvesExtension和 的一部分SupportedPointsExtension


我們不是根據 JA3 字符串創建客戶端,而是可以生成與 Web 瀏覽器等良性簽名匹配的 JA3 簽名。有一些預設允許 JA3 簽名匹配 Chrome 或 Firefox,甚至更多。我們僅限於屏蔽使用 Go 可用的相同擴展的應用程序。例如,如果 Chrome 使用 Go 不支持的擴展程序,我們無法屏蔽它。屏蔽密碼套件比較棘手,因爲任何密碼套件都可以進行廣告,即使它沒有實現。如果執行握手的服務器接受客戶端通告但實際上並不支持的密碼套件,則會出現問題。只要服務器接受實際支持的密碼套件,虛假宣傳比可用密碼套件多的密碼套件就不是問題

 

Go 的net/http庫有一個名爲Transport. 傳輸結構負責編寫如何將數據包發送到目標服務器。由於 JA3 的簽名是基於 ClientHello 數據包的,我們可以進行 TLS 握手,讓 Go 完成剩下的工作。該Transport對象是一個參數http.Client結構其中大部分進入開發人員都很熟悉。通過生成Transport結構體,我們的庫應該可以與任何現有的 Go 項目無縫協作

 

濃縮下梗概,意思就是在go構建請求,三次握手之後,到實際要發起client hello包之前,ja3transport把數據包攔截了,然後把原來的ja3指紋修改成了自傳遞的ja3字段發出client hello,服務端就認了,然後就通過了。

 

太牛逼了,他不是直接修改的tls裏的那五個數組套件,因爲ja3transport作者自己也說了,要想突破ja3,他認爲的方法和選擇的方法也是避開了直接改5個JA3參數,而是在5個JA3參數創建好之後進行攔截替換

 

那麼也就是說,其實golang跟python比也並沒有在語言上佔有很大優勢,唯一就是golang多了這麼一羣人提前就研究並寫好了這個第三方庫,而python沒法解決只是還沒有人寫出能夠攔截數據包並替換ja3指紋的庫,也就是這個並不是python的缺陷啊。當然,如果你急於求得結果,我建議你還是學一下golang來解決問題。

 

 

更多的解釋請看原文:https://medium.com/cu-cyber/impersonating-ja3-fingerprints-b9f555880e42

 

 

ja3transport後續問題

 

作者也說了,如果你隨意地僞造ja3,假如服務端通過一些方式得知你客戶端訪問進程跟實際的ja3不匹配,那應該也會屏蔽你

我們能想到的最簡單的檢測改進是將 JA3 簽名與生成 TLS ClientHello 數據包的進程映像配對。如果有客戶端生成與 Firefox 匹配的 JA3 簽名,但該進程不是 Firefox,則可能會發生一些奇怪的事情

 

ja3transport缺陷

 

但是,用這個庫ja3transport執行的剛纔那個案例網站的時候發現報瞭如下錯,提示就是說這個服務器不支持版本304的協議

 

tls: server selected unsupported protocol version 304

 

 

一搜這個報錯,就看到有個大佬說是因爲不支持http2.0導致的:

 

對啊,這個網站上面它強制http2了,那也就是說,ja3transport不支持http2.0,這就是他的缺陷啊

 

golang之CycleTLS庫http2.0+ja3指紋完美突破

 

那隻要能解決http2這個問題,是不是就破了這個站呢?再看上面這個大佬發的日期:

 

 

 

7 May,那現在已經過去這麼久了,大膽猜測一下,是不是這個大佬已經解決了呢?此時估計有朋友應該回想,“你這個人怎麼這麼不嚴謹,什麼都靠猜嗎?上一篇解決猿人學19題刪一大片cipher加密算法解決問題也是猜的”

 

哈哈哈,是啊,因爲我個人覺得,爬蟲跟前後端開發還是有點區別的,前後端開發,按照我的理解,講究的邏輯嚴密,事先考慮各個層面的問題,儘量少bug然後服務能夠長期穩定運行,但是爬蟲的話,有時候沒思路的情況下真的是大膽猜測出來的,我現在的思維已經轉向這個方面了,雖然以前也幹過後端開發,但是思維已經回不去了。

 

 

我開始嘗試了這個庫:git地址:https://github.com/Danny-Dasilva/CycleTLS,真的就是抱着試一試的心態,執行,結果真的跟瀏覽器訪問一樣的,搞定,牛逼!

 

 

 

 

所以,也就是說,之前用的庫github.com/CUCyber/ja3transport,不夠適合當下場景 http2+ja3雙重驗證

 

 

go代碼:

 

package main

import (
	"github.com/Danny-Dasilva/CycleTLS/cycletls"
	"log"
)

func main() {

	client := cycletls.Init()

	response, err := client.Do("(保密)", cycletls.Options{
		Body : "",
		Ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0",
		UserAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 Edg/92.0.902.67",
	}, "GET");
	if err != nil {
		log.Print("Request Failed: " + err.Error())
	}
	log.Println(response)
}

  

 

是不是感覺代碼量也少很多

 

 

nodejs

 

還是用上面大佬Danny-Dasilva的CycleTLS庫即可,他也開發了node的庫:https://github.com/Danny-Dasilva/CycleTLS#example-cycletls-request-jsts

 

直接npm install cycletls,然後照着案例的代碼來就行了,可能對於大部分爬蟲開發來說,node相對golang來說會更熟悉一點的,

const initCycleTLS = require('cycletls');
// Typescript: import initCycleTLS from 'cycletls';

(async () => {
  // Initiate CycleTLS
  const cycleTLS = await initCycleTLS();

  // Send request
  const response = await cycleTLS('https://ja3er.com/json', {
    body: '',
    ja3: '771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0',
    userAgent: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0',
    proxy: 'http://username:[email protected]:443'
  }, 'get');

  console.log(response);

  // Cleanly exit CycleTLS
  cycleTLS.exit();

})();

 

驗證python指紋

既然已經可以隨意改了對吧,那我改成python默認的指紋訪問下這個網站看看呢?我下面只改了ja3指紋,看運行結果,果然是被拉黑了,哈哈哈哈

 

 

 

換接口驗證

 

爲了驗證真的成功了,哈哈,該嚴謹的地方確實得嚴謹一點,還是用的golang,我換了另一個接口地址執行,確實有結果了。

 

 

用wireshark做最後的驗證

 

那邊go程序在執行,還是這個被馬死的目標,這邊wireshark抓包看結果,是的,相信你也看出貓膩了,它居然發了兩次client hello包

 

 

 

而之前我們看到的,比如猿人學的那個,實際只會發一次的,這裏發兩次就很奇怪,然後,這兩次發出去的ja3指紋還不一樣:

 

 

 

哪裏不一樣,以逗號作爲分割,除了第一個數和最後一個數,其他的字段的開頭一個數組都不一樣(以【-】作爲分割)

 

 

然後,此時此刻,我們先去ja3官網看看瀏覽器本來的指紋呢?

 

 

chrome訪問ja3官網返回得到的:
    771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0

chrome訪問目標網站用wireshark抓包得到:

  第一個:
    771,43690-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,60138-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-51914-41,14906-29-23-24,0

  第二個:
    771,10794-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,14906-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-2570-21,60138-29-23-24,0

 

仔細對比之後,也就剛好多了標記的


 

去掉上面標記出來的,其實第一個和第二個是一樣的,僅僅是這個被我馬賽克馬死的平臺是這樣,我猜應該是這個平臺自己多加了一層握手流程,所以會有2個client hello,具體爲啥有兩個不糾結了,我也不是該平臺的開發,也沒法得知具體原因,不重要了,能獲取數據就行了。

 

不過等等,突然有個疑問?爲啥wireshark的ja3指紋,同一個golang腳本啊,就算兩個client hello,也應該是兩個一樣的ja3指紋啊,爲了進一步分析,先用瀏覽器訪問ja3後,同時看看wireshark抓包的是啥,這?我該信哪個?怎麼wireshark多了點其他的東西

 

 

 

 

這引出了一個新的問題,哪個纔是對的

 

ja3到底存在嗎? 

 

按理來說,應該信ja3官方,因爲這玩意兒就是別人搞出來的,那既然如此,是wireshark在搞事咯?(此時此刻突然想起了學生時代的一個數學邏輯題,假如你是偵探,現在有幾個嫌疑人,已知裏面有個人說了謊,從幾個嫌疑人的供詞裏找出真兇。。。扯遠了)

 

爲了進一步確認這個問題,根據青南大佬給文章的方案,可以僞造ja3指紋,那此時此刻,試下吧,現在的邏輯就是,我用一個我已知的指紋去請求ja3,然後看看ja3官方的返回,再看wireshark的ja3指紋對比,如果wireshark裏的ja3不全等於我們自定義的ja3,那就確認是wireshark在他喵的搞事了

 

 

首先澄清,沒作弊哈,我用的第一個,跟我瀏覽器裏的ja3是不一樣的

 

 

 

這裏我用的ja3transport庫了,因爲ja3官網沒有強制HTTP2了,運行下面的代碼,發現返回的確實改變了的,且值正是我們給定的

 

 

 

再看wireshark這邊:

 

 

發現也是自定義的那個值,沒有奇怪的數組了

 

 

相信有朋友會問,這就奇怪了,爲啥這裏又一樣了?難道wireshark沒有騙我們?啊這。。。,不是吧,忘了嗎?ja3transport這個庫會在在三次握手後,即將發起client hello數據包時,攔截這個包,然後把自定義的ja3指紋替換原有的啊,這是ja3transport庫的原理,所以,這裏wireshark能跟我們給定的ja3指紋對應上

 

 

那麼,也就是說,wireshark有一套的自己的ja3指紋解析套件解析並顯示了,但是這個解析套件跟ja3官網是不一樣的,所以顯示不一樣。當然這是我經過多次分析推理得出來的結論,查了wireshark的文檔,暫時沒找到相關的介紹和解釋,姑且這麼理解吧,肯定信ja3官方不能信wireshark啊,畢竟這ja3是別人搞出來的。

 

而且仔細看下面這個圖,我鼠標放到ja3上面的時候,下面的進制數據並不會對應顯示

 

 

 

用微信好友chao的話,"所有真實的信息都有二進制的數據,而wireshark的ja3都沒有對應的二進制數據"

 

所以我跟chao討論之後,認爲ja3其實並不存在(上一次這麼醍醐灌頂還是讀到《三體》裏的那句臺詞"物理學不存在",不好意思又扯遠了。。。),或者說ja3並不是實質性存在的字符,而是通過TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats這五個tls組件根據自己的加密算法另類存在的,因爲wireshark都能通過自己的解析邏輯解析顯示啊。以上推論僅代表個人觀點,有誤請指正

 

 

需要注意的點

1.有沒有發現,其實ja3在2017年就有了,爲啥國內到現在這麼久了,而之前不是有句話,國內的互聯網行情領先國外幾十年,因爲國內各種安全防護,安全盾之類的確實太前沿,而國外這方面的防護很少,就cloudflare,akamai等的雲防護,以及谷歌的行爲檢測,能數下來的就幾個,但是國內相關的安全防禦手段就太多了。

在我查閱ja3相關的問題時,發現國外好多開發者在2018,2019年就有人在問怎麼修改ja3指紋了,那爲啥這個ja3指紋沒有大規模用到呢?很奇怪,之前在蔡老闆的知識星球裏跟某大佬也有過簡單的探討,表示了國內對於的ja3爲啥國內沒普及的看法,我倒是覺得很可能在明年會有大批普及的,但它確實也有自己的問題,確實會導致訪問速度稍微的變慢一點點(對於不用太在意秒級響應的來說其實可以忽略不計),犧牲零點幾秒到一兩秒的響應時間就能阻擋一大片爬蟲,我覺得是值得的,國內開發大佬這麼多,肯定可以優化時間這個問題的。

 

2.有了一個ja3,那我覺得後續肯定會出現升級版或者替代版了,紅藍對抗,反爬與反反爬,一直在對抗中進步,是好是壞,只能用時間來判定了。而且其實這個ja3有關的方法和介紹,我完全可以自己搞懂憋着不說,用來作爲自己的絕技的,但是我個人是一個樂於分享的人,我覺得一些值得記錄的東西就應該記錄下來或者公開出來,很多新東西靠自己一個人摸索是沒法走到更遠的,好比這個ja3,如果一開始沒有Lee Brotherston大佬在2015公開講解,也就不會有這麼牛逼的ja3指紋出現了,好東西確實是要留着自己用,不過哪些東西可以分享那些東西可以保留我還是有分寸的。很喜歡微信好友Regionover在一篇文章裏的一句話:【故事要留給過去,但成長要用於分享

3.另外,希望國內外能有大神可以仿照這個ja3transport庫或者CycleTLS庫寫一個python的庫出來,唉,我自己也想寫出來啊,在寫這篇文章的時期,我也在看原理,對於在這之前對golang僅限於字面上瞭解的我來說,真的有點喫力,要寫個python庫出來,還是需要花很多時間研究的。

 

 

結語

1.這次的解析個人覺得終於算是深入理解ja3了

2.以上都是個人見解,如果有誤還望指正,有任何問題,我很樂意跟各位大佬們交流,我微信id:geekbyte

3.最近通過蔡老闆的羣,認識了很多大佬,學到很多技術,受益匪淺。蔡老闆的羣大佬太多了,各種大廠的人,多到簡直舔不過來,如果你也想進羣,可以加蔡老闆的星球,沒錯就是文章開頭提到那個有着無處安放的魅力的男人 :

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章