猿人学APP02实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
function stringToByte(str) {
const bytes = [];
let len, c;
len = str.length;
for (let 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;
}

function byteToString(arr) {
if (typeof arr === 'string') {
return arr;
}
let str = '',
_arr = arr;
for (let i = 0; i < _arr.length; i++) {
const one = _arr[i].toString(2),
v = one.match(/^1+?(?=0)/);
if (v && one.length === 8) {
const bytesLength = v[0].length;
let store = _arr[i].toString(2).slice(7 - bytesLength);
for (let st = 1; st < bytesLength; st++) {
store += _arr[st + i].toString(2).slice(2);
}
str += String.fromCharCode(parseInt(store, 2));
i += bytesLength - 1;
} else {
str += String.fromCharCode(_arr[i]);
}
}
return str;
}


function data(str, timestamp) {
let result = {}
Java.perform(function () {

const NativeLib = Java.use('com.yuanrenxue.challenge.two.NativeLib');
const byteArray = Java.array('byte', stringToByte(str))
const Base64 = Java.use("android.util.Base64")

try {

const rawData = NativeLib.encrypt(byteArray, timestamp)
console.log("test result: " + rawData);

const base64EncodedData = Base64.encodeToString(rawData, 10)

result.rawData = rawData
result.base64EncodedData = base64EncodedData


} catch (e) {
console.log(e)
}
})

return result

}

rpc.exports = {
data: data
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# server.py
import json

import frida
from flask import Flask, request

hook = open('data.js', 'r', encoding='utf-8').read()


def on_message(message, data):
if message['type'] == 'send':
print(f"send message:{message['payload']}")
elif message['type'] == 'error':
print(message['stack'])


deviceManage = frida.get_usb_device()
front_app = deviceManage.get_frontmost_application()

print("===正在运行的应用为:", front_app)
process = deviceManage.attach(front_app.pid)

script = process.create_script(hook)
script.on('message', on_message)
script.load()

app = Flask(__name__)


@app.route('/getdata', methods=['POST']) # data解密
def getsign():
data = request.get_data()
json_data = json.loads(data.decode("utf-8"))

page = json_data.get("page")
timestamp = json_data.get('timestamp')
s = str(page) + ":" + str(timestamp)
res = script.exports.data(s, timestamp)
return res


if __name__ == '__main__':
app.run()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# client.py
import json
import time

import requests

url = 'http://127.0.0.1:5000/getdata'
data_url = 'https://www.python-spider.com/api/app2'

headers = {
'user-agent': "Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; Nexus 6P Build/OPM7.181105.004) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'

}

s = []

for i in range(1, 101):
timestamp = int(round(time.time() * 1000))

data1 = {"page": i, "timestamp": timestamp}

getData = requests.post(url, json=data1).json()
print(getData)

data = {"data": getData['base64EncodedData']}

res = requests.post(data_url, data=data, headers=headers).text

content = json.loads(res)
s.extend([i['value'].strip('\r') for i in content['data']])
print(sum(int(i) for i in s))


猿人学APP02实战
https://kingjem.github.io/2022/07/17/猿人学/猿人学APP02实战/
作者
Ruhai
发布于
2022年7月17日
许可协议