猿人学APP第一题

发布于:2023-05-22 ⋅ 阅读:(203) ⋅ 点赞:(0)

抓包分析

  • copy CURL 转 requests代码
def app1():
    import requests
    headers = {
        "Accept-Language": "zh-CN,zh;q=0.8",
        "User-Agent": "Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; Nexus 6P Build/OPM1.171019.011) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
        "Host": "www.python-spider.com",
        "Cache-Control": "no-cache"
    }
    url = "https://www.python-spider.com/api/app1"
    data = {
        "page": "1",  # 页码
        "sign": "538f6c31cc41a5154d549b1026b6c7cf",
        "t": "1670468702882" # 时间戳
    }
    response = requests.post(url, headers=headers, data=data)

    print(response.text)
    print(response)
响应
{"status": "1", "state": "success", "data": [{"value": "8080\r"}, {"value": "4988\r"}, {"value": "3842\r"}, {"value": "3520\r"}, {"value": "1500\r"}, {"value": "1237\r"}, {"value": "9936\r"}, {"value": "6209\r"}, {"value": "4303\r"}, {"value": "5807\r"}]}
  • 逆向目标:sign生成

jadx搜索

搜索代码:"sign 搜到类似代码片段,有参数page,t,sign应该就是我们要找的
在这里插入图片描述

右键跳转声明位置(代码位置是一个接口)

sign= new C5334Oooo000().OooO(sb.toString().getBytes(StandardCharsets.UTF_8));

完整加密代码:

public String OooO(byte[] bArr) {
        ArrayList<Integer> OooO0oO2 = OooO0oO(bArr);
        int i = 1732584193;
        int i2 = -271733879;
        int i3 = -1732584194;
        int i4 = 271733878;
        for (int i5 = 0; i5 < OooO0oO2.size() / 64; i5++) {
            int[] iArr = new int[16];
            for (int i6 = 0; i6 < 16; i6++) {
                int i7 = (i5 * 64) + (i6 * 4);
                iArr[i6] = (OooO0oO2.get(i7 + 3).intValue() << 24) | OooO0oO2.get(i7).intValue() | (OooO0oO2.get(i7 + 1).intValue() << 8) | (OooO0oO2.get(i7 + 2).intValue() << 16);
            }
            int[] iArr2 = {0, 4, 8, 12};
            int i8 = i;
            int i9 = i2;
            int i10 = i3;
            int i11 = i4;
            int i12 = 0;
            while (i12 < 4) {
                int i13 = iArr2[i12];
                i8 = OooO0O0(i8, i9, i10, i11, iArr[i13], 3);
                int OooO0O02 = OooO0O0(i11, i8, i9, i10, iArr[i13 + 1], 7);
                i10 = OooO0O0(i10, OooO0O02, i8, i9, iArr[i13 + 2], 11);
                i9 = OooO0O0(i9, i10, OooO0O02, i8, iArr[i13 + 3], 19);
                i12++;
                i11 = OooO0O02;
            }
            int[] iArr3 = {0, 1, 2, 3};
            int i14 = i8;
            int i15 = i11;
            for (int i16 = 0; i16 < 4; i16++) {
                int i17 = iArr3[i16];
                i14 = OooO0Oo(i14, i9, i10, i15, iArr[i17], 3);
                i15 = OooO0Oo(i15, i14, i9, i10, iArr[i17 + 4], 5);
                i10 = OooO0Oo(i10, i15, i14, i9, iArr[i17 + 8], 9);
                i9 = OooO0Oo(i9, i10, i15, i14, iArr[i17 + 12], 13);
            }
            int[] iArr4 = {0, 2, 1, 3};
            int i18 = i14;
            int i19 = 0;
            while (i19 < 4) {
                int i20 = iArr4[i19];
                int OooO0o2 = OooO0o(i18, i9, i10, i15, iArr[i20], 3);
                i15 = OooO0o(i15, OooO0o2, i9, i10, iArr[i20 + 8], 9);
                i10 = OooO0o(i10, i15, OooO0o2, i9, iArr[i20 + 4], 11);
                i9 = OooO0o(i9, i10, i15, OooO0o2, iArr[i20 + 12], 15);
                i19++;
                i18 = OooO0o2;
            }
            i += i18;
            i2 += i9;
            i3 += i10;
            i4 += i15;
        }
        return String.format("%02x%02x%02x%02x", Integer.valueOf(i), Integer.valueOf(i2), Integer.valueOf(i3), Integer.valueOf(i4));
    }
  • 加密逻辑不长,感兴趣的也可直接翻译成python代码
  • 我就不翻译了,直接上frida Hook测试一下

FridaHook

Java.perform(function () {
    console.log('perform seccuss')
    let Oooo000 = Java.use("o00oO00o.Oooo000");
    Oooo000.OooO.implementation = function(s){
        let arr = Java.use("java.util.Arrays")
        let JavaString = Java.use("java.lang.String")
        console.log("args Bytes:",arr.toString(s))
        console.log("args String:", JavaString.$new(s))
        let res = this.OooO(s)
        console.log('res String:',JavaString.$new(res))
        return res
    }
});

