移動端爬蟲工具與方法介紹
本文來自網易雲社群
作者:王濤
本文主要介紹了移動端爬蟲的工具與方法,作為一個入門的大綱。沒有詳細介紹的也給出了本人學習過程中借鑑的資料的連結,適合對移動端爬蟲感興趣的同學入門。
一、抓包模擬
基本原理(中間人攻擊)
中間人攻擊:在中間人攻擊中,攻擊主機通常截斷客戶端和伺服器的加密通訊。攻擊機以自己的證書替代伺服器發給客戶端的證書。通常,客戶端不會驗證該證書,直接接受該證書,從而建立起和攻擊機的安全連線。這樣,客戶端傳送的資料,都會被攻擊機獲取和解密。
工具介紹
Fiddler | charles | anyproxy | |
---|---|---|---|
手機安裝證書 | 需要 | 需要 | 需要 |
支援抓取 | http/websocket/https(單向認證) | http/websocket/https(單向認證) | http/websocket/https(單向認證) |
支援平臺 | win/mac/linux(受限) | win/mac/linux | win/mac/linux |
指令碼開發 | Jscript.net | 未知 | js |
具體的報文走向如下
手機上的配置方法(以Fiddler為例,其它類似)
-
準備工作:手機與PC在同一個區域網內(可以連同一個WIFI,或者電腦插入移動WIFI)
-
配置步驟見下:
==特別說明,抓不到報文可能的情況==
1、單向雙向 https
https的抓包原理是基於中間人攻擊的方式,但是這種方式只適用於單向認證的方式,也就是隻是客戶端去檢驗服務端的證書。而雙向認證的Https,服務端還會校驗客戶端的證書。https握手過程如下:
如何檢測是雙向認證還是單向認證,可以通過wireshark抓包看雙方的協商過程,證書的交換是否是雙向的。
解決辦法:暫時沒有好的辦法解決這個抓包的問題
2、ssl pinning
ssl pinning:證書鎖定Certificate Pinning是SSL/TLS加密的額外保證手段。它會將伺服器的證書公鑰預先儲存在客戶端。在建立安全連線的過程中,客戶端會將預置的公鑰和接受的證書做比較。如果一致,就建立連線,否則就拒絕連線。Certificate Pinning在手機軟體中應用較多。因為這些應用連線的伺服器相對固定,可以預先將伺服器的X509證書或者公鑰儲存在App中。例如,蘋果應用商店Apple App Store就預置了這個功能。當使用中間人工具或者Fiddler之類的工具攔截資料,就會造成應用商店無法聯網的情況。
抓取實現
抓到報文後,就可以模擬請求了。請求傳送的幾種方式:
-
抓包工具裡面提供了傳送功能,Fiddler中的Composer 標籤裡提供了此功能。
-
Chrome的Postman擴充套件程式也可以用來發送報文。
-
Python中的requests包也可以方便地實現
缺陷
-
如何構造更多的請求?(常見的分頁請求、更換查詢引數等)
-
如果抓不到包怎麼辦?(如果通訊走socket怎麼辦?)
-
http引數中包含加密、簽名欄位,如何找到引數的生成方法?
二、模擬點選
基本原理(基於UIautomator)
通過程式模擬人的行為對APP的介面進行點選、滑動等操作,同時可以獲取APP的Activity頁面上的大部分控制元件上的文字資訊(有一些可能獲取不到,Uiautomator本身就獲取不到)
工具介紹
Appium | Macaca | |
---|---|---|
支援平臺 | 需要 | 需要 |
指令碼語言 | PC/ios/android/hybrid(h5、native混合) | PC/ios/android/hybrid |
備註 | 支援Android所有版本 | Android支援API>17 |
底層框架 | UIAutoation(IOS)/UIAUtomator+Selendroid(Android) | XCUITest(IOS)/UIAUTOMATOR(Android) |
穩定性 | 一般 | 更好 |
開源 | JS基金專案,社群活躍 | 阿里開源,未來未知 |
==特別說明==
無
抓取實現
-
程式基本架構
-
框架API說明 以Appium為例,Appium 支援的API 介紹如下:
-
定位支援
-
通過accessibility id查詢元素
-
通過元素id
-
通過元素文字內容
-
通過元素可見連結文字定位
-
通過元素標籤名稱定位元素
-
通過元素class name屬性定位元素
-
支援單個、批量獲取
-
操作支援
-
從某個元素滑動到另一個元素
-
把某元素拖到目標元素
-
模擬手指點選(最多五個手指),可設定按住時間長度(毫秒)
-
從A點滑動到B點,滑動時間可配
-
快速滑動
-
模擬雙指捏(縮小操作)
-
在元素上執行放大操作
-
單擊
-
還能搖一搖(IOS支援)
-
執行JS指令碼
-
獲取H5頁面的page source
-
輸入框輸入(回車的支援,建議選用sogou輸入法,keycode: 66 ,==這樣不需要去定位鍵盤上回車的輸入==)
-
控制APP
-
安裝、刪除、執行、關閉APP
-
指定執行某APP的某activity
-
獲取控制元件資訊
-
文字
-
元素tag名稱
-
內容描述(content-desc)
樣例程式碼(python)
如果使用過selenium做爬蟲或測試,對這個介面應該很熟悉。
from appium import webdriver desired_caps = {} desired_caps['platformName'] = 'Android'desired_caps['platformVersion'] = '6.0'desired_caps['deviceName'] = '192.168.174.101:5555'desired_caps['appPackage'] = 'com.android.calculator2'desired_caps['appActivity'] = '.Calculator'driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) driver.find_element_by_id("digit_1").click() driver.find_element_by_id("op_add").click() driver.find_element_by_id("digit_2").click() driver.find_element_by_id("eq").click() driver.quit()
缺陷
-
獲取效率低
-
定位元素需要時間
-
為了保證穩定,需要在額外地增加等待時間
獲取的資料有限
-
只能獲取到介面上可視控制元件的資訊
-
H5頁面資訊,(需要切換driver到H5)
Appium的不穩定,出現異常時有可能程序卡死,需要重新啟動
三、APK逆向
基本原理
方法一、二 對於沒有android逆向經驗的朋友是不錯的選擇,開發起來也比較簡單,能滿足一些對於應用資料的需求。但是如果想要更高效地獲取更多的資料,就需要研究APP的程式碼。通過向APK中注入自己的程式碼,修改APP本身原來的邏輯,比如修改函式執行內容、增加新的邏輯等等來來實現自己的目標。一般的操作步驟如下:
-
逆向APK
-
分析smali程式碼
-
通過hook框架向APK中注入程式碼,修改邏輯
需要的基礎
-
smali語法
-
APK反編譯
-
靜態、動態除錯
-
常用HOOK框架
-
反除錯、反HOOK應對策略
下面知識可以快速入門smali語法,最基本的資料型別,函式定義關鍵字,暫存器作用說明
關鍵字
field private isFlag:z --- 定義變數.method --- 方法.parameter --- 方法引數.prologue --- 方法開始.line 12 --- 此方法位於第12行invoke-super --- 呼叫父函式const/high16 v0, 0x7fo3 --- 把0x7fo3賦值給v0invoke-direct --- 呼叫函式return-void --- 函式返回void.end method --- 函式結束new-instance --- 建立例項iput-object --- 物件賦值iget-object --- 呼叫物件invoke-static --- 呼叫靜態函式
資料型別
B --- byteC --- charD --- double (64 bits)F --- floatI --- intJ --- long (64 bits)S --- shortV --- void 只能用於返回值型別Z --- BooleanLxxx/yyy/zzz; --- 類 [XXX --- 陣列
暫存器型別
暫存器採用v和p來命名, v表示本地暫存器,p表示引數暫存器, 共16個暫存器,v0~v15, 關係如下 v0第一個本地暫存器 v1第二個本地暫存器v2 p0(this)v3 p1第一個引數 v4 p2第二個引數 v5 p3第三個引數 當然,如果是靜態方法的話就只有5個暫存器了,不需要存this了。 .registers使用這個指令指定方法中暫存器的總數 .locals使用這個指定表明方法中非參暫存器的總數,放在方法的第一行
工具介紹
1. 反編譯工具
APKToolbox 工具
AndroidKiller(smali 程式碼IDE)
常見問題及解決辦法
-
有一些包無法使用Apktool進行反編譯,常用解決辦法:
需要先下載smali.jar,baksmali.jar signapk.jar, 先把APK包解壓縮,然後直接使用 smali.jar baksmali.jar 來進行解壓縮1:將dex 輸出為 smali檔案 java -jar baksmali-2.0.3.jar classes.dex # 把dex 檔案反編譯2:將修改的smali 檔案 重新打包成dex 檔案# 把 out 資料夾下的smali檔案重新打包成classes.dex檔案java -jar smali-2.0.3.jar out #給APK包簽名java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk
2. 脫殼工具
一些對安全性要求高的APP會採用加固工具為自己的APK加殼,表象就是你能反編譯程式碼,反編譯出來的smali程式碼很簡單,只能看到殼的主程式程式碼,並沒有真實的業務邏輯程式碼。 可以藉助apktoolbox來進行檢測是什麼殼,而去尋找對應的脫殼工具。(由於加固這個比較專業,這裡只推薦幾款比較出名的脫殼工具,細的就講不了了)
3. 常用Hook 框架
xposed | Cydia Substrate | Frida | |
---|---|---|---|
支援的系統 | android | android/IOS | win/mac/linux/IOS/Android |
版本要求 | android<=8.0 | android(<=4.4)/ios(<=9.1) | android<=8.1 |
開發語言 | Java | Java | Python+Js |
是否Root | 需要 | 需要 | 需要 |
執行 | 安裝後重啟 | 安裝模組後需要軟重啟 | 基於指令碼互動 |
Java/Native | Java層 | Java/Native | Java/Native |
4. 動態除錯smali程式碼
5. 動態除錯so
==特殊說明==
隨著開發者對於資料安全性的重視,一般的APK都會有各種保護策略,包括程式碼混淆、加殼,反除錯,hook檢查等等策略。我們非專業安全研究人員,只能見招拆招,只要能實現我們的目的就可以了,面對一些常規的策略有以下幾種應對措施。
反除錯
-
呼叫ptrace(PTRACE_TRACEME,0,0,0) (原理一個程序只能被一個程序Ptrace)
-
檢測TracerPid的值
-
檢測程式碼的執行間隔時間
-
檢測手機的硬體資訊是否在偵錯程式中
-
檢測android_server的埠號
-
檢測android_server 名稱
-
檢測在除錯狀態下的軟體斷點
-
通過使用Inotify對檔案進行監控
-
檢測程序列表中是否存在常見的Hook/除錯的程序名稱
反hook
-
檢測已經安裝的應用裡是否包含xposed/Cydia Substrate
-
hook PackageManager的getInstalledApplications,把Xposed或者Substrate的包名去掉
-
關鍵函式檢查呼叫棧裡的可疑方法
-
hook Exception的getStackTrace,把自己的方法去掉
-
檢測並不應該Native的native方法
-
hook getModifiers,把flag改成看起來不是native
-
通過/proc/[pid]/maps檢測可疑的共享物件或者JAR
-
hook 開啟的檔案的操作,返回/dev/null或者修改的map檔案
抓取實現
-
基於框架,開發hook程式碼
缺陷
-
hook的方式對APK的程式碼有侵入,需要對APK中的各種反除錯、反hook檢測手段做規避
-
如果遇到加殼的,分析時間會很長。如果無法脫殼,那麼將無法實現抓取
四、開發工具
-
Requests庫
-
開源框架包括
-
Pyspider
-
Scrapy
-
Tornado協和實現併發訪問
五、參考
網易雲免費體驗館,0成本體驗20+款雲產品!
更多網易研發、產品、運營經驗分享請訪問網易雲社群。