基於Charles抓HTTPS包流程

1、問題描述

如果客戶端中添加了證書白名單,此時使用Https進行網絡通信,使用charles就會出現Connect錯誤,導致無法抓包。錯誤圖示如下。
HTTPS抓包Connect錯誤圖
本文通過增加客戶端中資源文件中內置的證書白名單的方式實現了對這種情況的抓包。
注意:由於客戶端的內置證書路徑不一定能找到,並且找到之後也不一定是明文或者格式也不一定能正確分析,所以這個方案的通用性存在問題,請謹慎參考。
本文會先分析Charles的抓包原理,然後從原理中嘗試解決方案,最後對結果進行展示。

2、Charles抓包原理

2.1 HTTP通信抓包原理

如果客戶端和服務器使用HTTP進行通信,由於請求和應答數據本身沒有加密,所以請求和應答能夠直接在Charles中展現。

2.2 HTTPS通信抓包原理

如果客戶端和服務器使用HTTPS進行通信,HTTPS的請求和應答內容經過了加密,所以Charles需要對請求和應答內容進行相應的處理才能正確展現相關內容。Charles的做法就是對客戶端把自己僞裝成“服務器”,對服務端把自己僞裝成“客戶端”。
交互流程如下:
1、Charles攔截客戶端的請求,僞裝成客戶端向服務器443端口發送證書請求;
2、服務器向“客戶端”(實際上是Charles)返回服務器的CA證書(證書中包含公鑰);
3、Charles攔截服務器的響應,獲取服務器證書公鑰,然後自己製作一張證書,將服務器證書替換後發送給客戶端;(Charles此時獲取了服務器證書的公鑰)
4、客戶端接收到“服務器”(實際上是Charles)的證書後,生成一個對稱密鑰,用Charles的公鑰加密,發送給“服務器”(Charles);
5、Charles攔截客戶端的響應,用自己的私鑰解密對稱密鑰,然後用服務器證書公鑰加密,發送給服務器;(Charles此時獲取了對稱密鑰)
6、服務器用自己的私鑰解密對稱密鑰,向“客戶端”(Charles)發送響應;
7、Charles攔截服務器的響應,替換成自己的內容後發送給客戶端;

其中有兩個需要注意的點:
1、如果用戶不選擇信任安裝Charles的CA證書,Charles也無法獲取請求內容;(所以抓包過程中需要安裝Charles的證書)
2、如果客戶端內置了自身的CA證書或者證書白名單,此時如果Charles把自己的證書發送給客戶端,客戶端會發現與客戶端內的證書不一致,會出現上圖中的Connect錯誤,導致Charles無法獲取信息的;(本文主要解決這個問題)

3、解決方案

對客戶端進行解包和重新打包,詳細流程見自己2015年寫的的一篇博客(https://blog.csdn.net/liushaofang/article/details/50381902),由於當時使用apktool的版本比較老,導致部分資源會解析失敗,所以在新的資源中將apktool更新爲2.3.4版本,目前能夠正常自己分析的一個apk,對應的資源鏈接爲(https://download.csdn.net/download/liushaofang/12473744
主要注意的點是解包命令和打包命令需要進行更新(需要用-p命令指定framepath,需要加上-r命令,命令含義可以參考apktool的help document),簽名命令保持不變。

3.1 解包

java -jar apktool.jar d -r -o targetdir -p framepath -f target.apk

3.2 增加證書白名單(重點)

此時需要分析客戶端的結構,找到內置證書的白名單,並將Charles分發給客戶端的證書添加到客戶端中,這一步不具備通用性,需要依據實際情況進行分析,有一條值得借鑑的經驗就是從res資源目錄中去找。

3.3 重新打包

java -jar apktool.jar b -o updatetarget.apk -p framepath targetdir

3.4 簽名

此步驟和以前一致,需要在Auto-sign目錄中執行

java -jar signapk.jar testkey.x509.pem testkey.pk8 updatetarget.apk updatetarget-signed.apk

4、結論

重新使用Charles抓包,能夠正常抓取所有的通信數據包。

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