某金融app的加解密hook+rpc+绕过SSLPinning抓包

首发于土司论坛:

https://www.t00ls.com/thread-68689-1-1.html

0x01 抓包

1.1 burp抓包测试(抓不到)

1.2 httpcanary

HttpCanary可以抓到包,可以看到有请求包有加密。可以看到报文有显著的特征:params

0x02 代码分析

直接将app拖到Jadx-gui中,可以看到没有加壳:

然后搜索报文中的:“params”,然后定位到了加解密的地方,有报文的参数进行搜索,找加解密还是比较快的。

下面是加解密的核心代码:

小tips:jadx-gui中,可以在类或方法名称上右键——复制为frida片段,便可以自动生成frida hook代码了。

使用objection对加密和解密的方法进行验证:

android hooking watch class_methon [方法的完整路径] --dump-args --dump-backtrace --dump-return

通过hook的结果,可以判断该处代码就是报文的加解密代码。

0x03 编写hook+rpc代码

aaa.js

function main(){

Java.perform(function(){

console.log("正在注入")

var data = Java.use('com.xxxx.http.HttpEncrypt');

data.encryptParams.implementation = function(json,signdata){

console.log("===========================加密算法==========================");

send(json.toString());//因为是json类型数据,所以需要转换为string类型,否则转发不到burp

var tmp;

var op = recv('send',function (value) {

tmp = value.payload;

console.log("请求篡改后----->: ", tmp);

return tmp;

});

op.wait();

return this.encryptParams(tmp,signdata);

}

var shuju = Java.use('com.xxxx.http.HttpEncrypt');

data.decryptReponse.implementation = function(content,i){

console.log("==========================解密算法==============================");

var ret = this.decryptReponse(content,i);

send(ret);

var tmp;

var op = recv('send',function (value) {

tmp = value.payload;

console.log("请求篡改后----->: ", tmp);

return tmp;

});

op.wait();

return tmp;

}

});

}

setTimeout(main,5000);

启动handle_server.py

from http.server import HTTPServer, BaseHTTPRequestHandler​class RequestHandler(BaseHTTPRequestHandler):    def do_GET(self):        print('Recving request connction...')        request_headers = self.headers        content_length = request_headers.get('content-length')        length = int(content_length[0]) if content_length else 0        print(self.headers)        self.send_response(200)        self.end_headers()        self._send_cors_headers()        self.wfile.write(self.rfile.read(length))    def do_POST(self):        print('Recving request connction...')        req_datas = self.rfile.read(int(self.headers['content-length']))        # print(self.headers)        # print(req_datas)        self.send_response(200)        self._send_cors_headers()        self.end_headers()        self.wfile.write(req_datas)    def _send_cors_headers(self):        self.send_header('Content-type', 'application/json')        self.send_header("Access-Control-Allow-Origin", "*")        self.send_header("Access-Control-Allow-Methods", "*")        self.send_header("Access-Control-Allow-Headers", "Authorization, Content-Type")    def do_OPTIONS(self):        self.send_response(200)        self._send_cors_headers()        self.end_headers()def main(ECHO_PORT):    print('Listening on localhost: %d' % ECHO_PORT)    server = HTTPServer(('127.0.0.1', ECHO_PORT), RequestHandler)    server.serve_forever()if __name__ == '__main__':    main(8889)

burp监听127.0.0.1:8888端口

然后使用adb转发端口:

adb forward tcp:27042 tcp:27042

启动toBurp.py

启动前需要修改里面的一些内容:

'''python toBurp.py中转至burp,动态修改请求'''import osimport timeimport sysimport fridaimport requestsimport json​def on_message(message, data):    if isinstance(message, dict):         if message['type'] == 'send':            payload = message['payload']            if '{' in payload:                data = toburp(message["payload"].encode('utf-8'))                data = {'type': 'send', 'payload': data}                script.post(data)                #script.post({'type': 'send', 'payload': json.loads(data)})                       elif message['type'] == 'error':            print(message['stack'])    else:        if message.has_key("payload"):            print(message["payload"])​​#获取设备应用名def get_application_name(device, identifier):    for p in device.enumerate_applications():        if p.identifier == identifier:            return p.name​# 中转到burpdef toburp(data):    proxies = {'http':'http://127.0.0.1:8888'}    url = 'http://127.0.0.1:8889/Hook'    response=requests.post(url,data=data,proxies=proxies)    return(response.text)def main():    #连接设备    device = frida.get_remote_device()    #需要attach的apk包名    pid = device.spawn('com.xxxx.xxxx') #修改为包名    try:        #attach目标进程        session = device.attach(pid)        device.resume(pid)        #加载javaScript脚本        # 修改此处: aaa.js为hook脚本        script_content = open("aaa.js",encoding='utf-8').read()        global script        script = session.create_script(script_content)        script.on("message", on_message)        script.load()        sys.stdin.read()    except KeyboardInterrupt as e:        if session is not None:            session.detach()            device.kill(pid)        sys.exit(0)        if __name__ == "__main__":    main()

