實戰|一次APP密文Hook獲取明文數據
在APP測試過程中,可能會遇到各種阻礙,如:
- Root檢測,不能在root手機進行測試。
- 代理檢測,無法代理抓包。
- 證書強校驗,會出現“網絡連接錯誤”等提示信息。
- 請求包的body部分被加密,使用AES、RSA等等。
那么在遇到這些情況的如何去應對?
目前比較好用的方法是Hook抓包,繞過一些檢測校驗。(逆向加密算法成本太高,比較費時間,這里加密函數是在native層的。)
本文將講述APP在密文通信下,通過hook手段看到明文數據。
1.請求包密文參數hook:
打開某APP,登入抓包發現數據加密處理了,想辦法搞明文:

使用app查看工具查看apk是否加固,最終驗證是360加固。

然后使用了脫殼機進行脫殼,脫殼機拖出了很多dex文件,最終目的是想知道 “明文”、“密文”相關的函數在哪個dex文件(僅展示部分文件)。

下一步思考,進行簡單的定位,分析請求包的body部分,觀察iv參數,很像base64編碼。

嘗試使用base64解碼,解碼后的數據為 “5b567f680892474e”,這數據可能是AES算法的IV,十六進制的。

既然body的iv部分使用了base64編碼,下一步立馬想到對“某APP”進行base64的hook,因為他的request請求體部分肯定調用了base64加密,js代碼如下:
Java.perform(function () {
function showStacks() {
console.log(
Java.use('android.util.Log').getStackTraceString(
Java.use('java.lang.Throwable').$new()
)
)
}
var base64 = Java.use("android.util.Base64");
base64.encodeToString.overload('[B', 'int').implementation = function (a,b) {
showStacks();
console.log("base64.encodeToString: ", JSON.stringify(a));
var result = this.encodeToString(a,b);
console.log("base64.encodeToString: ",result)
return result;
};
});
Hook的結果,確實調用了android內置的base64方法,但是,結果和iv的不一樣。進一步分析,他這個的base64是請求體cookie里面部分數據的base64結果,不是body部分的,所以加密和這塊無關。
但是這一部分有價值,他的調用棧顯示了整個調用過程,分析調用棧有個 “encryption” 字眼,第一印象,這估計就是加密函數,所以,下面根據調用棧的類名,定位脫殼后的dex文件(為什么要定位dex?因為脫殼后的dex文件太多,無法準確定位功能點)

通過上圖調用棧,將encryption的類名進行全文搜索,關聯到是5856160這個dex文件:

然后用jadx分析這個dex,發現都是方法a的重載

直接用objection批量hook,發現是調用了2個a方法,一個參數是“[object Object]”,另一個是“int, java.util.Map”:

針對上述兩個方法進行hook,編寫hook腳本:
Java.perform(function () {
var name = "com.xxx.xx.util.encryption.c";
var encrypt = Java.use(name);
encrypt.a.overload('java.util.Map').implementation = function (obj) {
console.log("parameter is : ", JSON.stringify(obj));
var retval = this.a(obj);
console.log("1 return value : ",retval);
return retval;
};
encrypt.a.overload('int', 'java.util.Map').implementation = function (num, map) {
console.log("first parameter : ",num);
console.log("second parameter : ",JSON.stringify(map));
var retval = this.a(num, map);
console.log("2 return value : ", retval);
return retval;
};
});
然后運行打印,驗證一下,一個是明文數據,一個是密文數據:

分析過程到此結束,即可看到明文數據。
2.響應數據hook
再進一步分析,然后發現com.xxx.xx.h.a方法有響應內容輸出:

進入com.xxx.xx.h.a方法:

然后反編譯dex文件,發現response關鍵字眼,代碼中是將內容放入af的c方法中,下面看看af是什么:

發現af好像是kotlin的有一個底層庫:(af是混淆后的名字)

然后用objection打印參數查看,確實有響應包的數據,下面直接hook這個kotlin模塊:

編寫hook腳本:
Java.perform(function () {
var name = "com.xxx.xx.util.encryption.c";
var encrypt = Java.use(name);
encrypt.a.overload('java.util.Map').implementation = function (obj) {
//console.log("parameter is : ", JSON.stringify(obj));
var retval = this.a(obj);
send(retval);
var tmp;
var op = recv('python_send', function(value) {
console.log("修改完的數據:", value.payload);
tmp=value.payload;
return value.payload;
}).wait();
//console.log("op: ",op);
return tmp;
};
var response = Java.use("kotlin.jvm.internal.af");
response.c.overload('java.lang.Object', 'java.lang.String').implementation = function (obj, s) {
var r = s.indexOf("try");
//console.log("r = ", r);
if (r!=-1) {
console.log("result is ",)
console.log("one param is ", obj);
//console.log("two param is ", s);
}
var retval = this.c(obj,s);
return retval;
};
});
這里hook腳本js和python腳本聯合,將請求發送到burpsuite,再通過burpsuite將修改后的數據回調進app進行后序操作,如下圖:
正常的請求過程

Hook的過程:

這個過程中需要一個中轉服務器,一個和burpsuite通信的腳本:(其中hook的語句寫入了通信腳本里面,讓其自動加載進去)。最終控制臺輸出明文數據。
測試截圖:

?