為什麼我抓不到baidu的資料包
最近,有位讀者問起一個奇怪的事情,他說他想抓一個baidu.com
的資料包,體驗下看包的樂趣。
但卻發現“抓不到”,這就有些奇怪了。
我來還原下他的操作步驟。
首先,透過ping
命令,獲得訪問百度時會請求哪個IP。
$ ping baidu.com
PING baidu.com (39.156.66.10) 56(84) bytes of data.
64 bytes from 39.156.66.10 (39.156.66.10): icmp_seq=1 ttl=49 time=30.6 ms
64 bytes from 39.156.66.10 (39.156.66.10): icmp_seq=2 ttl=49 time=30.6 ms
64 bytes from 39.156.66.10 (39.156.66.10): icmp_seq=3 ttl=49 time=30.6 ms
從上面的結果可以知道請求baidu.com
時會去訪問39.156.66.10
。
於是用下面的tcpdump
命令進行抓包,大概的意思是抓eth0
網路卡且ip
為39.156.66.10
的網路包,儲存到baidu.pcap
檔案中。
$ tcpdump -i eth0 host 39.156.66.10 -w baidu.pcap
此時在瀏覽器中開啟baidu.com
網頁。或者在另外一個命令列視窗,直接用curl
命令來模擬下。
$ curl '
按理說,訪問baidu.com的資料包肯定已經抓下來了。
然後停止抓包。
再用wireshark
開啟baidu.pcap
檔案,在過濾那一欄裡輸入http.host == "baidu.com"
。
此時發現,一無所獲。
這是為啥?
到這裡,有經驗的小夥伴,其實已經知道問題出在哪裡了。
為什麼沒能抓到包
這其實是因為他訪問的是HTTPS協議的baidu.com。HTTP協議裡的Host和實際傳送的request body都會被加密。
正因為被加密了,所以沒辦法透過http.host
進行過濾。
但是。
雖然加密了,如果想篩選還是可以篩的。
HTTPS握手中的Client Hello階段,裡面有個擴充套件server_name
,會記錄你想訪問的是哪個網站,透過下面的篩選條件可以將它過濾出來。
tls.handshake.extensions_server_name == "baidu.com"
此時選中其中一個包,點選右鍵,選中Follow-TCP Stream
。
這個TCP連線的其他相關報文全都能被展示出來。
從截圖可以看出,這裡面完整經歷了TCP握手和TLS加密握手流程,之後就是兩段加密資訊和TCP揮手流程。
可以看出18號和20號包,一個是從埠56028發到443,一個是443到56028的回包。
一般來說,像56028
這種比較大且沒啥規律的數字,都是客戶端隨機生成的埠號。
而443
,則是HTTPS的伺服器埠號。
HTTP用的是80埠,如果此時對著80埠抓包,也會抓不到資料。
粗略判斷,18號和20號包分別是客戶端請求baidu.com
的請求包和響應包。
點進去看會發現URL和body都被加密了,一無所獲。
那麼問題就來了。有沒有辦法解密裡面的資料呢?
有辦法。我們來看下怎麼做。
解密資料包
還是先執行tcpdump抓包
$ tcpdump -i eth0 host 39.156.66.10 -w baidu.pcap
然後在另外一個命令列視窗下執行下面的命令,目的是將加密的key匯出,並給出對應的匯出地址是/Users/xiaobaidebug/ssl.key
。
$ export SSLKEYLOGFILE=/Users/xiaobaidebug/ssl.key
然後在同一個命令列視窗下,繼續執行curl命令或用命令列開啟chrome瀏覽器。目的是為了讓curl或chrome繼承這個環境變數。
$ curl '
或者
$ open -a Google\ Chrome #在mac裡開啟chrome瀏覽器
此時會看到在/Users/xiaobaidebug/
下會多了一個ssl.key
檔案。
這時候跟著下面的操作修改wireshark
的配置項。
找到Protocols之後,使勁往下翻,找到TLS
那一項。
將匯出的ssl.key
檔案路徑輸入到這裡頭。
點選確定後,就能看到18號和20號資料包已經被解密。
此時再用http.host == "baidu.com"
,就能過濾出資料了。
到這裡,其實看不了資料包的問題就解決了。
但是,新的問題又來了。
ssl.key檔案是個啥?
這就要從HTTPS的加密原理說起了。
HTTPS握手過程
HTTPS的握手過程比較繁瑣,我們來回顧下。
先是建立TCP連線,畢竟HTTP是基於TCP的應用層協議。
在TCP成功建立完協議後,就可以開始進入HTTPS階段。
HTTPS可以用TLS或者SSL啥的進行加密,下面我們以TLS1.2
為例。
總的來說。整個加密流程其實分為兩階段。
第一階段是TLS四次握手,這一階段主要是利用非對稱加密的特性各種交換資訊,最後得到一個"會話秘鑰"。
第二階段是則是在第一階段的"會話秘鑰"基礎上,進行對稱加密通訊。
我們先來看下第一階段的TLS四次握手是怎麼樣的。
第一次握手:
•
Client Hello
:是客戶端告訴服務端,它支援什麼樣的加密協議版本,比如TLS1.2
,使用什麼樣的加密套件,比如最常見的RSA
,同時還給出一個客戶端隨機數。
第二次握手:
•
Server Hello
:服務端告訴客戶端,伺服器隨機數 + 伺服器證書 + 確定的加密協議版本(比如就是TLS1.2)。
第三次握手:
•
Client Key Exchange
: 此時客戶端再生成一個隨機數,叫pre_master_key
。從第二次握手的伺服器證書裡取出伺服器公鑰,用公鑰加密pre_master_key
,發給伺服器。•
Change Cipher Spec
: 客戶端這邊已經擁有三個隨機數:客戶端隨機數,伺服器隨機數和pre_master_key,用這三個隨機數進行計算得到一個"會話秘鑰"。此時客戶端通知服務端,後面會用這個會話秘鑰進行對稱機密通訊。•
Encrypted Handshake Message
:客戶端會把迄今為止的通訊資料內容生成一個摘要,用"會話秘鑰"加密一下,發給伺服器做校驗,此時客戶端這邊的握手流程就結束了,因此也叫Finished報文。
第四次握手:
•
Change Cipher Spec
:服務端此時拿到客戶端傳來的pre_master_key
(雖然被伺服器公鑰加密過,但伺服器有私鑰,能解密獲得原文),集齊三個隨機數,跟客戶端一樣,用這三個隨機數透過同樣的演算法獲得一個"會話秘鑰"。此時伺服器告訴客戶端,後面會用這個"會話秘鑰"進行加密通訊。•
Encrypted Handshake Message
:跟客戶端的操作一樣,將迄今為止的通訊資料內容生成一個摘要,用"會話秘鑰"加密一下,發給客戶端做校驗,到這裡,服務端的握手流程也結束了,因此這也叫Finished報文。
四次握手中,客戶端和服務端最後都擁有三個隨機數,他們很關鍵,我特地加粗了表示。
第一次握手,產生的客戶端隨機數,叫client random
。
第二次握手時,伺服器也會產生一個伺服器隨機數,叫server random
。
第三次握手時,客戶端還會產生一個隨機數,叫pre_master_key
。
這三個隨機數共同構成最終的對稱加密秘鑰,也就是上面提到的"會話秘鑰"。
你可以簡單的認為,只要知道這三個隨機數,你就能破解HTTPS通訊。
而這三個隨機數中,client random
和 server random
都是明文的,誰都能知道。而pre_master_key
卻不行,它被伺服器的公鑰加密過,只有客戶端自己,和擁有對應伺服器私鑰的人能知道。
所以問題就變成了,怎麼才能得到這個pre_master_key
?
怎麼得到pre_master_key
伺服器私鑰不是誰都能拿到的,所以問題就變成了,有沒有辦法從客戶端那拿到這個pre_master_key
。
有的。
客戶端在使用HTTPS與服務端進行資料傳輸時,是需要先基於TCP建立HTTP連線,然後再呼叫客戶端側的TLS庫(OpenSSL、NSS)。觸發TLS四次握手。
這時候如果加入環境變數SSLKEYLOGFILE就可以干預TLS庫的行為,讓它輸出一份含有pre_master_key
的檔案。這個檔案就是我們上面提到的/Users/xiaobaidebug/ssl.key
。
但是,雖然TLS庫支援匯出key檔案。但前提也是,上層的應用程式在呼叫TLS庫的時候,支援透過SSLKEYLOGFILE
環境觸發TLS庫匯出檔案。實際上,也並不是所有應用程式都支援將SSLKEYLOGFILE。只是目前常見的curl和chrome瀏覽器都是支援的。
SSLKEYLOGFILE檔案內容
再回過頭來看ssl.key
檔案裡的內容。
# SSL/TLS secrets log file, generated by NSS
CLIENT_RANDOM 5709aef8ba36a8eeac72bd6f970a74f7533172c52be41b200ca9b91354bd662b 09d156a5e6c0d246549f6265e73bda72f0d6ee81032eaaa0bac9bea362090800174e0effc93b93c2ffa50cd8a715b0f0
CLIENT_RANDOM 57d269386549a4cec7f91158d85ca1376a060ef5a6c2ace04658fe88aec48776 48c16429d362bea157719da5641e2f3f13b0b3fee2695ef2b7cdc71c61958d22414e599c676ca96bbdb30eca49eb488a
CLIENT_RANDOM 5fca0f2835cbb5e248d7b3e75180b2b3aff000929e33e5bacf5f5a4bff63bbe5 424e1fcfff35e76d5bf88f21d6c361ee7a9d32cb8f2c60649135fd9b66d569d8c4add6c9d521e148c63977b7a95e8fe8
CLIENT_RANDOM be610cb1053e6f3a01aa3b88bc9e8c77a708ae4b0f953b2063ca5f925d673140 c26e3cf83513a830af3d3401241e1bc4fdda187f98ad5ef9e14cae71b0ddec85812a81d793d6ec934b9dcdefa84bdcf3
這裡有三列。
第一列是CLIENT_RANDOM,意思是接下來的第二列就是客戶端隨機數,再接下來的第三列則是pre_master_key
。
但是問題又來了。
這麼多行,wireshark怎麼知道用哪行的pre_master_key呢?
wireshark
是可以獲得資料包文上的client random
的。
比如下圖這樣。
注意上面的客戶端隨機數是以 "bff63bbe5"
結尾的。
同樣,還能在資料包文裡拿到server random。
此時將client random
放到ssl.key的第二列裡挨個去做匹配。
就能找到對應的那一行記錄。
注意第二列的那串字串,也是以 "bff63bbe5"
結尾的,它其實就是前面提到的client random
。
再取出這一行的第三列資料,就是我們想要的pre_master_key
。
那麼這時候wireshark
就集齊了三個隨機數,此時就可以計算得到會話秘鑰,透過它對資料進行解密了。
反過來,正因為需要客戶端隨機數,才能定位到ssl.key
檔案裡對應的pre_master_key
是哪一個。而只有TLS第一次握手(client hello
)的時候才會有這個隨機數,所以如果你想用解密HTTPS包,就必須將TLS四次握手能抓齊,才能進行解密。如果連線早已經建立了,資料都來回傳好半天了,這時候你再去抓包,是沒辦法解密的。
總結
• 文章開頭透過抓包baidu的資料包,展示了用wireshark抓包的簡單操作流程。
• HTTPS會對HTTP的URL和Request Body都進行加密,因此直接在
filter欄
進行過濾http.host == "baidu.com"
會一無所獲。• HTTPS握手的過程中會先透過非對稱機密去交換各種資訊,其中就包括3個隨機數,再透過這三個隨機數去生成對稱機密的會話秘鑰,後續使用這個會話秘鑰去進行對稱加密通訊。如果能獲得這三個隨機數就能解密HTTPS的加密資料包。
• 三個隨機數,分別是客戶端隨機數(client random),服務端隨機數(server random)以及pre_master_key。前兩個,是明文,第三個是被伺服器公鑰加密過的,在客戶端側需要透過SSLKEYLOGFILE去匯出。
• 透過設定SSLKEYLOGFILE環境變數,再讓curl或chrome會請求HTTPS域名,會讓它們在呼叫TLS庫的同時匯出對應的sslkey檔案。這個檔案裡包含了三列,其中最重要的是第二列的client random資訊以及第三列的pre_master_key。第二列client random用於定位,第三列pre_master_key用於解密。
參考資料
極客時間 -《網路排查案例課》
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2929636/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 我就想學介面測試,為什麼還要學 Fiddler 抓包,抓包是什麼鬼?
- 手機通過 fiddler 抓包,有些請求為什麼就得不到返回資料了
- 為什麼用抓包工具看HTTPS包是明文的HTTP
- 在 ios 手機上用 charles 抓包,抓取不到 wss 資料。iOS
- charles 用電腦分享 wifi 為什麼抓不了包?WiFi
- 為什麼抓包檔案有好幾種型別?型別
- 抓包概念大比較:資料包、資料包、分組
- 解釋下為什麼抓包 https 需要安裝證書HTTP
- 為什麼我的 PHP 資料庫連線失敗?PHP資料庫
- 為什麼我們需要資料庫事務資料庫
- 資料包遠端傳輸的抓包系統scratch
- yaml 檔案裡的中文,以 json 格式請求抓包為什麼是 unicodeYAMLJSONUnicode
- 零基礎學習大資料為什麼找不到工作?大資料
- HTTP協議的請求與資料抓包HTTP協議
- 前端攻城獅必會資料抓包前端
- 使用tcpdump+wireshark抓包分析網路資料包TCP
- 老闆今天問我為什麼公司的資料庫這麼爛,我是這樣回答的......資料庫
- 大資料能做什麼,為什麼學大資料大資料
- NMAP為什麼掃描不到埠
- Fiddler抓包和修改WebSocket資料,支援wssWeb
- 我們為什麼要遠離資料庫生成的ID?- Tugberk Ugurlu資料庫
- 為什麼我害怕資料結構學得好的程式設計師?資料結構程式設計師
- 資料庫管理-第121期 我為什麼寫文章(202301203)資料庫
- 我為什麼要做IT
- 按下www.baidu.com發生什麼AI
- Python 爬取 baidu 股票市值資料PythonAI
- 閉包是什麼?怎麼形成一個閉包?為什麼使用閉包?
- Debookee 8.1.2 網路資料抓包及分析工具
- 戈小羊:為什麼我們都是大資料時代的“統計文盲”?大資料
- paluch.biz - Lombok的資料類是有害的!為什麼我不再使用Lombok?Lombok
- 為什麼軟體工程師找不到工作?我想分享四個“恐怖故事”軟體工程工程師
- 為什麼需要資料治理
- 資料治理為什麼要清洗資料
- 抓包Http/Https/Other資料包(小迪網路安全筆記~HTTP筆記
- 我的ECS為什麼“卡卡”的
- 資料出境是什麼意思?我國資料出境合規要求是什麼?
- 我為什麼使用 JavaJava
- Charles抓包—App資源代理APP