APP 載入 JS 的逆向解析方法
抓取登入包
解決安全檢測
使用木木模擬器,安裝好app剛準備愉快的抓個包。竟然檢測到root,不能進入。那就先把這個給他hook掉。
用jadx開啟apk,全域性搜尋一下,提示的文字。
可以看到這裡進行了幾種檢測,編寫frida hook程式碼,直接把 initCheckSafe 方法置空
Java.perform(
function () {
var SecurityBuilder = Java.use('XXXXXXXX.SecurityBuilder');
var initCheckSafe = SecurityBuilder['initCheckSafe'].overload('android.content.Context',
'java.lang.String');
initCheckSafe.implementation = function () {
send("hook initCheckSafe");
};
}
解決完畢,我們再進入app
又提示要跟新,事是真的多。那就更新吧。點選更新後,載入了一些東西,然後進入了登入頁面。(!!! 後面發現這裡的坑)
抓包分析
配置好代理,直接抓包。
可以看到請求的資料模式都是
action=xxxx&data=json
把這個json資料拿出來看看,多嘗試幾次發現密碼不變這個password不變,其他的引數都可以寫死。到這裡,如果賬號少的話,手動抓一次包後續使用就可以了。但是我們能滿足於此嗎,盤它!
尋找加密位置
盲狙碰運氣
這個引數看著像是,某種加密後base64的結果。先base64解碼看看啥情況。將加密後的值urldecode之 後再base64解碼
一堆亂碼看不懂。那我們使用南山大佬寫的xposed的模組把常見加密hook一波,嘗試快速定位。啟用xposed plus模組,然後開啟ddms,檢視日誌資訊。
可以看到常見的加密類都被hook到了,但是在儲存的日誌中嘗試搜尋輸入的密碼,抓包的加密結果等, 都一無所獲。
搜尋反編譯程式碼
看來好事多磨,快的不行那我們去分析程式碼吧。
嘗試搜尋 登入連結 登入引數欄位值等,都尋找不到有用的資訊,事情好像陷入了僵局。
巧計尋出路
靜靜思考一會,回想到登入介面引數data後面的值是一個json型別,也就是字典型別。那能不能hook java中這個類,看看有沒有password賦值的操作
百度一波,得到如下hook程式碼
var print = console.log; function hoon_map(cName, mName, args) { Java.perform(function () { var clz = Java.use(cName); if (clz == null) { throw "java.use()==null" }; var method = null; method = clz[mName].overload(args[0], args[1]); method.implementation = function () { print(cName + " " + arguments[0] + " " + arguments[1]); var ret = method.apply(this, arguments); return ret }})} function main() { print("runing"); hoon_map("java.util.HashMap", "put", ["java.lang.Object", "java.lang.Object"]); hoon_map("java.util.LinkHashMap", "put", ["java.lang.Object",
"java.lang.Object"]); } main()
把這程式碼靈活運用一下,我們再登入一次看看結果。
果然發現了賦值操作,那就過濾一下無用的資訊,再把這個操作的呼叫棧列印出來,順藤摸瓜,那不就 能找到加密位置了嘛。感覺看到了希望。
還好呼叫棧不是很多,去掉 java開頭的和proxy,剩下的我們從上面開始一個個看一下,有沒有加密的地方。
一直找到最下面這個方法,引數可以看到是從 exec 這個函式的引數傳來的。那麼hook這個exec的入參看一下。
hook 結果:
這下矇蔽了,都追到根了,咋還是加密過的值呢。
再肯硬骨頭
發現線索一
有困難但是也不能放棄。再自己端詳一下exec的程式碼,發現它頭部有個@JavascriptInterface好像裝飾 器一樣的東西,和別的函式都不一樣。
不懂我們就去搜尋一下,然後發現這個是可以讓 js 和 java 互相呼叫的一個東西。
那就知道方向了,加密是在js中進行的,然後js中呼叫java裡的exec方法,將值傳了進來。
將apk反編譯,先去找找那些js中,有cbPassInfo setOfflineCache這些資訊。
喲呵,搜到了這兩個裡面有。把他倆拖出來瞅一瞅。
在 login.js 裡面只有這兩處。先驗證一下這裡是不是傳加密值的地方。
我把這裡的 cbPassInfo 改成別的字串,然後重新打包簽名apk,安裝,再抓取一次登入包,如果出現的是我修改的字元,那說明這就是呼叫的位置。
信心滿滿,又抓了一次包。結果啪啪打臉。還是 cbPassInfo 。
發現線索二
突然想到,重新安裝開啟後,有個提示框,更新資源,難道它又重新下載了這個檔案,把我修改的重置 了。
解除安裝,重灌後,抓包檢視下它更新的資源,發現果然是這樣。
既然修改apk不行,js又是靜態檔案,那直接在模擬器中搜尋login.js
結果有3,4個,把檔案重新命名,app開啟沒了登入介面,那就是它了。
模擬加密
分析js
先分析一下js,密碼就是透過藍框兩個方法加密的。
先搜尋一下 D 和 Base64,Base64沒有獲得有效的資訊。發現D應該和 sha1 有關係
這裡js不好除錯,我們利用js呼叫java的流程,把我們想要的值傳給java層,然後去hook接收的函式。這 裡把我把用到的函式,各種結果都列印了一下。
這個D剛才看是和sha1相關的,用標準的sha1對比一下。
發現和上面結果相同。那就只剩base64這個函式了。看列印出來的程式碼,發現這不是一個標準的base64,執行報錯缺少 c 變數。
搜素函式內的程式碼,在common.js中發現了
現在邏輯清楚了,把c的值拿過來,用js來實現加密。可以看到結果和抓包一致,收工。
總結
之前遇到的app都是在java程式碼中加密,或者 so庫裡面。在js中的這是第一次遇到。
幸運的是js沒有做處理,如果把web端的反扒應用在這,手機端又不好對js進行除錯,那真是夠禿頭的了,可怕。
這篇來自小夥伴 ID: 浮生 的投稿。
安利下偶的爬蟲逆向進階課,包含 安卓逆向抓取/安卓群控/JS逆向抓取/爬蟲框架設計與工程經驗,國慶時正好學習下,目前熟悉安卓逆向抓取技術拿個20K+ 的 offer 還是容易。
具體點選下面連線
我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。
***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***