网址:aHR0cHM6Ly9zcGlkZXJkZW1vLmNuL29iL29iX2NoYWxsZW5nZTEvP2NoYWxsZW5nZV90eXBlPW9iX2NoYWxsZW5nZTE=
接口:
定位就非常好定位
然后进入md5函数,这里已经确认过加了盐
找到盐值即可
py
import hashlib
def get_hex_md5_cracked(input_string):
"""
还原混淆 JS 中的 hex_md5 逻辑
"""
# 1. 从混淆代码中逆向出的固定盐值
# \xa3\xac\xa1\xa3 对应特定的扩展 ASCII 字符
salt = "\xa3\xac\xa1\xa3fdjf,jkgfkl"
# 2. 拼接输入字符串和盐值
plain_text = input_string + salt
# 3. 计算 MD5
# 通常网页端 JS 默认编码为 UTF-8
md5_hash = hashlib.md5(plain_text.encode('utf-8')).hexdigest()
return md5_hash
# 测试示例
# 假设 JS 传入的参数是 "123456"
# print(get_hex_md5_cracked("123456"))
但是这样写会有一个问题
这是一个非常经典的问题。导致结果不一致的原因不是"盐值"错了,而是**字符编码(Encoding)**的问题。
核心原因分析
- JavaScript 的处理方式 :
在该混淆 JS 的 MD5 实现中,它会取字符串中每个字符的charCodeAt()值,并将其截断为低8位(0-255)。
代码中的盐值包含\xa3(£),其 ASCII/Unicode 码点是 163 。JS MD5 库会直接把它当作一个字节0xA3处理。 - Python
utf-8的处理方式(上次代码的错误点) :
在 Python 中,\xa3是 Unicode 字符。如果你使用.encode('utf-8'),它会被编码成两个字节 :0xC2和0xA3。
这导致了哈希的输入内容变了,所以结果完全不同。 - 解决方法 :
必须使用latin-1(ISO-8859-1) 编码。这种编码方式会把0-255范围内的 Unicode 字符直接映射为单字节,与 JS 那个老旧 MD5 库的行为完全一致。
修正后的 Python 代码
请使用下面的代码,我修正了编码部分:
python
import hashlib
import time
def get_challenge_sign(page, timestamp=None):
# 1. 还原混淆代码中的盐值 (注意:这些是扩展ASCII字符)
salt = "\xa3\xac\xa1\xa3fdjf,jkgfkl"
# 2. 如果没有提供时间戳,生成一个(模拟 JS 的 new Date().getTime())
if timestamp is None:
timestamp = int(time.time() * 1000)
# 3. 拼接字符串:timestamp + page + salt
# JS逻辑: `${timestamp}${page}` + salt
plain_text = f"{timestamp}{page}{salt}"
# 4. 【关键步骤】使用 latin-1 编码,而不是 utf-8
# 这样 \xa3 (163) 才会变成单字节 b'\xa3',而不是双字节 b'\xc2\xa3'
input_bytes = plain_text.encode('latin-1')
# 5. 计算 MD5
sign = hashlib.md5(input_bytes).hexdigest()
return sign, timestamp
# --- 验证环节 ---
# 假设我们在 JS 控制台手动测试,固定以下输入:
# timestamp = 1735200000000 (示例时间戳)
# page = 1
# JS 逻辑: hex_md5("17352000000001") -> 预期结果
# 输入字符串实际为: "17352000000001" + "\xa3\xac\xa1\xa3fdjf,jkgfkl"
test_ts = 1735200000000
test_page = 1
sign, _ = get_challenge_sign(test_page, test_ts)
print(f"输入参数: page={test_page}, timestamp={test_ts}")
print(f"生成的 sign: {sign}")
# 如果你的 JS 控制台结果是 "c32b12ac...",说明你当时的 timestamp 肯定不是我上面造的这个。
# 你可以用这行 Python 代码去验证你控制台里报错的那组数据(确保 timestamp 和 page 一致)。
为什么加上 encode('latin-1') 就对了?
- **JS 里的
\xa3**:被视为单字节0xA3(十进制 163)。 - **Python
utf-8**:\xa3->b'\xc2\xa3'(两个字节,导致 MD5 错乱)。 - **Python
latin-1**:\xa3->b'\xa3'(一个字节,与 JS 一致)。