猿人学安卓逆向对抗比赛-第一题(JAVA层加密)

JAVA层加密

抓包

证书导入(charles同理)

先安装为用户证书(如下)

然后将证书导入系统

adb shell 
su
cd /data/misc/user/0/cacert-added
mount -o remount,rw /system
cp * /etc/security/cacerts/
chmod 777 /etc/security/cacerts/*

请求报文

模拟器设置代理,打开第一关,下拉刷新

请求报文

POST https://appmatch.yuanrenxue.com/app1 HTTP/1.1
Accept-Language: zh-CN,zh;q=0.8
User-Agent: Mozilla/5.0 (Linux; U; Android 7.1.2; zh-cn; SM-N976N Build/QP1A.190711.020) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Content-Type: application/x-www-form-urlencoded
Content-Length: 55
Host: appmatch.yuanrenxue.com
Connection: Keep-Alive
Accept-Encoding: gzip
Cache-Control: no-cache

page=1&sign=eacbc038f554358249f45fbe842dfc&t=1658142626

代码分析

根据/app1在jadx搜索


右键查找用例

前两个进入任意一个

右键sign跳到声明

com.yuanrenxue.match2022.security.Sign

hookcom.yuanrenxue.match2022.security.Sign获取传参与返回值

sign()的参数为page=page(页数)+时间戳

知道具体的传参就可以主动调用获取返回值

代码实现

js代码

//字符串转字节序列
function stringToByte(str) {
    var bytes = new Array();
    var len, c;
    if (str){
        len = str.length;
        for(var i = 0; i < len; i++) {
            c = str.charCodeAt(i);
            if(c >= 0x010000 && c <= 0x10FFFF) {
                bytes.push(((c >> 18) & 0x07) | 0xF0);
                bytes.push(((c >> 12) & 0x3F) | 0x80);
                bytes.push(((c >> 6) & 0x3F) | 0x80);
                bytes.push((c & 0x3F) | 0x80);
            } else if(c >= 0x000800 && c <= 0x00FFFF) {
                bytes.push(((c >> 12) & 0x0F) | 0xE0);
                bytes.push(((c >> 6) & 0x3F) | 0x80);
                bytes.push((c & 0x3F) | 0x80);
            } else if(c >= 0x000080 && c <= 0x0007FF) {
                bytes.push(((c >> 6) & 0x1F) | 0xC0);
                bytes.push((c & 0x3F) | 0x80);
            } else {
                bytes.push(c & 0xFF);
            }
        }
    }
    return bytes;
}
//主动调用sign函数
var a
var yy
function main(a) {
 console.log("Script loded successfully")
 console.log(a)
    Java.perform(function () {
        console.log("Inside java perform function")
        var Sign = Java.use('com.yuanrenxue.match2022.security.Sign')//对指定的类名动态的获取这个类的JavaScript引用
        console.log("Java.use.successfully") //定位类
        var asinn = Sign.$new()   //创建实例
        yy = asinn.sign(stringToByte(a))
        console.log(yy) //定位类
    })
    return yy
}
rpc.exports = {
    main: main
}

rpc调用

"""
第一关 JAVA 层加密
"""
import frida ,time ,sys
import requests
# from requests.packages import urllib3
def on_message(message,data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

def get_url():
    device = frida.get_usb_device(timeout=1000)  # 获取USB设备句柄
    process = device.attach('com.yuanrenxue.match2022')  # 注入进程
    print(process)

    with open('02.js', encoding='utf-8') as f:
        jscode = f.read()

    script = process.create_script(jscode)  # 加载js代码
    script.on('message', on_message)  # 监控任何来自目标进程的消息
    script.load()
    print('load js ok')
    num = 0
    for i in range(1,101):
        url = 'https://appmatch.yuanrenxue.com/app1'
        headers = {
            'accept-language': 'zh-CN,zh;q=0.8',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.47',
            'content-type': 'application/x-www-form-urlencoded',
            'accept-encoding': 'gzip',
            'cache-control': 'no-cache'
        }
        data = {
            'page':str(i),
            't': str(int(time.time()))
        }
        data['sign'] = script.exports.main('page='+data['page']+data['t'])
        print(data)
        response = requests.post(url,headers=headers,data=data,verify=False)
        print(response.json())
        value_data = response.json()
        for value in value_data['data']:
            num += int(value['value'])
        print(num)
        time.sleep(1)
if __name__ == '__main__':
    get_url()
posted @ 2022-09-02 13:11  JKding233  阅读(312)  评论(0编辑  收藏  举报