第一步 准备工具

1.charles 抓包工具
2.pixelxl 真机
3.jadx
4.本机安装 python 和 frida

抓包分析数据

第三题依旧是计算 1~100也的数值之和
在这里插入图片描述
通过抓包可以 获取到 post 提交的路径

https://appmatch.yuanrenxue.com/app3

post form 表单数据 有两个参数
在这里插入图片描述

m 为 加密的数据
page 为 页数

jadx 分析

直接 搜索 /app3 可以获取到 唯一匹配值
在这里插入图片描述
然后 依旧是 双击进入,找到 url 路由定义的类
在这里插入图片描述
右键 查找 用例 可以看到有三个

前两个是一样的,直接第一个双击进入
在这里插入图片描述
可以看到一个 crypto 加密方法 直接 Ctrl + 鼠标左键进入

在这里插入图片描述
发现 也是一个 so 层的加密函数 ,那么 和 第二题一样,直接 frida hook 一下这个 函数 ,查看一下 函数 传入的值是啥

注意一点,这里有两个参数 ,一个是String 一个是long
所以在 hook的时候,记住 加入 overload

代码如下

function main(){
    console.log("hooking.......")
    Java.perform(function(){
        var crypto = Java.use("com.yuanrenxue.match2022.fragment.challenge.ChallengeThreeFragment");
        crypto.crypto.overload('java.lang.String', 'long').implementation = function(arg1,arg2){
            console.log("args1=>",arg1);
            console.log("args2=>",arg2);
            var result = this.crypto(arg1,arg2);
            console.log(result);
            return result;
        }
    });
}

setImmediate(main);

在这里插入图片描述
可以看到的是

arg1 => 0051657273703000
args2=> 1657273703000
可以猜一下
arg1 应该是 005 的page 页数 + 13位的时间戳
arg2 就是13为的时间戳

可以重新在滑动一下手机,跳转到第六页试试看
在这里插入图片描述
欸,好像没毛病!

那么就简单了,我们主动调用试试看

主动调用

代码如下


function invokesign(str,long){
    var result = null;
    Java.perform(function(){
        Java.choose("com.yuanrenxue.match2022.fragment.challenge.ChallengeThreeFragment",{
            onMatch:function(ins){
                console.log('ins=>',ins);
                result = ins.crypto(str,long);
                console.log("result=>",result);
                
            },onComplete(){}
        })
    });
    return result;
}

效果如下

在这里插入图片描述
欸,好像没啥问题,那么就直接 rpc 一波试试看

frida rpc 调用

代码如下

function main(){
    console.log("hooking.......")
    Java.perform(function(){
        var crypto = Java.use("com.yuanrenxue.match2022.fragment.challenge.ChallengeThreeFragment");
        crypto.crypto.overload('java.lang.String', 'long').implementation = function(arg1,arg2){
            console.log("args1=>",arg1);
            console.log("args2=>",arg2);
            var result = this.crypto(arg1,arg2);
            console.log(result);
            return result;
        }
    });
}

setImmediate(main);
//invokesign("0041657273677000",1657273677000)
function invokecrypto(str,long){
    var result = null;
    Java.perform(function(){
        Java.choose("com.yuanrenxue.match2022.fragment.challenge.ChallengeThreeFragment",{
            onMatch:function(ins){
                console.log('ins=>',ins);
                result = ins.crypto(str,long);
                console.log("result=>",result);
                
            },onComplete(){}
        })
    });
    return result;
}

rpc.exports = {
    invokecrypto:invokecrypto,
}

python 代码如下

import time
import frida
import requests

from requests.packages import urllib3
 
urllib3.disable_warnings()

def my_message_handler(message, payload):
    print("message=>",message)
    print("payloa=>d",payload)


# connect wifiadb
device = frida.get_device_manager().add_remote_device("192.168.0.102:8888")
print('设备=>',device)

session = device.attach("com.yuanrenxue.match2022")
print('session=>',session)

# load script
with open("app3.js") as f:
    script = session.create_script(f.read())

script.on("message", my_message_handler)
script.load()

# script.exports.invokecrypto("0041657273677000",1657273677000)

def get_url():
    num = 0
    for i in range(1,101):
        url = 'https://appmatch.yuanrenxue.com/app3'
        headers = {
            'accept-language': 'zh-CN,zh;q=0.8',
            'user-agent': 'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; Pixel XL Build/OPM1.171019.011) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30',
            'content-type': 'application/x-www-form-urlencoded',
            'accept-encoding': 'gzip',
            'cache-control': 'no-cache'
        }
        data = {
            'page':str(i),
        }
        ts = int(time.time())*1000
        if i <10:
            data['m'] = script.exports.invokecrypto(str('00'+str(i)+str(ts)),ts)
        elif 10 <=i and i <100:
            data['m'] = script.exports.invokecrypto(str('0'+str(i)+str(ts)),ts)
        elif i >= 100:
            data['m'] = script.exports.invokinvokecryptoesign(str(str(i)+str(ts)),ts)

        print('data->',data)
        response = requests.post(url,headers=headers,data=data,verify=False)
        print(response.text)
        value_data = response.json()
        for value in value_data['data']:
            num += int(value['value'])
        print(num)

        time.sleep(1)
    # print(num)
if __name__ == '__main__':
    get_url()

    

最终的效果

在这里插入图片描述
在这里插入图片描述

总结

so 层的混淆和 不混淆 其实 不太重要,只要是静态注册的,就可以直接通过hook java的 静态的注册的方法 找到函数 传入的数据进行分析
然后直接进行主动调用即可,不需要管SO层里面的算法进行了多么离谱的混淆加密

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