猿人学安卓逆向对抗比赛-第一题(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()