frida版本要求对应一致
电脑端安装Firda模块
pip install frida
pip install frida-tools
手机端下载服务端
Releases · frida/frida
adb shell getprop ro.product.cpu.abi #adb查看手机架构
下载对应的 frida-server
#push到手机
adb push frida-server-16.7.0-android-x86_64 /data/local/tmp
#给权限后运行
chmod 777 frida-server-16.7.0-android-x86_64
./frida-server-16.7.0-android-x86_64
电脑端配置端口转发
#方法一 用cmd
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
#方法二 用python
import subprocess
subprocess.getoutput("adb forward tcp:27042 tcp:27042")
subprocess.getoutput("adb forward tcp:27043 tcp:27043")
# 枚举手机上的所有进程 & 前台进程
import frida
# 获取设备信息
rdev = frida.get_remote_device()
# 枚举所有的进程
processes = rdev.enumerate_processes()
for process in processes:
print(process)
# Process(pid=5852, name="拼多多", parameters={}) 进程id号,应用名字,应用包名(后面会用到)
# Process(pid=7489, name="com.google.android.gms.unstable", parameters={})
print('-----------------')
# 获取在前台运行的APP
front_app = rdev.get_frontmost_application()
print(front_app)
如果报错,大概率是没有做端口转发
开启车智赢然后放到前台运行上面的脚本
Application(identifier="com.che168.autotradercloud", name="车智赢+", pid=8555, parameters={})
这里我们搜索关键词 LOGIN_URL
找到了密码登录的函数
然后我们看一下加密函数的代码
public static final String encodeMD5(String str) {
char[] cArr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
try {
byte[] bytes = str.getBytes();
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(bytes);
byte[] digest = messageDigest.digest();
char[] cArr2 = new char[digest.length * 2];
int i = 0;
for (byte b : digest) {
int i2 = i + 1;
cArr2[i] = cArr[(b >>> 4) & 15];
i = i2 + 1;
cArr2[i2] = cArr[b & TType.m];
}
return new String(cArr2).toLowerCase();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
现在我要hook encodeMD5
这个方法
scr = """
Java.perform(function () {
//找到类 反编译的首行+类名:com.autohome.ahkit.utils下的
var SecurityUtil = Java.use("com.autohome.ahkit.utils.SecurityUtil");
//替换类中的方法
SecurityUtil.encodeMD5.implementation = function(str){ console.log("参数:",str);
var res = this.encodeMD5(str); //调用原来的函数
console.log("返回值:",res);
return res; }});
"""
最后的脚本
import subprocess
import frida
import sys
# 连接手机设备
subprocess.getoutput("adb forward tcp:27042 tcp:27042")
subprocess.getoutput("adb forward tcp:27043 tcp:27043")
rdev = frida.get_remote_device()
# 包名:com.che168.autotradercloud
# 车智赢+
session = rdev.attach("车智赢+")
scr = """
Java.perform(function () {
//找到类 反编译的首行+类名:com.autohome.ahkit.utils下的
var SecurityUtil = Java.use("com.autohome.ahkit.utils.SecurityUtil");
//替换类中的方法
SecurityUtil.encodeMD5.implementation = function(str){ console.log("参数:",str);
var res = this.encodeMD5(str); //调用原来的函数
console.log("返回值:",res);
return res; }});
"""
script = session.create_script(scr)
def on_message(message, data):
print(message, data)
script.on("message", on_message)
script.load()
sys.stdin.read()
这里我们就Hook了 encodeMD5
方法,
我们可以尝试随便输入一个表单进行登录
可以发现我们能够接受到参数与返回值
那个很长一串的参数是其他地方调用的这个方法
这里我将会通过hook把返回值由md5变成明文
现在这个我传入参数 123456
返回值是 md5(123456)
我将return 修改成 str
这里的 str
就是我传入的值
然后抓包看看返回值是多少
这里就变成了我们传入的参数,而不是 123456
的md5值了
方式适应场景:Attach 方式是在目标应用程序已经运行的过程中动态地连接并注入 Frida 的 Agent 代码(app运行后再hook)
缺点: 不能hook,app一运行时就执行的方法
方式适应场景:Spawn 方式是在目标应用程序启动时直接注入 Frida 的 Agent 代码(app运行后重启然后注入)
spanw方案是在app运行一开始就hook--》它能hook更早期的方法
attach方案,在app运行后,再进行hook--》只能hook,某个操作对应的方法
发送验证码抓包
获取到了请求地址
https://miappshop.jshulin.com/memberLogin/phoneCode?phone=xxxx&serviceType=6
简单写过python脚本
import requests
phone = input("请输入手机号: ")
url = f"https://miappshop.jshulin.com/memberLogin/phoneCode?phone={phone}&serviceType=6"
headers={
"user-agent":"123"
}
res = requests.get(url,headers=headers)
print(res.text) # 打印返回的响应内容