carcabot/tiktok-xgnarly-decoded

GitHub: carcabot/tiktok-xgnarly-decoded

对 TikTok X-Gnarly 请求签名的完整逆向工程,提供纯 JavaScript 的编码器和解码器实现,帮助研究人员理解和分析该签名机制的每一个细节。

Stars: 2 | Forks: 1

# tiktok-xgnarly-decoded 对 TikTok 的 `X-Gnarly` 请求签名的完整逆向工程,包含可用的纯 JavaScript 参考编码器和解码器。无需原生绑定,无需无头浏览器,无需混淆包——传输格式的每一个字节都已解析。 ## 什么是 X-Gnarly? `X-Gnarly` 是 TikTok 的 Web 客户端(`webmssdk` / `secsdk`)附加到 API 调用上的请求参数。它是一个类似 base64 的数据块(当前的 ZTCA payload 大小约为 332 个字符),包含: - 一个包含 16 个字段的 TLV payload(时间戳、计数器、URL/body/UA 的 MD5、SDK 版本、两个随机 uint32,以及一个将所有整数联系在一起的 XOR header), - 由 48 个随机字节作为密钥生成的 ChaCha 风格流密码输出,这 48 个字节本身通过校验和计算的偏移量嵌入到了密文中, - 一个开头的魔数(Magic byte)(`'K'` = 75),以便解码器可以快速失败。 本仓库详细介绍了每一个步骤,并提供了一个大小适中、足够在一个下午阅读完毕的实现。 ## 涵盖的版本 X-Gnarly 签名已在多个内部版本标签下发布。本项目追踪了以下完整范围内的传输格式;`src/` 中的参考实现与 **5.1.3-ZTCA** 逐字节对应。 **X-Gnarly payload 版本(TLV 字段 9):** - `5.1.3-ZTCA` *(当前版本 — 本仓库的参考向量)* - `5.1.3` - `5.1.2` - `5.1.1` - `5.1.0` - `5.0.x` **观察到携带 X-Gnarly 的 `webmssdk` 宿主包版本:** - `webmssdk 1.0.0.211` - `webmssdk 1.0.0.224` - `webmssdk 1.0.0.368` *(`encode.js` 中的默认 `sdkVersion`)* - `webmssdk 1.0.0.4xx` - `webmssdk 2.0.0.485` - `webmssdk 2.0.0.485-ZTCA` 在我们观察到的从 `1.0.0.211` 到 `2.0.0.485-ZTCA` 的每一个 `webmssdk` 构建版本中,自定义 base64 字母表、魔数(`'K'` / 75)和 ChaCha 核心一直**保持稳定**。TLV 字段集和轮次推导方案才是不断演进的部分。 ## 相关的 TikTok 签名参数 对于通过搜索引擎来到这里的读者——X-Gnarly 是 TikTok 的 Web 和移动端技术栈发出的几种签名之一。它们*不可*互换,但经常在流量抓包中同时出现,并且可以使用相同的逆向工程技术: | Header / param | Surface | 说明 | |---|---|---| | `X-Gnarly` | web (`webmssdk`) | 本仓库。ChaCha-XOR + TLV。 | | `X-Bogus` | web (`acrawler`) | 前身;类 AES + base64。 | | `X-Argus` | 移动端 | Protobuf payload,原生库。 | | `X-Ladon` | 移动端 | 基于 `X-Khronos` + sec_device_id 的 XOR。 | | `X-Khronos` | 移动端 | Unix 时间戳。 | | `X-Gorgon` | 移动端(旧版) | 基于 MD5,在较新的构建版本中已弃用。 | | `X-Mssdk-Info` | web | 来自 `webmssdk` 的配套遥测数据。 | | `X-TT-Params` | web | AES-128-CBC 加密的查询字符串。 | | `msToken` | web + 移动端 | 服务器颁发的防重放 token。 | | `ttwid` | web | 基于 Cookie 的会话/设备 ID。 | 此处仅实现了 `X-Gnarly`。 ## 快速开始 ``` import { encode, decode } from "./src/encode.js"; const xgnarly = encode( // queryString: the URL's `?...` portion, minus the leading '?', // with msToken substituted in and X-Bogus / X-Gnarly stripped. "aid=1988&app_language=en&...", // body: empty string for GET, the raw body for POST. "", // navigator.userAgent at sign time. "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...", // secsdk request counters; small ints are fine off-page. { totalXHRRequests: 3, totalFetchRequests: 1 }, ); const { fields, keyStart, rounds } = decode(xgnarly); console.log(fields[9]); // "5.1.3-ZTCA" console.log(fields[10]); // "1.0.0.368" ``` 运行往返 + 已知向量测试: ``` node --test test/ ``` ## 项目结构 ``` src/ alphabet.js custom base64 alphabet used by webmssdk cipher.js ChaCha-style stream cipher + round derivation payload.js 16-field TLV encoder / decoder encode.js producer (encode → cipher → embed key → base64) decode.js consumer (base64 → recover key by brute-force keyStart → decrypt → parse) test/ roundtrip.test.mjs encode → decode round-trip on synthetic inputs vectors.test.mjs decode of a real captured X-Gnarly with field-by-field assertions examples/ verify-real.mjs pretty-print a captured X-Gnarly's fields ``` ## TLV 字段参考 | # | 类型 | 含义 | |---|---|---| | 0 | uint | XOR header(所有整数字段的异或结果,**最后**写入) | | 1 | uint | 常量 `65` | | 2 | uint | `ubcode` — 端点类别(`/api/post/...` 的默认值为 `4`) | | 3 | str | MD5(queryString) — 十六进制 | | 4 | str | MD5(body) — 十六进制;GET 请求时为 `""` | | 5 | str | MD5(userAgent) — 十六进制 | | 6 | uint | `floor(now / 1000)` — Unix 秒数 | | 7 | uint | 写入 SDK 的构建时哈希值(观察到为 `3181061566`) | | 8 | uint | `now % 0x80000000` — 毫秒时间戳的低 31 位 | | 9 | str | X-Gnarly payload 版本(如 `5.1.3-ZTCA`) | | 10| str | `webmssdk` SDK 版本(如 `1.0.0.368`) | | 11| uint | 常量 `1` | | 12| uint | 拦截的总请求数(XHR + fetch) | | 13| uint | 字段 12 的伴随计数对 | | 14| uint | 高 16 位 = 字段 1 << 16;低 16 位 = 随机值 | | 15| uint | 完整的 uint32 随机值 | ## 免责声明 本仓库以 MIT 协议发布,仅供**研究、教育、安全分析和互操作性**之用。它不包含 TikTok 的专有代码;每一个字节都是独立地从公共网络流量和对公开发布的 `webmssdk` 包的净室逆向中重新推导出来的。 - 使用它来了解现代客户端请求签名的工作原理。 - 使用它来验证捕获的 X-Gnarly 是否由真正的 SDK 构建版本发出。 - **请勿**将其用于绕过速率限制、在生产端点上规避机器人防护、进行工业规模的抓取,或以其他方式违反 TikTok 的服务条款或适用法律(如 CFAA、DMCA §1201、GDPR 等)。 维护者不隶属于 TikTok、ByteDance 或其任何子公司。诸如 `webmssdk`、`secsdk`、`ZTCA`、`X-Gnarly`、`X-Bogus`、`X-Argus`、`X-Ladon`、`X-Khronos`、`X-Gorgon` 和 `msToken` 等名称在此仅用于标识正在研究的协议。 ## 许可证 MIT — 详见 [许可证](./LICENSE)。
标签:Base64, ChaCha, CMS安全, JavaScript, TikTok, webmssdk, Web安全, X-Gnarly, 云资产清单, 加解密, 协议分析, 数据可视化, 权限提升, 流密码, 算法还原, 自定义脚本, 蓝队分析, 请求签名, 逆向工程