一.前言
今天也是讲最后一个基础知识点了,ptrace占坑,这个也算是一个坑,今天通过这个案例和大家讲一下,今天这个案例我们来整验证码登录,版本选择4.7.8
二.抓包分析
抓包发现,请求头里的东西通过改包发现都是可以破的,需要破的其实就是这个请求体里面的sign,那我们现在就来反编译找到sign
三.找到sign的加密位置
我们搜索sign发现太多了,所以我们可以搜索请求体的其他参数,g7timestamp
发现第二个特别像回事,我们点进去
这不正是将请求体参数进行拼接,然后sign对其进行加密,然后再拼接进去吗,那我们再点进去
发现是对加密进行url编码吗?主要加密逻辑是.a那我们再点进去
这个是不是似曾相识,进行hmacsha1加密然后转成base64格式,但是得注意的是这个是hmacsha1,sha1不一样,我一开始也以为是sha1,以为是传的两个参数一个是盐,其实hmacsha1需要一个key,大家读名字也就知道了
但是我们不选择hook这个函数,而是选择hook上一层的a,查看四个字符串是啥,这样比较容易看
四.HOOK以及ptrace占坑
我们需要hook的是这个,这里给出hook代码
import frida
import sys
# 连接手机设备
rdev = frida.get_remote_device()
session = rdev.attach("司小宝")
scr = """
Java.perform(function () {var p0 = Java.use("cmt.chinaway.com.lite.s.i1");p0.a.implementation = function (str, str2, str3,str4) {console.log("---------------------")console.log('参数是:',str, str2, str3,str4);var res = this.a(str, str2, str3,str4);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()
发现一运行就报错
这个报错是说进程被占用,那现在就是我们的frida的端口被占用了,这就是我们今天要讲的知识点
4.1 查看app运行进程id号
方式一:手机端启动frida-server
-电脑端执行:frida-ps -U -a # 可以看到id号,hook时候,可以使用id号
方式二:进入到手机中
adb shell
su
ps -A |grep lite # 包名可以简写
问题:
明明发现司小宝在运行,但是就是hook不到
发现车智赢在运行,能hook到
4.2 ptrace占坑
这个就是frida反调试的一种,我们之前学过两种,删除so文件,换用hluda,这次就是 ptrace占坑,什么是ptrace占坑呢?
ptrace可以让一个进程监视和控制另一个进程的执行,并且修改被监视进程的内存、寄存器等,主要应用于调试器的断点调试、系统调用跟踪等--》frida调试,就是基于这种方式来实现的
在Android app保护中,ptrace被广泛用于反调试【frida基于ptrace】。一个进程只能被ptrace一次,如果先调用了ptrace方法,那就可以防止别人调试我们的程序。这就是传说中的先占坑。
一个进程只能被一个进程附加,为了防止frida的附加,程序中自己先基于ptrace附加自己,我们如果后期使用frida去附加app时,就会报错了
我们发现没有冒号的两个,而其中一个名字是 __skb_wait_for_more_packets
解决方法一:kill掉
我们操作一遍发现,直接kill杀不到,那我们强制kill -9 杀掉就会强制退出,所以一定是内部做了进程监听,我们所以得使用另一个方法,但是后续有的app可以用这个方法
解决方法二:spawn方案
解决方法三:后期学习aosp刷机,修改aosp源码--》让app自己的附加进程启动失败--》编译刷入到手机中,即可解决这个问题
那我们作为基础肯定是用方法二,这里给出新的hook代码
import frida
import sys
#spwan 自动运行
rdev = frida.get_remote_device()
pid = rdev.spawn(["cmt.chinaway.com.lite"]) #这里添加的是包名
session = rdev.attach(pid)scr = """
Java.perform(function () {var p0 = Java.use("cmt.chinaway.com.lite.s.i1");p0.a.implementation = function (str, str2, str3,str4) {console.log("---------------------")console.log('参数是:',str, str2, str3,str4);var res = this.a(str, str2, str3,str4);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()
rdev.resume(pid)
sys.stdin.read()
那不就知道了么四个参数是啥,key就是 1KMrg0dfufc0wpnXEJacEQX1YEUYA0Ja
str2 + "\n" + str3 + "\n/" + str4进行处理
再进行 HmacSHA1加密,这很简单,我给出生成代码
import hmac
import base64
from hashlib import sha1def sign(g7timestamp):try:secret_key="1KMrg0dfufc0wpnXEJacEQX1YEUYA0Ja"content=f"""POST\n{g7timestamp}\n/v2/isnb-openapi-proxy/auth/router"""# 1 秘钥secret_key = secret_key.encode()# 创建hmac对象,指定使用sha1算法mac = hmac.new(secret_key, digestmod=sha1)# 2 待加密明文mac.update(content.encode('utf-8'))# 生成HMAC并进行Base64编码hmac_result = mac.digest()base64_result = base64.b64encode(hmac_result)# 返回Base64编码后的结果return base64_result.decode()except Exception as e:raise Exception(f"Failed to generate HMAC : {e}")if __name__ == '__main__':res=sign('1717765476740')print(res)
接下来登陆的话抓个包发现加密也是这个sign,我就不和大家讲了
五.总结
今天主要是讲了ptrace占坑,啥难度都没,简简单单对不对,明天就要和大家讲重头戏了,也就是介绍unidbg,这个会有几天的课程,讲完我们的app逆向基础就先告一段落了
补充
有需要源码的看我主页签名名字私信我,有求必应