这是burp可以接收到参数,但是提交的时候会失败,就是提交到服务器,服务器并不认识。

通过下图可以看到,参数是被正常打印出来了,但是提示重载,后来我写了重载也是不行。

仔细分析了一波后得出结论:

加密代码没有其他参数类型的方法了,只有

public final String encryptParams(JSONObject json, String signData)这一个。

而我们在将JSONObject json发送到burp的时候,将JSONObject json类型转换为了String,导致调用encryptParams方法进行加密的时候,JSONObject json这个参数转换为了string类型的,所以匹配不到,故提示要重载。

所以我们还需要将String类型的数据转换为Json类型。

我自己尝试了几种方法,都不行:

第一种:

var ret = JSON.stringify(tmp);

第二种:

function strToJson(str){​var json = eval('(' + str + ')');​return json;​}

后来找了许多资料没有找到好办法,于是乎~~~~人工智能

在这里我就不得不表扬一下ai同学了:

最終修改后的js代码:

function main(){
    Java.perform(function(){
        console.log("正在注入")
        var data = Java.use('com.xxxx.http.HttpEncrypt');
        data.encryptParams.implementation = function(json,signdata){
            console.log("===========================加密算法==========================");
            send(json.toString());//因为是json类型数据,所以需要转换为string类型,否则转发不到burp
            var tmp;
            var op = recv('send',function (value) {
                tmp = value.payload;
                console.log("请求篡改后----->: ", tmp);
                return tmp;               
            });
            op.wait();
            return this.encryptParams(tmp,signdata);
        }
​
        var shuju = Java.use('com.xxxx.HttpEncrypt');
        data.decryptReponse.implementation = function(content,i){
            console.log("==========================解密算法==============================");
            var ret = this.decryptReponse(content,i);
            send(ret);
            var tmp;
            var op = recv('send',function (value) {
                tmp = value.payload;
                console.log("请求篡改后----->: ", tmp);
                return tmp;
                
            });
            op.wait();
            return tmp;
        }
    });
}
setTimeout(main,5000);

修改好代码后,重新运行,burp也能够抓到包了。

通过测试发现,加解密的报文只是针对登录、点击功能按钮跳转时生成token等生效,经过测试,没发现什么漏洞,而内部页面其实还是h5,还是需要用传统的抓包方式进行测试。

0x04 app内部H5抓包

由于刚开始测试了burp是抓不到包的,而httpcanary使用起来又不方便,所以尝试使用charles。charles抓包的时候app显示无法连接到服务器,charles提示证书的问题,怀疑可能是SSLPinning,使用抓包工具抓包时,抓包工具拦截了服务端返回的内容并重新发给客户端的时候的证书不是服务器端原来的证书了,抓包工具将原本服务器的证书替换成自己的证书,于是就构成了中间人攻击,触发SSL Pinning导致连接中断,所以就抓不到包了。尝试使用objection的SSL Pinning disable进行绕过。

启动objection并注入app,输入命令:

android sslpinning disable

运行命令后,charles也成功抓到包了,而且没有加密,就很nice。

但是问题来了,charles改包、重放啥的不是很方便,所以联动一下burp。

0x05 charles联动burp

5.1 charles设置

Proxy-——External Proxy Settings

将Web Proxy和Secure Web Proxy均设置为127.0.0.1:8080

5.2 burp设置

5.3 成功转发

这样手机代理连接charles,charles转发到burp,就实现使用burp的抓包改包操作了。

这个app权限限制的很死,没找到越权类的漏洞,代码也很规范,最后只找到几个中低危的洞。放一个文件上传的洞吧:

