文章总结: 本文讲解JS逆向反混淆练习平台第二题的解题过程,通过抓包分析发现动态cookie字段m,定位混淆代码并还原逻辑。关键发现是m值通过魔改MD5算法计算时间戳生成,文章提供完整Python实现代码,包括自定义MD5算法和请求流程,最终成功获取数据。建议使用魔改浏览器跳过debugger,结合AI工具辅助代码转换提升效率。 综合评分: 78 文章分类: 逆向分析,实战经验,爬虫,WEB安全
JS逆向|逆向反混淆练习平台第二题加密参数并获取数据
原创
悦来客栈的老板 悦来客栈的老板
菜鸟学Python编程
2026年3月29日 21:00 湖北
关注它,不迷路。
- 本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!
为啥不用AI来逆向?因为古法逆向,用的时间更少。
一.题目地址
https://match.yuanrenxue.cn/match/2
二.抓包分析
打开控制台后,抓包分析,停在debugger位置:
当你只是想分析加密参数的接口时,可以使用 魔改的浏览器来跳过这个debugger。
题目说的是动态cookie,使用魔改的浏览器抓包后发现有个 m 字段:
定位到混淆代码,直接彻底还原即可清晰的看到 m 的赋值过程:
这里注意到 _0xd38b9f 函数,它每次返回的时间戳 都是不一样的。
过程:
第一次请求:
https://match.yuanrenxue.cn/api/question/2?page=1&pageSize=10&kw=
这个接口,会返回上面的混淆js,并根据时间戳计算出 m 的值。然后带着 m 的cookie 值再次访问这个接口,就可以拿到正确的data了。
三.请求源码
使用AI将还原的js代码处理Python纯算代码,方便程序调用:
import reimport jsonimport randomimport timeimport requests
session = requests.Session()
session.headers = { "User-Agent": "yuanrenxue",
}
session.cookies.set('sessionid','你的sessionid')
def to_int32(value: int) -> int: value &= 0xFFFFFFFF return value if value < 0x80000000 else value - 0x100000000
def unsigned_rshift(value: int, bits: int) -> int: return (value & 0xFFFFFFFF) >> bits
def safe_add(x: int, y: int) -> int: x = to_int32(x) y = to_int32(y) low = (x & 0xFFFF) + (y & 0xFFFF) high = (x >> 16) + (y >> 16) + (low >> 16) return to_int32((high << 16) | (low & 0xFFFF))
def bit_rol(value: int, shift: int) -> int: value = to_int32(value) return to_int32(((value << shift) & 0xFFFFFFFF) | unsigned_rshift(value, 32 - shift))
def md5_cmn(q: int, a: int, b: int, x: int, s: int, t: int) -> int: return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b)
def md5_ff(a: int, b: int, c: int, d: int, x: int, s: int, t: int) -> int: return md5_cmn((b & c) | (~b & d), a, b, x, s, t)
def md5_gg(a: int, b: int, c: int, d: int, x: int, s: int, t: int) -> int: return md5_cmn((b & d) | (c & ~d), a, b, x, s, t)
def md5_hh(a: int, b: int, c: int, d: int, x: int, s: int, t: int) -> int: return md5_cmn(b ^ c ^ d, a, b, x, s, t)
def md5_ii(a: int, b: int, c: int, d: int, x: int, s: int, t: int) -> int: return md5_cmn(c ^ (b | ~d), a, b, x, s, t)
def str_to_binl(raw: str) -> list[int]: words: list[int] = [] bit_len = 8 * len(raw) for bit_index in range(0, bit_len, 8): word_index = bit_index >> 5 while len(words) <= word_index: words.append(0) words[word_index] = to_int32( words[word_index] | ((ord(raw[bit_index // 8]) & 0xFF) << (bit_index % 32)) ) return words
def binl_to_str(words: list[int]) -> str: chars: list[str] = [] total_bits = 32 * len(words) for bit_index in range(0, total_bits, 8): chars.append(chr(unsigned_rshift(words[bit_index >> 5], bit_index % 32) & 0xFF)) return "".join(chars)
def core_modified_md5(words: list[int], bit_len: int) -> list[int]: words = words[:]
pad_index = bit_len >> 5 while len(words) <= pad_index: words.append(0) words[pad_index] = to_int32(words[pad_index] | (0x80 << (bit_len % 32)))
length_index = 14 + (((bit_len + 64) >> 9) << 4) while len(words) <= length_index: words.append(0) words[length_index] = bit_len while len(words) % 16 != 0: words.append(0)
a = 1732584193 b = -271733879 c = -1732584194 d = 271733878
for i in range(0, len(words), 16): old_a = a old_b = b old_c = c old_d = d
a = md5_ff(a, b, c, d, words[i], 7, -680876936) d = md5_ff(d, a, b, c, words[i + 1], 12, -389564586) c = md5_ff(c, d, a, b, words[i + 2], 17, 606105819) b = md5_ff(b, c, d, a, words[i + 3], 22, -1044525330) a = md5_ff(a, b, c, d, words[i + 4], 7, -176418897) d = md5_ff(d, a, b, c, words[i + 5], 12, 1200080426) c = md5_ff(c, d, a, b, words[i + 6], 17, -1473231341) b = md5_ff(b, c, d, a, words[i + 7], 22, -45705983) a = md5_ff(a, b, c, d, words[i + 8], 7, 1770010416) d = md5_ff(d, a, b, c, words[i + 9], 12, -1958414417) c = md5_ff(c, d, a, b, words[i + 10], 17, -42063) b = md5_ff(b, c, d, a, words[i + 11], 22, -1990404162) a = md5_ff(a, b, c, d, words[i + 12], 7, 1804603682) d = md5_ff(d, a, b, c, words[i + 13], 12, -40341101) c = md5_ff(c, d, a, b, words[i + 14], 17, -1502882290) b = md5_ff(b, c, d, a, words[i + 15], 22, 1236535329) a = md5_gg(a, b, c, d, words[i + 1], 5, -165796510) d = md5_gg(d, a, b, c, words[i + 6], 9, -1069501632) c = md5_gg(c, d, a, b, words[i + 11], 14, 643717713) b = md5_gg(b, c, d, a, words[i], 20, -373897302) a = md5_gg(a, b, c, d, words[i + 5], 5, -701558691) d = md5_gg(d, a, b, c, words[i + 10], 9, 38016083) c = md5_gg(c, d, a, b, words[i + 15], 14, -660478335) b = md5_gg(b, c, d, a, words[i + 4], 20, -405537848) a = md5_gg(a, b, c, d, words[i + 9], 5, 568446438) d = md5_gg(d, a, b, c, words[i + 14], 9, -1019803690) c = md5_gg(c, d, a, b, words[i + 3], 14, -187363961) b = md5_gg(b, c, d, a, words[i + 8], 20, 1163531501) a = md5_gg(a, b, c, d, words[i + 13], 5, -1444681467) d = md5_gg(d, a, b, c, words[i + 2], 9, -51403784) c = md5_gg(c, d, a, b, words[i + 7], 14, 1735328473) b = md5_gg(b, c, d, a, words[i + 12], 20, -1926607734) a = md5_hh(a, b, c, d, words[i + 5], 4, -378558) d = md5_hh(d, a, b, c, words[i + 8], 11, -2022574463) c = md5_hh(c, d, a, b, words[i + 11], 16, 1839030562) b = md5_hh(b, c, d, a, words[i + 14], 23, -35309556) a = md5_hh(a, b, c, d, words[i + 1], 4, -1530992060) d = md5_hh(d, a, b, c, words[i + 4], 11, 1272893353) c = md5_hh(c, d, a, b, words[i + 7], 16, -155497632) b = md5_hh(b, c, d, a, words[i + 10], 23, -1094730640) a = md5_hh(a, b, c, d, words[i + 13], 4, 681279174) d = md5_hh(d, a, b, c, words[i], 11, -358537222) c = md5_hh(c, d, a, b, words[i + 3], 16, -722521979) b = md5_hh(b, c, d, a, words[i + 6], 23, 76029189) a = md5_hh(a, b, c, d, words[i + 9], 4, -640364487) d = md5_hh(d, a, b, c, words[i + 12], 11, -421815835) c = md5_hh(c, d, a, b, words[i + 15], 16, 530742520) b = md5_hh(b, c, d, a, words[i + 2], 23, -995338651) a = md5_ii(a, b, c, d, words[i], 6, -198630844) d = md5_ii(d, a, b, c, words[i + 7], 10, 1126891415) c = md5_ii(c, d, a, b, words[i + 14], 15, -1416354905) b = md5_ii(b, c, d, a, words[i + 5], 21, -57434055) a = md5_ii(a, b, c, d, words[i + 12], 6, 1700485571) d = md5_ii(d, a, b, c, words[i + 3], 10, -1894986606) c = md5_ii(c, d, a, b, words[i + 10], 15, -1051523) b = md5_ii(b, c, d, a, words[i + 1], 21, -2054922799) a = md5_ii(a, b, c, d, words[i + 8], 6, 1873313359) d = md5_ii(d, a, b, c, words[i + 15], 10, -30611744) c = md5_ii(c, d, a, b, words[i + 6], 15, -1560198380) b = md5_ii(b, c, d, a, words[i + 13], 21, 1309151649) a = md5_ii(a, b, c, d, words[i + 4], 6, -145523070) d = md5_ii(d, a, b, c, words[i + 11], 10, -1120210379) c = md5_ii(c, d, a, b, words[i + 2], 15, 718787259) b = md5_ii(b, c, d, a, words[i + 9], 21, -343485441)
a = safe_add(a, old_a) b = safe_add(b, old_b) c = safe_add(c, old_c) d = safe_add(d, old_d)
return [a, b, c, d]
def utf8_to_js_raw(value: str) -> str: return str(value).encode("utf-8").decode("latin1")
def modified_md5_hex(value: str) -> str: raw = utf8_to_js_raw(value) digest = binl_to_str(core_modified_md5(str_to_binl(raw), 8 * len(raw))) hex_chars = "0123456789abcdef" parts: list[str] = [] for ch in digest: code = ord(ch) parts.append(hex_chars[(code >> 4) & 0x0F] + hex_chars[code & 0x0F]) return "".join(parts)
def main() -> None:
pattern = r'return 0x[0-9A-Fa-f]{11}' cookie_url = "https://match.yuanrenxue.cn/api/question/2?page=1&pageSize=10&kw=" res = session.get(cookie_url) match = re.search(pattern, res.text)
if (match): group1 = match.group()
timestamp = int(group1[7:],16)
value = modified_md5_hex(str(timestamp)) + f"|{timestamp}; path=/"
session.cookies.set('m',value)
total = 0 for i in range(1,6): cookie_url = f"https://match.yuanrenxue.cn/api/question/2?page={i}&pageSize=10&kw=" res = session.get(cookie_url) data = res.json()["data"] print (i,res.json()['data']) total +=sum(data) print (total)
if __name__ == "__main__": main()
可以拿到结果:
做这道题,依然用到了AI,已经离不开它了。
今天的分享就到这里,感谢阅读。
欢迎加入知识星球,学习更多AST和爬虫技巧。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:菜鸟学Python编程 悦来客栈的老板 悦来客栈的老板《JS逆向|逆向反混淆练习平台第二题加密参数并获取数据》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论