目录
一、发起请求
二、观察发现只有入参 __data__ 进行了加密,返回是明文
三、 观察JS调用栈
四、从JS中搜索 __data__
五、使用XHR对Ajax请求进行断点
六、再次发起请求就会断点拦住请求
七、对XHR入口分析
八、逐个栈断点进行查看,还是没有发现可疑之处编辑
九、 重新刷新页面,从JS中搜索__data__进行分析
十、对可疑之处全部打上断点
十一 、溯源加密函数
十二、再次追踪
十三、再再次追踪
十四、整体链路追踪
十五、模拟请求
一、发起请求
二、观察发现只有入参 __data__ 进行了加密,返回是明文
三、 观察JS调用栈
四、从JS中搜索 __data__
发现一个像样的都没有
五、使用XHR对Ajax请求进行断点
六、再次发起请求就会断点拦住请求
七、对XHR入口分析
八、逐个栈断点进行查看,还是没有发现可疑之处
九、 重新刷新页面,从JS中搜索__data__进行分析
重新请求断点并没有断住,往下看,发现类似的疑点有很多处,接下来我们只好把每一处都打上断点
十、对可疑之处全部打上断点
再次发起请求,断点到encrypt函数处。因为是反向追踪,每次必须重新请求,确保调用的数据链是正确的。
这里要记住这个入参的大致形式,咱们要追踪的正是这个入参,是怎么换算成了密文的。
十一 、溯源加密函数
十二、再次追踪
再次发起请求,断点到encrypt函数处。因为是反向追踪,每次必须重新请求,确保调用的数据链是正确的。
十三、再再次追踪
再次发起请求,断点到encrypt函数处。因为是反向追踪,每次必须重新请求,确保调用的数据链是正确的。
断点放过第一次
断点放过第二次
断点放过第三次
断点放过第四次 .....
一直没有找到符合预期的参数链
此时我们发现,network栏一直有接口调用,每次都经过上面断点的函数,导致我即使一直放行,也都无法等到想要的参数链的到来。
十四、整体链路追踪
此时我们只好重新发起请求,对刚刚每一步的追踪都打上断点,然后逐次放行下来,让参数链第一时间断点
function t(e) {
var t = (e = btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g, (function (e, t) {
return String.fromCharCode(parseInt("0x" + t))
}
)))).length / 2;
e.length % 2 !== 0 && (t = e.length / 2 + 1);
for (var n = "", r = 0; r < t; r++)
n += e[r] + e[t + r];
return n
}
const e = {"action":"next","session_id":"c6bfb1e6-c772-4e3c-aabe-1ec3b70efe35","send_msg":[{"msg_type":"user_query","user_query":"你好呀"}],"channel":"chat-web","client_chan":"chatOnCom","parent_id":"3a696901-51e9-47d6-956d-f3b9d520f275","file_ids":[]}
let a = t(JSON.stringify(e));
console.log(a)
十五、模拟请求
import json
import execjs
import requests
js_code = """
function t(e) {
var t = (e = btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g, (function (e, t) {
return String.fromCharCode(parseInt("0x" + t))
}
)))).length / 2;
e.length % 2 !== 0 && (t = e.length / 2 + 1);
for (var n = "", r = 0; r < t; r++)
n += e[r] + e[t + r];
return n
}
function get__data__(message) {
const e = {
"action": "next",
"session_id": "",
"send_msg": [{"msg_type": "user_query", "user_query": message}],
"channel": "chat-web",
"client_chan": "chatOnCom",
"parent_id": "0",
"file_ids": []
}
return t(JSON.stringify(e))
}
"""
# 编译JavaScript代码
ctx = execjs.compile(js_code)
# 执行JavaScript代码并获取参数加密结果
result = ctx.call("get__data__", "你知道詹姆斯在NBA多少年了吗")
url = "https://chat.sensetime.com/api/richmodal/v1.0.2/chat"
payload = {
"__data__": result}
headers = {
'authorization': 'Bearer 你的TOKEN',
'debug': 'undefined',
'priority': 'u=1, i',
'system-type': 'web',
'version-code': '',
'x-request-id': 'eb9eeb23-6db5-439a-9b48-531d9de87b2c',
'Cookie': 'UM_distinctid=190e93d52b8520-0bcaa0440d727f-26001f51-1fa400-190e93d52b9a8f; CNZZDATA1281349177=866722293-1721900029-https%253A%252F%252Fgithub.com%252F%7C17219100029',
'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
'content-type': 'application/json;charset=UTF-8'
}
response = requests.request("POST", url, headers=headers, data=json.dumps(payload))
# 直接输出text中文乱码了
# print(response.text)
# 这里进行主动解码一下
print(response.content.decode('utf-8'))