猿人学第2题「js混淆-动态cookie」解题记录
猿人学第2题「js混淆-动态cookie」解题记录
题目链接:https://match.yuanrenxue.cn/match/2
难度:入门偏基础 · 一句话概括:页面 JS 动态生成一个带时效的 cookiem(md5|时间戳),请求数据接口时必须带上,否则拿不到数据。
一、题目目标与规则
- 请求全部 5 页数据,每页 10 个值,共 50 个值,计算这 50 个值的加和。
- 第 5 页请求时 UA 要改成
yuanrenxue。 - 请求必须携带
sessionid,每个已登录用户的数字答案不同。
二、抓包与接口分析
打开题目页面,切到 Network,先正常点一次「获取数据」或翻页,能看到数据接口:
GET https://match.yuanrenxue.cn/api/question/2?page=1&pageSize=10&kw=
请求参数:
| 参数 | 说明 |
|---|---|
page |
页码,1 ~ 5 |
pageSize |
每页条数,固定 10 |
kw |
关键字,本题留空 |
关键 Cookie:
m:动态生成,格式为<md5>|<时间戳>,例如0be2ff4275383c6a9a0a0a7060c639a8|1775462964474sessionid:登录后的会话凭证,每个用户不同,必须带上
响应结构(JSON):
{
"state": "success",
"data": [值1, 值2, ..., 值10]
}
data 是一个长度为 10 的数组,把 5 页的 data 全部加起来就是答案。
如果 m 缺失、格式不对、或时间戳与 md5 不匹配,接口会返回错误状态(拿不到 data)。
三、逆向思路
1. 定位 cookie 的生成位置
打开题目页,cookie m 不是服务器下发的,而是页面 JS 动态写入的。在页面里搜索 cookie 或者 m= 相关逻辑,能找到生成 m 的代码。核心逻辑非常直接:
m = MD5(当前毫秒时间戳) + "|" + 当前毫秒时间戳
也就是说,m 由两部分拼接,中间用竖线 | 分隔:
- 前半段:当前毫秒时间戳做一次标准 MD5 得到的 32 位小写十六进制串;
- 后半段:同一个毫秒时间戳本身。
服务器收到后,会用竖线后面的时间戳重新算一次 MD5,与竖线前面的 md5 比对,一致才放行。这正是「动态 cookie」的校验点。
2. 还原混淆后的 MD5
页面里给出的 MD5 实现是被混淆过的:变量名变成了 _0x2a4cc9、_0x5d0afa 这类十六进制风格的名称,代码被压成一大坨。但仔细观察结构,能认出它就是一个标准 MD5 的经典实现:
1732584193、-271733879、-1732584194、271733878是 MD5 的 4 个初始向量;- 四轮循环里的常量
-680876936、-389564586、606105819……是 MD5 的标准正弦常量; <<、>>>、|、&组合是 MD5 的循环移位与轮函数。
把变量名还原、去掉无意义的 if (1) { ... } else { ... } 死代码后,整理成 env.js,暴露一个 get(t) 函数:
function get(t) {
return _0x502edc(t); // 即 MD5(t),返回 32 位小写 hex
}
get(t) 接收一个时间戳(数字),返回它的 MD5 值。文件里保留了原始的 _0x 命名(去混淆后直接可跑),重点是 get 这个入口函数。
3. Python 侧调用
Python 每次请求前:
- 取
ti = int(time.time() * 1000)得到当前毫秒时间戳; - 用
execjs调用get(ti)得到 md5; - 拼成 cookie:
m = md5 + "|" + str(ti); - 立即发出请求。
这样 md5 和竖线后的时间戳来自同一个 ti,保证同源匹配。
四、核心代码
a.py(execjs 调用 + 每页重新生成 m + 求和)
import requests
import time
import execjs
def get_data(t, m_, page):
headers = {
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"cache-control": "no-cache",
"pragma": "no-cache",
"priority": "u=1, i",
"referer": "https://match.yuanrenxue.cn/match/2",
"sec-ch-ua": "\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Google Chrome\";v=\"146\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36",
"x-requested-with": "XMLHttpRequest"
}
cookies = {
"Hm_lvt_434c501fe98c1a8ec74b813751d4e3e3": "1773750584",
"sessionid": "frzna2wyl0oh1grr2ut761ejtf03a20i",
"Hm_lvt_f80b2b389f44bbfb3bfe1704817d44e0": "1773750388,1775317756,1775386530,1775462871",
"Hm_lpvt_f80b2b389f44bbfb3bfe1704817d44e0": "1775462871",
"HMACCOUNT": "00959BC5EB881F83",
# "m": "0be2ff4275383c6a9a0a0a7060c639a8|1775462964474",
'm': m_ + '|' + str(t)
}
url = "https://match.yuanrenxue.cn/api/question/2"
params = {
"page": str(page),
"pageSize": "10",
"kw": ""
}
response = requests.get(url, headers=headers, cookies=cookies, params=params)
print(response.json())
print(response)
return sum(response.json().get("data"))
with open('env.js', 'r', encoding='utf-8') as f:
a = f.read()
b = execjs.compile(a)
s = 0
for i in range(1, 5):
ti = int(time.time() * 1000)
m = b.call('get', ti)
s += get_data(ti, m, i)
def get_data(t, m_, page):
headers = {
"accept": "application/json, text/javascript, */*; q=0.01",
"accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"cache-control": "no-cache",
"pragma": "no-cache",
"priority": "u=1, i",
"referer": "https://match.yuanrenxue.cn/match/2",
"sec-ch-ua": "\"Chromium\";v=\"146\", \"Not-A.Brand\";v=\"24\", \"Google Chrome\";v=\"146\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "yuanrenxue",
"x-requested-with": "XMLHttpRequest"
}
cookies = {
"Hm_lvt_434c501fe98c1a8ec74b813751d4e3e3": "1773750584",
"sessionid": "frzna2wyl0oh1grr2ut761ejtf03a20i",
"Hm_lvt_f80b2b389f44bbfb3bfe1704817d44e0": "1773750388,1775317756,1775386530,1775462871",
"Hm_lpvt_f80b2b389f44bbfb3bfe1704817d44e0": "1775462871",
"HMACCOUNT": "00959BC5EB881F83",
# "m": "0be2ff4275383c6a9a0a0a7060c639a8|1775462964474",
'm': m_ + '|' + str(t)
}
url = "https://match.yuanrenxue.cn/api/question/2"
params = {
"page": str(page),
"pageSize": "10",
"kw": ""
}
response = requests.get(url, headers=headers, cookies=cookies, params=params)
print(response.json())
print(response)
return sum(response.json().get("data"))
ti = int(time.time() * 1000)
m = b.call('get', ti)
s += get_data(ti, m, 5)
print(s)
说明:上面
a.py里get_data定义了两遍是有意为之。Python 是顺序执行的——for i in range(1, 5)这个循环位于第二个get_data定义之前,所以前 4 页(page 1~4)调用的是第一个get_data(普通 Chrome UA);循环结束后才定义第二个get_data(UA 为yuanrenxue),第 5 页调用的是第二个版本。这样恰好实现了「前 4 页和第 5 页的 UA 区分」。如果自己重写,建议用if page == 5来切换 UA,更清晰。
env.js(还原后的 MD5,暴露 get(t))
function _0x515028(_0x2a4cc9, _0x2fd680, _0x441e15, _0x1a024b, _0x132ce7, _0x293790, _0x15e09a) {
return _0x57529e(_0x441e15 ^ (_0x2fd680 | ~_0x1a024b), _0x2a4cc9, _0x2fd680, _0x132ce7, _0x293790, _0x15e09a);
}
function _0x478b78(_0x3f0b00, _0x395755, _0x3ddb00, _0x5292d8, _0x412914, _0x45d586, _0x1fbac6) {
return _0x57529e(_0x395755 ^ _0x3ddb00 ^ _0x5292d8, _0x3f0b00, _0x395755, _0x412914, _0x45d586, _0x1fbac6);
}
function _0x302504(_0x309b89, _0x188a45, _0x3aa948, _0x3dfe05, _0x52e64a, _0x2e353d, _0x27c963) {
return _0x57529e(_0x188a45 & _0x3dfe05 | _0x3aa948 & ~_0x3dfe05, _0x309b89, _0x188a45, _0x52e64a, _0x2e353d, _0x27c963);
}
function _0x5e49b9(_0x5674bf, _0x48d35e) {
return _0x5674bf << _0x48d35e | _0x5674bf >>> 32 - _0x48d35e;
}
function _0x26c01(_0x2461f0, _0x3e0025) {
var _0x42175b = (65535 & _0x2461f0) + (65535 & _0x3e0025);
return (_0x2461f0 >> 16) + (_0x3e0025 >> 16) + (_0x42175b >> 16) << 16 | 65535 & _0x42175b;
}
function _0x57529e(_0x1a802e, _0x361283, _0x1abf85, _0x146325, _0x197acd, _0x346085) {
return _0x26c01(_0x5e49b9(_0x26c01(_0x26c01(_0x361283, _0x1a802e), _0x26c01(_0x146325, _0x346085)), _0x197acd), _0x1abf85);
}
function _0x5d0afa(_0x2fca0b, _0x260646, _0x1283b0, _0x3df4a5, _0x1d67fd, _0x1d3d99, _0x3b9cd3) {
return _0x57529e(_0x260646 & _0x1283b0 | ~_0x260646 & _0x3df4a5, _0x2fca0b, _0x260646, _0x1d67fd, _0x1d3d99, _0x3b9cd3);
}
function _0x25e8eb(_0x1c7699) {
var _0x2c4f37,
_0x30269a,
_0x44c5b7 = "0123456789abcdef",
_0x501090 = "";
for (_0x30269a = 0; _0x30269a < _0x1c7699["length"]; _0x30269a += 1) _0x2c4f37 = _0x1c7699["charCodeAt"](_0x30269a), _0x501090 += _0x44c5b7["charAt"](_0x2c4f37 >>> 4 & 15) + _0x44c5b7["charAt"](15 & _0x2c4f37);
return _0x501090;
}
function _0x43e4c6(_0x6b9888) {
var _0x31cd16,
_0x30aebc = "",
_0x34684d = 32 * _0x6b9888["length"];
for (_0x31cd16 = 0; _0x31cd16 < _0x34684d; _0x31cd16 += 8) _0x30aebc += String["fromCharCode"](_0x6b9888[_0x31cd16 >> 5] >>> _0x31cd16 % 32 & 255);
return _0x30aebc;
}
function _0x128ddc(_0x30bf4f, _0xb0f1f) {
_0x30bf4f[_0xb0f1f >> 5] |= 128 << _0xb0f1f % 32, _0x30bf4f[14 + (_0xb0f1f + 64 >>> 9 << 4)] = _0xb0f1f;
if (1) {
var _0x168c9d,
_0x478290,
_0x208876,
_0x56f67c,
_0x472fe1,
_0x754dea = 1732584193,
_0x40c927 = -271733879,
_0x1a2e8c = -1732584194,
_0x1e9c99 = 271733878;
} else {
var _0x168c9d,
_0x478290,
_0x208876,
_0x56f67c,
_0x472fe1,
_0x754dea = 0,
_0x40c927 = -0,
_0x1a2e8c = -0,
_0x1e9c99 = 0;
}
for (_0x168c9d = 0; _0x168c9d < _0x30bf4f["length"]; _0x168c9d += 16) _0x478290 = _0x754dea, _0x208876 = _0x40c927, _0x56f67c = _0x1a2e8c, _0x472fe1 = _0x1e9c99, _0x754dea = _0x5d0afa(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d], 7, -680876936), _0x1e9c99 = _0x5d0afa(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 1], 12, -389564586), _0x1a2e8c = _0x5d0afa(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 2], 17, 606105819), _0x40c927 = _0x5d0afa(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 3], 22, -1044525330), _0x754dea = _0x5d0afa(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 4], 7, -176418897), _0x1e9c99 = _0x5d0afa(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 5], 12, 1200080426), _0x1a2e8c = _0x5d0afa(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 6], 17, -1473231341), _0x40c927 = _0x5d0afa(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 7], 22, -45705983), _0x754dea = _0x5d0afa(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 8], 7, 1770010416), _0x1e9c99 = _0x5d0afa(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 9], 12, -1958414417), _0x1a2e8c = _0x5d0afa(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 10], 17, -42063), _0x40c927 = _0x5d0afa(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 11], 22, -1990404162), _0x754dea = _0x5d0afa(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 12], 7, 1804603682), _0x1e9c99 = _0x5d0afa(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 13], 12, -40341101), _0x1a2e8c = _0x5d0afa(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 14], 17, -1502882290), _0x40c927 = _0x5d0afa(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 15], 22, 1236535329), _0x754dea = _0x302504(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 1], 5, -165796510), _0x1e9c99 = _0x302504(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 6], 9, -1069501632), _0x1a2e8c = _0x302504(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 11], 14, 643717713), _0x40c927 = _0x302504(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d], 20, -373897302), _0x754dea = _0x302504(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 5], 5, -701558691), _0x1e9c99 = _0x302504(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 10], 9, 38016083), _0x1a2e8c = _0x302504(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 15], 14, -660478335), _0x40c927 = _0x302504(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 4], 20, -405537848), _0x754dea = _0x302504(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 9], 5, 568446438), _0x1e9c99 = _0x302504(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 14], 9, -1019803690), _0x1a2e8c = _0x302504(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 3], 14, -187363961), _0x40c927 = _0x302504(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 8], 20, 1163531501), _0x754dea = _0x302504(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 13], 5, -1444681467), _0x1e9c99 = _0x302504(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 2], 9, -51403784), _0x1a2e8c = _0x302504(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 7], 14, 1735328473), _0x40c927 = _0x302504(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 12], 20, -1926607734), _0x754dea = _0x478b78(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 5], 4, -378558), _0x1e9c99 = _0x478b78(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 8], 11, -2022574463), _0x1a2e8c = _0x478b78(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 11], 16, 1839030562), _0x40c927 = _0x478b78(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 14], 23, -35309556), _0x754dea = _0x478b78(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 1], 4, -1530992060), _0x1e9c99 = _0x478b78(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 4], 11, 1272893353), _0x1a2e8c = _0x478b78(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 7], 16, -155497632), _0x40c927 = _0x478b78(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 10], 23, -1094730640), _0x754dea = _0x478b78(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 13], 4, 681279174), _0x1e9c99 = _0x478b78(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d], 11, -358537222), _0x1a2e8c = _0x478b78(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 3], 16, -722521979), _0x40c927 = _0x478b78(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 6], 23, 76029189), _0x754dea = _0x478b78(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 9], 4, -640364487), _0x1e9c99 = _0x478b78(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 12], 11, -421815835), _0x1a2e8c = _0x478b78(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 15], 16, 530742520), _0x40c927 = _0x478b78(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 2], 23, -995338651), _0x754dea = _0x515028(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d], 6, -198630844), _0x1e9c99 = _0x515028(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 7], 10, 1126891415), _0x1a2e8c = _0x515028(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 14], 15, -1416354905), _0x40c927 = _0x515028(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 5], 21, -57434055), _0x754dea = _0x515028(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 12], 6, 1700485571), _0x1e9c99 = _0x515028(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 3], 10, -1894986606), _0x1a2e8c = _0x515028(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 10], 15, -1051523), _0x40c927 = _0x515028(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 1], 21, -2054922799), _0x754dea = _0x515028(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 8], 6, 1873313359), _0x1e9c99 = _0x515028(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 15], 10, -30611744), _0x1a2e8c = _0x515028(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 6], 15, -1560198380), _0x40c927 = _0x515028(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 13], 21, 1309151649), _0x754dea = _0x515028(_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99, _0x30bf4f[_0x168c9d + 4], 6, -145523070), _0x1e9c99 = _0x515028(_0x1e9c99, _0x754dea, _0x40c927, _0x1a2e8c, _0x30bf4f[_0x168c9d + 11], 10, -1120210379), _0x1a2e8c = _0x515028(_0x1a2e8c, _0x1e9c99, _0x754dea, _0x40c927, _0x30bf4f[_0x168c9d + 2], 15, 718787259), _0x40c927 = _0x515028(_0x40c927, _0x1a2e8c, _0x1e9c99, _0x754dea, _0x30bf4f[_0x168c9d + 9], 21, -343485441), _0x754dea = _0x26c01(_0x754dea, _0x478290), _0x40c927 = _0x26c01(_0x40c927, _0x208876), _0x1a2e8c = _0x26c01(_0x1a2e8c, _0x56f67c), _0x1e9c99 = _0x26c01(_0x1e9c99, _0x472fe1);
return [_0x754dea, _0x40c927, _0x1a2e8c, _0x1e9c99];
}
function _0x3e99a0(_0x51c7b5) {
var _0x1c9c19,
_0xcf3eff = [];
for (_0xcf3eff[(_0x51c7b5["length"] >> 2) - 1] = undefined, _0x1c9c19 = 0; _0x1c9c19 < _0xcf3eff["length"]; _0x1c9c19 += 1) _0xcf3eff[_0x1c9c19] = 0;
var _0x392110 = 8 * _0x51c7b5["length"];
for (_0x1c9c19 = 0; _0x1c9c19 < _0x392110; _0x1c9c19 += 8) _0xcf3eff[_0x1c9c19 >> 5] |= (255 & _0x51c7b5["charCodeAt"](_0x1c9c19 / 8)) << _0x1c9c19 % 32;
return _0xcf3eff;
}
function _0x109b3b(_0x3a92bb) {
return _0x43e4c6(_0x128ddc(_0x3e99a0(_0x3a92bb), 8 * _0x3a92bb["length"]));
}
function _0x2fc1d1(_0x158ba2) {
return unescape(encodeURIComponent(_0x158ba2));
}
function _0x1d227d(_0x58b9cc) {
return _0x109b3b(_0x2fc1d1(_0x58b9cc));
}
function _0x38f2f1(_0x8d4c0e) {
return _0x25e8eb(_0x1d227d(_0x8d4c0e));
}
function _0x502edc(_0x251460, _0x5537d6, _0xf632ac) {
return _0x38f2f1(_0x251460);
}
function get(t) {
return _0x502edc(t)
}
五、踩坑记录
| 序号 | 坑 | 说明 / 正确做法 |
|---|---|---|
| 1 | m 强时效 |
必须「生成后立即请求」,不要提前生成再慢慢请求,时间戳一过期服务器就不认了。 |
| 2 | md5 与时间戳不同源 | 竖线两边的值必须用同一个 t:md5 = MD5(t)、`m = md5 + " |
| 3 | 第 5 页 UA | 前 4 页用普通 Chrome UA,第 5 页要改成 yuanrenxue,否则第 5 页数据拿不到。 |
| 4 | 别忘 sessionid |
接口需要登录态,sessionid 必须带上,且每个用户不同,答案也不同。 |
六、总结
这道题的考点是「JS 混淆 + 动态 cookie 校验」:页面把标准 MD5 混淆后用于生成带时效的 m cookie。还原 MD5、理清 m = md5|timestamp 的格式后,Python 侧用 execjs 每次请求前重新生成并立即请求即可。整体逆向量不大,是一道非常适合入门 JS 逆向和 cookie 分析的题。

浙公网安备 33010602011771号