如何脫殼加固過的Apk並利用其API「走近庫」

0x00 尋找突破口

打開首頁,emm 就一個登錄頁面,沒了 隨便寫點東西提交看看

天生手欠的我一不小心就多輸了一個單引號

WDNMD,除了數字和字母其他都不行? 這叫我怎麼測? 剛剛要放棄,就在這時,首頁的一個二維碼吸引了我 正是Android端的軟體,眼前一亮,彷彿找到了打開新世界的大門

開開心心地把軟體下載過來,想反編譯找找看有什麼可利用的介面

360加固? fa?!

我以為上帝關上了我的門,還會留個窗給我,結果還是無情地把窗給我鎖上了

0x01 zjDroid脫殼

刀不鋒利馬太瘦,你拿什麼工具和我斗。 我們已經知道不論是利用什麼方法加固apk 若要讓軟體要正常運行,就必須讓程式最終載入原dex文件,這樣的話,如果我能dump出記憶體中已經載入的dex 就可以無視在載入dex前的一大堆解殼操作 而ZjDroid就可以做到這一點,ZjDroid是一款基於Xposed開發的插件,它可以輕鬆地hook住所有的activity,並且將軟體當前載入的dex寫出

在github上fork其源碼,進行分析 有進行過Xposed插件開發的大佬們都知道,想讓Xposed載入你編寫的插件的核心程式碼 就必須在assest/xposed_init文件內寫入你想要載入的核心程式碼的所在包

進入ReverseXposedModule類

可以看到圖中兩處紅線標記處 因為我們的目的是Dump處dex文件,所以先對第二處紅線標記處進行分析 跟進DexFileInfoCollecter的start方法

通過觀察程式碼可知,第一處紅線標記處程式利用反射找到了系統DexFile類的openDexFileNative方法 這個方法和系統載入dex文件有關,這裡不深入分析 接著看第二處標記處,程式調用Xposed模組的hookMethod方法hook住了openDexFileNative方法 繼續看第三處,在hook完成之後,只要系統調用到了openDexFileNative方法,紅線處的程式碼就會執行 第三處紅線處的程式碼用於獲取載入的dex的資訊,這裡不深入分析 也就是說,只要用戶打開某個app,系統調用dex文件的方法就會被執行,那麼ZjDroid只需要hook住系統調用dex文件的方法,就可以在軟體載入原dex後做任何事情了! hook載入dex方法的程式碼已經執行完畢

我們回到ReverseXposedModule類中的第一處紅線標記處,進行分析 跟進其調用的initModuleContext方法

查看第一處標記,程式同樣的找到了Application類的onCreate方法 開發過app的大佬們都很熟悉這個onCreate方法吧,這是每個軟體在啟動時默認最先執行的方法 這裡ZjDroid同樣對系統的Application類的onCreate方法進行了hook,換句話說,只要用戶點開任何一個軟體,都能被程式hook住 同樣的,程式也是利用hookMethod進行的hook操作,hook後的操作在ApplicationOnCreateHook類中,跟進程式碼

可以看到程式給每個被hook的app註冊了一個廣播,跟進程式碼

分析程式碼可知,當被hook的app接收到含有com.zjdroid.invoke字元的廣播時就會進入判斷 程式將提取出廣播中鍵為"target"和"cmd"的值 通過圖中第二處紅線下方的程式碼可知target就是app的pid號 在獲取cmd的值後,cmd的值將被傳入CommandHandlerParser類中 跟進程式碼

觀察程式碼可知cmd的值就是一個json格式的字元串 程式將根據json中的值對應地執行操作 我們需要dump出dex文件,假設我發送的廣播進入了ACTION_DUMP_DEXFILE分支 程式將向DumpDexFileCommandHandler類傳入指定值,跟進程式碼

其中紅線標記處就是dump dex文件的核心程式碼了 跟進

查看其中紅線處,data成員調用的方法就是dump出記憶體中dex文件的程式碼,接著程式將data寫出到指定目錄 遺憾的是,紅線出的程式碼為native層的程式碼,而native層的程式碼作者並沒有開源 編譯,運行 踩坑注意:這個工具的so文件似乎在5.0以上的Android系統不起作用,所以我特意刷了一個4.4的Android再去安裝ZjDroid 在手機的Xposed中啟用此插件,然後打開需要脫殼的app adb shell dumpsys activity top查看最頂層活動的PID號 接著發送廣播dump出dex

dex被成功dump、

0x02 尋找介面

查看軟體的入口 打開指定類 未加殼的dex成功被載入了! 我現在看到的是原dex的程式碼,而不是殼dex的程式碼!

可以看到onCreate方法為native層方法,但是接著往下看 getInfo方法中有一個利用post請求調用的登錄介面 請求一下看看什麼情況

WTF?返回的實體中告訴我無權調用此介面?! 難怪把onCreate方法放在native層里!一定是在onCreate方法中需要進行什麼操作才能正常調用此介面 可native層的程式碼實在是無能為力 本打算就這麼放棄了,最後一次在程式碼中搜索可能存在的介面

其中一處介面讓我眼前一亮

WTF?!WTF?!居然可以請求!還沒有過濾特殊符號?! 管理員還真是粗心

丟到sqlmap里

收工!

ps:具體細節不做演示,本文僅限圈內技術交流禁止用於非法用途!