這篇是跟我精進爬蟲技術的小夥伴的實操總結文投稿,一篇標準的安卓7抓包指南。
因為App對裝置限制的原因,換了一臺 Android 7 的測試機,在這期間又遇上了幾種棘手的檢測與驗證。感覺採用防抓包技術的廠商越發多了起來。解決完這些問題,寫一篇日誌來記錄一下,作為日後排查手冊。
系統校驗證照
Android 7.0 之後,預設情況下 app 只信任系統級別的 CA 。從 chls.pro/ssl 安裝的證照是在使用者級,這導致了 Charles 無法攔截應用流量。有兩種方法可以繞過:
(一)將 Charles CA 安裝為系統級 CA ,需要修改 /system 許可權,全域性 APP 生效,需 Root
(二)修改 APP 包 Androidmanifest 檔案並重打包,僅針對單一APP生效,無需 root
第一種操作,基於 ADB shell 安裝證照,需要 Root :
# 1.從Charles取出證照
charles-proxy-ssl-proxying-certificate.pem
# 2.獲取證照hash,並修改證照檔名為hash+字尾''.0'' 。本例為fc0dd2c8.0
iMac:~ imac$ openssl x509 -in ./charles-proxy-ssl-proxying-certificate.pem -noout -subject_hash
# 執行結果:fc0dd2c8
# 3.連線測試機,adb shell 修改 /system許可權,
adb push fc0dd2c8.0 證照到 /system/etc/security/cacerts/
mount -o rw,remount /system
# 4.修改證照許可權為664,重啟裝置
cd /system/etc/security/cacerts/
chmod 664 ./fc0dd2c8.0
reboot
第二種操作,基於修改 Manifest 重新打包 APK,免Root :
原理是當 platformBuildVersionCode>=24 時候,App 就只信任系統級別的CA。修改 apk 中的AndroidManifest 強行降底執行環境的 API Level ,雖然麻煩,但這種方案的存在意義是,目標APP 有裝置 Root 檢測時適用。
執行 Apktool 反解,Android Studio 開啟 AndroidManifest.xml ,目標 API 級別會在檔案的 “manifest” 元素的 “platformBuildVersionCode” 屬性中指定。將 platformBuildVersionCode=26改成 23 ,使用 apktool 重新打包簽名安裝,就可以正常抓包了。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" \
android:versionCode="55" android:versionName="8.3" platformBuildVersionName="8.0.0" \
platformBuildVersionCode="26" package="com.test.test001">
流程:
apktool反解
修改AndroidManifest.xml
apktool 打包
keytool 生成證照
jarsigner apk簽名
如果有簽名校驗,jadx分析修改smali繞過
APP校驗證照
(一)App單向驗證APP 內建校驗證照,即廠商將證照檔案或證照值內建在 APK 安裝包內,通訊請求時 app 自身通過程式碼來校驗證照和伺服器的關係,即 SSL Pinning 。有2種解決方案:
1.逆向 App 取出證照,匯入到抓包程式中
證照通常在 /assets 裡
jadx 反編譯後搜尋 .p12 .pem .cer ssl 等關鍵詞
Hook 監聽證照讀取位置
——-例項暫略,有空另起一篇專門寫扣證照——-
2. Hook 繞過證照的校驗邏輯
JustTrustMe(Root+Xposed)
DroidSSLUnpinning(Root/免Root+Frida)
JustTrustMe 在測試過程中並不順利,首先安裝時需要依賴 Xposed 框架,如果目標採用xposed 檢測,會引發新的問題。並且 JustTrustMe 在某些 App 的新版本已失效,只能分析舊版本 app 或等待作者更新。用法簡單,安裝後 xposed 勾選啟動,重啟手機。
# xposed-->
https://repo.xposed.info/module/de.robv.android.xposed.installer
# JustTrustMe-->
https://github.com/Fuzion24/JustTrustMe/releases/tag/v.2
# TrustMePlus(魔改)-->
https://github.com/langgithub/JustTrustMePlus
DroidSSLUnpinning 在 Root 和非 Root 環境下都可以工作,Root 環境下操作更方便一些:
確認本地環境已安裝 frida&frida-tools
確認測試機 cpu 架構,https://github.com/frida/frida/releases 下載對應的frida-server–>
adb shell
getprop ro.product.cpu.abi
#執行結果
arm64-v8a
部署到手機並執行–>
adb push ./frida-server-12.8.20-android-arm64 /data/local/tmp/
cd /data/local/tmp
chmod 777 frida-server-12.8.20-android-arm64
./frida-server-12.8.20-android-arm64
tcp 轉發,用於與 frida-server 通訊,之後的每個埠對應每個注入的程式
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
本地 DroidDrops 目錄下執行
frida -U com.zhiliaoapp.musically --no-pause -l hooks.js
啟動 App,charles 抓包恢復正常。
(二)App雙向驗證APP 雙向校驗,即伺服器要認證請求淶源是否真實客戶端(來自真實證照),大概原理這樣:
app –>服務端(證照)—- ok
app(證照)<–服務端—- ok
解決兩個技術點:
APP 以為 Charles 是服務端( Hook 繞過)
服務端以為 Charles 是客戶端 (逆向 APP ,獲得證照匯入到 charles )
非常見證照校驗技術的通殺解決方案
ssl_logger 的作用原理是 hook 底層 ssl_read 和 ssl_write 兩個方法,完全不用配置代理,不用理解 APP 客戶端和服務端的證照校驗問題。
大黑闊5alt釋出過一個魔改版本,精品中的精品。
https://github.com/5alt/ssl_logger
我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。
***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***