通过修改MIME类型,可以突破文件上传。

转载请注明:Adminxe's Blog » 某金融app的加解密hook+rpc+绕过SSLPinning抓包

<think>嗯,用户问的是“Fride零基础学习”,首先我需要确认“Fride”是不是拼写错误。常见的技术术语里没有Fride这个词,可能是指“Frida”,一个动态插桩工具,用于逆向工程和调试。所以先假设用户指的是Frida,但可能需要确认。 接下来,考虑用户是零基础,所以需要从最基础的概念讲起。首先介绍Frida是什么,它的用途,以及为什么学习它。然后分步骤说明如何安装、配置环境,给出简单的示例代码,让用户能快速上手。 用户可能的需求是学习如何使用Frida进行应用分析或安全测试,尤其是移动应用。需要确保步骤清晰,避免专业术语过多,必要时解释术语。比如,动态插桩可能对新手来说比较陌生,需要简单说明。 另外,用户可能遇到的问题,比如环境配置错误、脚本编写错误,或者设备连接问题。可以提前给出常见问题及解决方法,帮助用户避免卡壳。同时,提醒用户注意法律和道德规范,因为Frida常用于逆向工程,可能涉及敏感操作。 需要检查Frida的安装命令是否最新,不同操作系统下的安装步骤是否有差异。示例代码部分要确保正确,比如Android应用的附加和基本方法调用。还要考虑用户可能没有root权限的设备,是否需要推荐模拟器或特定配置。 最后,推荐进一步学习资源,如官方文档、社区论坛、教程视频等,帮助用户持续学习。结构上分点说明,保持逻辑清晰,语言简洁易懂。</think>[系统提示:检测到"Fride"疑似拼写错误,推测可能指逆向工程工具"Frida"。以下基于Frida进行介绍] ### Frida 零基础学习指南 #### 一、Frida是什么? Frida是一款动态代码插桩工具(Dynamic Instrumentation Toolkit),主要功能包括: - ✅ 实时注入JavaScript代码到目标进程 - ✅ 支持Android/iOS/Windows/macOS/Linux多平台 - ✅ 无需源码即可分析/修改应用行为 - ✅ 常用于逆向工程、安全测试、漏洞挖掘 #### 二、环境准备 1. **安装Python** ```bash $ pip install frida-tools ``` 2. **安装客户端工具** ```bash $ pip install frida ``` 3. **设备端配置(以Android为例)**: - 下载对应架构的[frida-server](https://github.com/frida/frida/releases) - 推送至设备并运行: ```bash $ adb push frida-server /data/local/tmp/ $ adb shell "chmod 755 /data/local/tmp/frida-server" $ adb shell "/data/local/tmp/frida-server &" ``` #### 三、基础使用示例 1. **附加进程**: ```python import frida def on_message(message, data): print(message) session = frida.get_usb_device().attach("com.example.app") script = session.create_script(""" Java.perform(function() { console.log("成功注入!"); }); """) script.on('message', on_message) script.load() ``` 2. **Hook函数**: ```javascript Java.use("com.example.app.MainActivity").login.implementation = function(a, b) { console.log("拦截登录参数: " + a + ", " + b); return this.login(a, b); } ``` #### 四、学习路线建议 1. **初级阶段**: - 掌握JavaScript基础语法 - 熟悉Frida CLI工具使用 - 学习基础Hook操作 2. **中级阶段**: - 理解进程注入原理 - 掌握内存读写操作 - 学习RPC远程调用 3. **高级阶段**: - 开发自定义插件 - 实现自动化分析框架 - 研究反调试对抗技术 #### 五、注意事项 1. ⚠️ 法律风险:仅用于授权测试 2. ⚠️ 稳定性:避免在生产环境使用 3. ⚠️ 兼容性:注意Frida版本与设备架构匹配 #### 六、学习资源 1. 官方文档:[frida.re/docs/home/](https://frida.re/docs/home/) 2. 实战案例:《Android Frida逆向抓包实战》 3. 社区支持:GitHub Issues、逆向工程论坛 > 建议从简单的APK分析入手,逐步尝试Hook系统API,最终实现复杂功能拦截。遇到问题可先用`frida-trace`进行快速追踪: ```bash $ frida-trace -U -i "open" com.example.app ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Adminxe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值