frida Hook某金融APP加密算法
0.前言
朋友给到一份APP,在渗透测试的过程中发现是密文传输的,想要进行渗透测试非常困难,想要尝试解密出来明文,这时候就用到的frida逆向大法。
1.安装APP
判断APP是否是加壳的,使用查壳工具发现是使用了邦邦企业壳
如果壳程序没有frida检测的话,其实对我们逆向HOOK的影响不算是特别的大。这里随便输入一个Hello frida脚本,判断存在frida检测,还得过一下frida的反调试....
2.frida反调试
常见的frida检测方式就是查看当前进程的maps文件,以及status文件,一般会使用libc.so中的open函数去打开文件,这里可以查看一下是查看到什么文件的时候程序就闪退了。代码脚本如下
function hook_open() {
var pth = Module.findExportByName("libc.so", "open");
Interceptor.attach(ptr(pth), {
onEnter: function (args) {
this.filename = args[0];
console.log("", this.filename.readCString());
}, onLeave: function (retval) {
return retval;
}
})
}
setImmediate(hook_open);
执行结果如下,可以根据结果进行两点判断。
1.确实程序是使用了libc.so中的open函数进行读取文件的
2.是读取到进程下的/task目录中的某一子线程的status文件就闪退的(这里关于被调试状态的进程的status文件的变化就不赘述了,网上有许多的文章)
于是我们的思路就有了,可不可以hook open函数发现它在读取task文件夹下的文件的时候就重定向文件到一个我们伪造的文件呢?代码如下,就是我们hook住open函数,然后如果发现它的入参存在task关键字,就定位到我们要它读的/sdcard/status
文件去,从而伪造一下手机的状态,尝试绕过frida反调试。
function redirect(src, dest) {
var openPtr = Module.getExportByName('libc.so', 'open');
var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
Interceptor.replace(openPtr, new NativeCallback((pathPtr, flags) => {
var path = pathPtr.readUtf8String();
var originPath = Memory.allocUtf8String(src);
var currentPath = Memory.allocUtf8String(dest);
var fd = -1;
if (path.indexOf("task") > -1) {
var targetPath = Memory.allocUtf8String(dest);
fd = open(targetPath, flags);
}
else {
// console.log('open file "' + path + '"');
fd = open(pathPtr, flags);
}
return fd;
}, 'int', ['pointer', 'int']));
}
function main() {
//hook_open();
redirect("task", "/sdcard/status");
}
setImmediate(main);
很好!已经成功可以注入进frida了
3.定位加密方法
这里我们抓包看一下数据包的样子,抓到的是如下形式的数据包,可以看到我们无法定位到关键的特征比如关键参数等等,那就只能搜索常用的加密类了,比如Crypto
于是我们启动objection尝试搜索是否存在这种加密类,注意这里那边注入bypass的frida不要放开,还是要一直注入,然后objection这里呢要使用APP的名字注入,这样是attach模式,可以同时和frida一起注入脚本。
使用android hooking search classes Crypto
命令搜索到了152个相关的类
之后我们将搜索出来的结果放到一个txt中,发现有两个不常见的类,因为其余都是安卓自带的以及Java的库,这种情况其实要优先查看开发自写的类的。
于是我们来hook这两个类
然后找到登录的位置,发送一个数据包,可以看到执行结果如下
可以定位到com.rytong.emp.net.CryptoHttpManager
这个类在进行加密,于是我们其实可以hook handleRequestBody()
方法,顾名思义它是处理请求体的方法,盲猜一下加密就在这里
然后再发一次包,可以看到第一个参数是明文的发送的接口,第二个我觉得应该就是加密前的明文的byte数组。
到这里objection就不能将byte数组转换成我们可以看懂的字符串了,需要去编写frida脚本了
function main() {
Java.perform(function () {
var CryptoHttpManager = Java.use('com.rytong.emp.net.CryptoHttpManager');
var StringClass = Java.use('java.lang.String');
CryptoHttpManager.handleRequestBody.implementation = function () {
console.log('\nURL ===> ', arguments[0]);
console.log('\nData ===> ', StringClass.$new(arguments[1]));
return this.handleRequestBody(arguments[0], arguments[1]);
}
})
}
setImmediate(main);
我们直接使用attach模式注入APP中可以看到,获取到了明文
之后的测试在JS中修改参数也可以,或者使用python将数据包转发到BP上也可以。
文章来源:https://www.t00ls.com/articles-70108.html
文章作者:Red256
布施恩德可便相知重
微信扫一扫打赏
支付宝扫一扫打赏