- 破解进度: 服务端不校验 cw 内容, 随机 4146B cw 即可 200 + 签发新 t2/t5 - 生成流程: 零设备注册链 getDfpConfig->selectOperator->dfpReport 打法 - tools/dfp_gen.py: cw/body 构建器 (TAF 4226B 结构) - tools/dfp_cli.py: 注册链 CLI - evidence: cw JSON 段/collection 段抓取样本
4.4 KiB
4.4 KiB
dfpReport 生成流程与逻辑(逆向推演总账)
目标:讲清楚 dfpReport 上报数据"每一步怎么生成"的完整链路。 已破解部分(黑纸白字)+ 待逆向部分(用 ⚠️ 标出)。
一、dfpReport 是什么
虎牙 huyaudb 风控的"设备行为上报"请求,POST 到 wsapi.huya.com:443 /,用腾讯 taf/wup 协议封装。
请求体(body)= taf 容器,内含若干 tag 字段,其中 tag2 是核心密文区(整个设备+行为报文的加密载荷)。
二、请求体生成的完整流程(逻辑推理)
第 1 步:准备明文 JSON(554B)——【已完全破解】
{"appId":"5008","appVer":"13.4.22","appkey":"865a...cbb0e3",
"channel":"xiaomi","deviceId":"02df...9389","deviceName":"M2102J2SC",
"hdid":"7c5387...85ee","heightPixels":"2120",
"systemVer":"M2102J2SC,30,11","widthPixels":"1080", ...}
来源:
appId/appVer/sdkVer/channel= App 编译期/运行期常量deviceName/systemVer= Android build propswidthPixels/heightPixels= 屏幕分辨率(运行期查询)hdid/deviceId/appkey= ⚠️ 设备三元组,这是核心待逆向项(见第三节)
第 2 步:准备 collection ↓ 数据集(大 JSON,每轮变化)——【部分破解,算法待逆向】
一个 ~3400B 的大 JSON,含动态行为数据:
touch_events(触摸事件时间/坐标)net_intfs(网络接口状态)phoneInfo(设备/系统信息汇总)qimei16/36(⚠️ 设备指纹 App 的标识,逆向目标)risk_apps(已安装的风险 App,如 magisk)scanned_appname(⚠️ ~2900B 二进制扫描结果)Poseidon_*反 frida 检测字段(读 /proc/self/maps 等检测 hook)
⚠️ collection 的构建逻辑(App 怎么采这些数据、怎么格式化)是"生成流程"里最大的一块未破解,但注意:验证已证明 collection 不参与服务端设备身份匹配(改它只影响"动态/静态"判定,不动 hdid)。
第 3 步:组合成明文平文本(pa)——【已知结构,精确边界待确认】
明文输入 ≈ JSON(554B) + collection(3420B) [顺序/分隔待最终确认]
第 4 步:XOR 加密(逐字节 keystream)——【算法已破解,种子待逆】
tag2 = [魔数 10B 57 18 82 cf 66 4b b3 94 01 ee] + [XOR密文]- keystream 逐字节 XOR 明文 → 密文
- 魔数恒定(明文头 XOR 固定值)
- keystream 每会话动态 → ⚠️ 种子(时间戳/会话随机+密钥)+ 生成函数待逆向
第 5 步:封装 taf/wup + 加密通信
body 各 tag 打包(taf 编码)→ POST wsapi.huya.com:443 /(TLS),Content-Type: application/octet-stream,i-ver: 1,User-Agent: okhttp/3.14.9。
第 6 步:服务端校验(已通过差分实验定论)
- 服务端解密 tag2 → 解析明文 JSON 三元组(hdid/deviceId/appkey)+ collection
- 三元组在设备库 + collection 完整 → 回显设备 hdid(actionV)
- 否则 → 动态随机 token(拒绝)
三、核心待逆向项(按"生成流程"重要性排序)
3.1 设备三元组(hdid/deviceId/appkey)怎么来【最关键】
已知:
- 是真设备派生(
pm clear不变,跨会话稳定) - 长度 40hex(hdid/deviceId)、32hex(appkey),像 hash 输出
- libhydeviceid.so 内有 MD5 实现(ror#7 @0xc37c0)+ SHA1 + hex 表 ⚠️ 待逆向:
- 从哪些硬件/系统信息(AndroidID/IMEI/build/serial?)派生
- 用哪个 hash(MD5/SHA1/自实现)
- 掺什么盐/固定密钥
3.2 collection 的完整构建逻辑
- 哪些数据源、如何采集、如何序列化、顺序
3.3 keystream 的种子与生成函数
- 种子来源(时间戳?线程随机?会话 ID?)
- 生成器(自实现伪随机?流密码?)
四、验证里"能做什么"的现实
已确认(纯 Python 可做):
forge_replay.py:任意帧真实 wire → XOR 差分改明文三元组 → 重放,HTTP 200(服务端接受,只是认不认设备问题)- 捕获比:任何一帧真实 ks 即可加密任意伪造明文(不需要生成器)
五、逆向"生成流程"的推荐路径(hook 而非纯静态)
由于 libhydeviceid.so 是 OLLVM 混淆,纯静态难。推荐用 frida 在生成点 hook,抓真实输入输出:
- hook 三元组派生:hook MD5(0xc37c0 附近)/ hex 表使用处,抓 hash 输入 → 反推三元组
- hook 加密函数入口:抓 keystream 生成函数输入(种子)
- hook collection 构建函数:抓各字段组装点
但 attach/spawn 反调试都强(已验证 attach 6/6 死,spawn 3-6s 死),给 hook 点逆向带来现实障碍