這個apk是去年參加某個CTF比賽時候的一道題,當時沒做出來,這幾天整理檔案翻出來了,決定再做一做,寫點筆記。
題目描述:某企業反饋其員工專用手機上,被安裝了一個間諜軟體,該軟體會不定期自動連線一個疑似黑客控制的伺服器,伺服器的連線密碼內嵌在該軟體中。逆向分析此間諜軟體,獲取其伺服器的連線密碼。
首先安裝執行一下。
拖到jadx裡面,可以看到java層並沒有什麼核心功能,關鍵是匯入了一個net庫,用了裡面的upload函式。
解壓apk之後得到libnet.so,拖到IDA裡面提示First Section must be SHT_NULL,很有可能section被加密了。
在IDA裡面看到有個.init_proc和JNI_OnLoad,JNI_OnLoad的程式碼應該是被加密過的。
那麼這個時候我們就只能動態除錯了,動態除錯的步驟網上一搜一大堆就不再詳細寫了,這裡在linker下的斷點, BLX R4之後就進入了.init_proc。
直到執行完sub_2C5A之後發現libnet.so已經消失了,取而代之的是debug077,同時JNI_OnLoad也被解密了出來。
這裡需要匯入JNI,在IDA7.0以下的版本中通常是通過這篇文章中的方法匯入JNI的。在IDA7.0及以上的版本中有一種更簡單的方法。View->Open subviews->Type Libraries,按下Insert,選擇android_arm(IDA6.8裡面沒有這個庫所以不能用這個方法)。
開啟Structures,按下Insert,選擇Add standard structure,選擇_JNIEnv和JNINativeMethod。
把變數的型別改成JNIEnv*,Force call type,現在看起來舒服多了。
這裡在JNI_OnLoad中通過RegisterNatives註冊了java層需要呼叫的native方法,我們到0x7579411C看看。
IDA沒有識別出來這個結構體,我們手動新增一下。右鍵Structure,選擇JNINativeMethod,函式名為Upload,地址為0x7578E30C,這個函式就是我們在java層看見的函式了,到這個地址看看。
右鍵Create Function,但是提示debug077:7578FBD0: The function has undefined instruction/data at the specified address。
直接按C,全部轉成程式碼,就可以建立函式然後F5了。
這裡兩個異或非常可疑,寫個指令碼看看異或之後的值是多少。
#include <idc.idc>
static main()
{
auto start,end,ptr;
auto key;
start=0x75794004;
key=0;
for(ptr=start;ptr<=start+11;ptr++)
{
Message("%c",Byte(ptr)^key);
key++;
}
Message("\n");
key=0;
for(ptr=start+12;ptr<=start+20;ptr++)
{
Message("%c",Byte(ptr)^key);
key++;
}
}
解出來這兩個字串就應該是答案了。
總結一下:
1.一定還是要用真機除錯,bug少點,nexus4就兩三百塊錢。我等屌絲還是應該搞android,比學ios/macos便宜多了。
2.關於IDA匯入JNI
這個文章中已經說了有兩種方法,IDA7.0以下的版本需要手動匯入jni.h檔案,IDA7.0及以上的版本可以使用內建的庫。
3.關於程式的debuggable選項
這一點文章中沒提,如果程式的debuggable選項未開啟就直接jdb去attach的話是除錯不了的,會出現下面這樣的錯誤。
可以修改AndroidManifest.xml中的debuggable="true"然後簽名重打包;或者修改系統屬性將defalut.prop中ro.debuggable設定為1。這兩種方法操作起來其實都很麻煩而且容易遇到各種各樣的問題,所以我一般用的方法一個是riusksk的BDopener,一個是netsniffer優化的mprop。這兩個工具更方便。如果還是報錯的話可以開啟DDMS,點一下你要除錯的程式,點了之後會出現8700的埠和紅色的蟲子。這個時候再attach應該就沒問題了,成功attach上去蟲子會變成綠色。
4.關於讓程式停在載入so檔案之前