启动app,注入测试

attach seccuss
perform seccuss
load seccuss
args Bytes: [112, 97, 103, 101, 61, 49, 49, 54, 55, 48, 57, 56, 55, 57, 52, 57, 49, 49, 55]
args String: page=11670987949117
res String: 67e0adb2756e899f36f6184316562da6
args Bytes: [112, 97, 103, 101, 61, 50, 49, 54, 55, 48, 57, 56, 55, 57, 53, 52, 52, 54, 48]
args String: page=21670987954460
res String: 9eea998e3017f9e244f700a5cd1a0e62
  • 入参为"page=" + 页码 + 时间戳

Frida主动调用

  • 以参数page=11670987949117测试
  • Java.use("o00oO00o.Oooo000").OooO(bArr)直接调用会报错:
    • Error: OooO: cannot call instance method without an instance
  • Java.choose()的方式从内存中搂个实例用,注入时需要进入指定页面触发指定函数,保证内存中已经加载了我们需要的类。

完整代码

Java.perform(function () {
    function stringToBytes(str) {  
        var ch, st, re = []; 
        for (var i = 0; i < str.length; i++ ) { 
            ch = str.charCodeAt(i);  
            st = [];                 
           do {  
                st.push( ch & 0xFF );  
                ch = ch >> 8;          
            }    
            while ( ch );  
            re = re.concat( st.reverse() ); 
        }  
        return re;  
    }
    console.log('perform seccuss')
    let JavaString = Java.use("java.lang.String")
    Java.choose("o00oO00o.Oooo000",{
        onMatch:function(instance){
            console.log('choose seccuss')
            let str1 = "page=11670987949117"
            let intArr = stringToBytes(str1)
            let bArr = Java.array('byte',intArr)
            let res = instance.OooO(bArr)
            console.log('res String:',JavaString.$new(res))        
        },
        onComplete(){}
    });
});

测试结果:

attach seccuss
perform seccuss
choose seccuss
res String: 67e0adb2756e899f36f6184316562da6
load seccuss
  • 和我们上面抓包的结果匹配

FridaRPC

  • 目标函数接收的参数类型为 bytes[]
  • 我们准备的函数为str类型
  • 需要将参数进行String to BytesArray 的转换
    js代码
function app1_sign_func(page, t) {
  var res;
  Java.perform(function () {
    function stringToBytes(str) {
      var ch,
        st,
        re = [];
      for (var i = 0; i < str.length; i++) {
        ch = str.charCodeAt(i);
        st = [];
        do {
          st.push(ch & 0xff);
          ch = ch >> 8;
        } while (ch);
        re = re.concat(st.reverse());
      }
      return re;
    }
    console.log("perform seccuss");
    Java.choose("o00oO00o.Oooo000", {
      onMatch: function(instance){
        console.log("choose seccuss");
        let str1 = "page=" + page + t;
        console.log("str1 =>",str1)
        let intArr = stringToBytes(str1);
        let bArr = Java.array("byte", intArr);
        res = instance.OooO(bArr);
        console.log('res =>',res)
      },
      onComplete:function(){},
    });
  });
  return res;
}

rpc.exports = {
  getsign: app1_sign_func,
};

注入的python代码:

import frida
import sys
import time
import requests

f = open('./js_code.js','r',encoding='utf-8')
jscode = f.read()
f.close()

process = frida.get_usb_device(-1).attach('猿人学APP')
print('attach seccuss')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
print('load seccuss')
api = script.exports
# sys.stdin.read()
 

def app1(page):
    headers = {
        "Accept-Language": "zh-CN,zh;q=0.8",
        "User-Agent": "Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; Nexus 6P Build/OPM1.171019.011) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
        "Host": "www.python-spider.com",
        "Cache-Control": "no-cache"
    }
    url = "https://www.python-spider.com/api/app1"
    t = str(int(time.time()*1000))
    sign = api.getsign(str(page),t)
    data = {
        "page": page,
        "sign": sign,
        "t": t
    }
    print(data)
    response = requests.post(url, headers=headers, data=data)

    print(response.text)
    print(response)

app1(1)

调用结果:

attach seccuss
load seccuss
perform seccuss
choose seccuss
str1 => page=11670997598567
res => 7e8154f39058fa6e585afa2ec48013bf
choose seccuss
str1 => page=11670997598567
res => 7e8154f39058fa6e585afa2ec48013bf
{'page': 1, 'sign': '7e8154f39058fa6e585afa2ec48013bf', 't': '1670997598567'}
{"status": "1", "state": "success", "data": [{"value": "9198\r"}, {"value": "2463\r"}, {"value": "6344\r"}, {"value": "5559\r"}, {"value": "6558\r"}, {"value": "2162\r"}, {"value": "1289\r"}, {"value": "6426\r"}, {"value": "1735\r"}, {"value": "8974\r"}]}
<Response [200]>

结束

  • Frida三板斧完事,收工。
本文含有隐藏内容,请 开通VIP 后查看