玄知安全实验室
- 关注

Frida是APP安全性测试中常见的工具,可以通过编写JavaScript、Python代码来和服务端进行交互,具有HOOK灵活,功能全面的特点,本篇利用靶场进行Frida的练习和记录,由于它十分强大,本篇只包含它的的冰山一角。
第一关:
frida-ps -Uai
查看模拟器中APP对应的标识符,等下启动程序时用
注意:靶场APP需要较高版本的安卓模拟器,如果手头没有现成的,可以使用阿木木~ https://adl.netease.com/d/g/mumu/c/gw_mumu12?type=pc&direct=1
安装.APK,随便输入点内容,点Summit,提示Try again
查看下源码
可以看到点击提交按钮后,触发
onclick,String obj = editText.getText().toString();获取了app中输入的内容,
final int i = get_random();生成了随机数,
再把他们俩传入void check(int i, int i2)方法
当 if ((i * 2) + 4 == i2)时,就成功了,那就需要HOOK一下get_random()、check()
先hook get_random():
Java.perform(function() {
var a= Java.use("com.ad2001.frida0x1.MainActivity");
a.get_random.implementation = function(){
console.log("This method is hooked");
let ret = this.get_random();
console.log('get_random ret value is ' + ret);
return ret;
}
})
运行APPfrida -U -f com.ad2001.frida0x1 -l 脚本文件.js
发现随机的数是44,那么根据算法 if ((i * 2) + 4 == i2),就是44*2+4=92,输入92试试:
也可以固定设置get_random的值,比如这里让他返回5,那就输入5*2+4=14
Hook check()方法的情况:
Java.perform(function() {
let MainActivity = Java.use("com.ad2001.frida0x1.MainActivity");
MainActivity["check"].implementation = function (i, i2) {
console.log('check is called' + ', ' + 'i: ' + i + ', ' + 'i2: ' + i2);
this.check(i, (i * 2) + 4);
return ;
};
})
直接给check方法传入参数(i,(i * 2) + 4),这样无论输入什么都是相等的了
第二关
打开APP,发现没有输入框:
太嚣张了,看看源码咋回事
发现当a == 4919,就会调用AES解密,编写脚本
let MainActivity = Java.use("com.ad2001.frida0x2.MainActivity");
MainActivity["get_flag"].implementation = function (a) {
console.log('get_flag is called' + ', ' + 'a: ' + a);
let ret = this.get_flag(a);
console.log('get_flag ret value is ' + ret);
return ret;
};
没好用。。。回去看源码,发现是静态方法
那就需要重新编写脚本,再等启动后,把语句粘进来,一回车,就看到执行成功了
Java.perform(function(){
let MainActivity = Java.use("com.ad2001.frida0x2.MainActivity");
MainActivity.get_flag(4919);
}
)
这关是练习怎么hook静态方法的
第三关
打开界面
只能查看源码,发现 if (Checker.code == 512) ,而Checker在另外一个类文件中
那么只要让Checker.code累加到512,就能赢了
Java.perform(function() {
var MainActivity = Java.use("com.ad2001.frida0x3.Checker");
codevle = MainActivity.code.value
console.log('')
MainActivity.code.value=512;
})
这里还提到了循环的方式,因为从0开始每次增加2,所以只要256次循环就可以使code的值变成512
Java.perform(function () {
var a = Java.use("com.ad2001.frida0x3.Checker"); // class reference
for (var i = 1; i <= 256; i++) {
console.log("Calling increase() method " + i + " times");
a.increase();
}
});
第四关
界面这样
看看源码:
看看Check
看起来和上一关一样,只要满足if (a == 1337) ,就能通过了
但是仔细看,和第三关是有区别的
可以发现,区别是这关要调用的get_flag()方法不是静态的,需要创建类的实例,在frida中实例化可以用$new(),然后再调用实例中的get_flag()方法并传参1337
Java.perform(function() {
var check = Java.use("com.ad2001.frida0x4.Check");
var check_obj = check.$new(); // Class Object
var res = check_obj.get_flag(1337); // Calling the method
console.log("FLAG " + res);
})
第五关
直接看代码吧。。。
好像又是相同的套路。。。只不过这次要hook的类是MainActivity,不能直接用
var a = Java.use("com.ad2001.frida0x5.MainActivity");
var main_act = a.$new(); // Class Object
main_act.flag(1337); // Calling the method
不然会因为Frida缺少上下文报错
Frida中有两个获取上下文相关的方法:
`Java.performNow` :用于在 Java 运行时上下文中执行代码的函数。
`Java.choose`:在运行时枚举指定 Java 类的实例(作为第一个参数提供)。
他的格式是这样的
Java.perform(function() {
var <class_reference> = Java.use("<package_name>.<class>");
var <class_instance> = <class_reference>.$new(); // Class Object
<class_instance>.<method>(); // Calling the method
})
于是试着往里套案例并给flag()方法传入1337
Java.performNow(function() {
Java.choose('com.ad2001.frida0x5.MainActivity', {
onMatch: function(instance) {
console.log("Instance found");
instance.flag(1337);
},
onComplete: function() {}
});
});
当Java.choose函数成功选择到com.ad2001.frida0x5.MainActivity类的实例时,onMatch回调函数将被调用,并在控制台中打印出"Instance found"。
onMatch 回调函数中执行特定的操作,例如修改实例的属性、调用实例的方法等
onComplete: function() {} 选择过程完成时,onComplete回调函数将被调用(在这个例子中为空函数),这句如果不需要可以空着,但是不能不写
靶场下载地址:https://github.com/DERE-ad2001/Frida-Labs
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)