🌟 ❤️
作者:yueji0j1anke
首发于公号:剑客古月的安全屋
字数:1705
阅读时间: 5min
声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。合法渗透,本文章内容纯属虚构,如遇巧合,纯属意外
目录
-
前言
-
JS API实例
-
总结
0x01 前言
本章续讲前些日子出的app攻防-Frida&Hook 系列1,深度讲解frida的更多常用脚本
0x02 JS API语法实例
Java.use(classname) 获取指定的java类
Java.choose(classname, callback) 获取类的所有实例
Java.perform(callback) 回调函数
Java.cast(object, classname) 反射类
Java.enumerateLoadedClasses(callback) 枚举加载类
Java.enumerateClassLoaders(callback) 枚举类加载器
Java.enumerateMethods(classmethod) 枚举类的所有方法
这些是比较常用的,网上许多调用脚本其实不具有普适性。下面列举几个常用的样本js代码,平时只需改方法或包名即可
1.列举所有运行Java类
比如有些时候我们脱壳逆向出来的安卓包代码不全,又找不到我们想要hook的函数,就可以列出所有当前运行的Java类和方法
####
Java.perform(function() {
var packagename = "com.xiaojianbang.app";
console.log("[*] enumerating classes...");
Java.enumerateLoadedClasses({
onMatch: function(_className) {
if (_className.startsWith(packagename)) {
console.log("[*] found class: " + _className);
}
},
onComplete: function() {
console.log("[*] class enuemration complete");
}
});
});
2.列举类方法、内部类
对于具体的类,想获取其所有非私有方法和字段、内部类,代码如下
Java.perform(function() {
var wallet = Java.use("com.xiaojianbang.app.Money");
var methods = wallet.class.getDeclaredMethods();
for (var i = 0; i < methods.length; i++) {
console.log("构造函数名:" + methods[i].getName());
}
// 枚举构造方法
var constructors = wallet.class.getDeclaredConstructors();
for (var j = 0; j < constructors.length; j++) {
console.log("获取类构造名: " + constructors[j].getName());
}
var fields = wallet.class.getDeclaredFields();
for (var k = 0; k < fields.length; k++) {
console.log("字段: " + fields[k].getName());
}
var classes = wallet.class.getDeclaredClasses();
for (var l = 0; l < classes.length; l++) {
console.log("内部类: " + classes[l].getName());
}
});
3.列举引用堆栈
有时候找不到相关的加密算法或者相关的包追踪,就可以直接查询引用堆栈
Java.perform(function() {
console.log("==========begain==========")
var wallet = Java.use("com.xiaojianbang.app.Money");
wallet["$init"].overload('java.lang.String', 'int').implementation = function() {
console.log('Money.$init is called');
showStacks();
this["$init"]();
}
function showStacks(){
console.log(
Java.use("android.util.Log") //首先找到log类
.getStackTraceString( //调用log类的该方法
Java.use("java.lang.Throwable").$new() //new一个对象
)
)
}
});
4.主动调用内部函数
这里其实跟前面讲的差不多,只不过是函数重载实现的不同用法,这里偏向的是函数的直接调用
Java.perform(function () {
// 获得Toast组件
var Toast = Java.use('android.widget.Toast');
var makeText = Toast.makeText;
var String = Java.use('java.lang.String');
// 重载makeText方法,拦截并修改传递的消息内容
makeText.overload('android.content.Context', 'java.lang.CharSequence', 'int').implementation = function (context, content, time) {
var hookContent = String.$new('You are hacked by 月金剑客'); // 修改显示内容
return this.makeText(context, hookContent, time);
};
});
这里直接hook了安卓的组件,一但触发弹窗,即可修改里面对应内容
5.RPC远程调用
通过frida的rpc机制可以使我们在应用程序和目标设备之间通信,并且可以自主传参调用执行代码
比如此时你要hook住一个aes加密的函数,如果是一个较大型的应用,那么你很难知道具体的密钥与向量,这个时候就可以去调用函数对我们想要的参数进行加密,常规做法如下
那如果变成rpc调用,则如下所示
import codecs
import frida
import os
def adbforward():
os.system("adb forward tcp:27042 tcp:27042")
os.system("adb forward tcp:27043 tcp:27043")
hook_code = '''
rpc.exports = {
// 函数名gethello
gethello: function(str){
Java.perform(function(){
send("hook started...");
// use 加载的类路径
var AuthUtils = Java.use('com.xiaojianbang.app.AES');
var sig = AuthUtils.aes(str); // context,str组要自己组装
send(sig);
}
)
}
};
'''
def on_message(message, data):
if message['type'] == 'send':
print(message['payload'])
elif message['type'] == 'error':
print(message['stack'])
process = frida.get_remote_device().attach('com.xiaojianbang.app')
script = process.create_script(hook_code)
script.on('message', on_message)
script.load()
script.exports.gethello('edc38cb9-c72d-3bc4-8e82-6fd9212d77a0')
效果如下,直接运用,不需要触发相关函数
0x03 总结
大概我平时用到的脚本就是这些,后期会在这个系列中讲解安卓中漏洞挖掘的思路以及frida在挖掘中的用法
原文始发于微信公众号(剑客古月的安全屋):app攻防-Frida&Hook 系列2
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论