百趣云 百趣云的博客

大麦风控 cookie 溯源:我写了个 Chrome 扩展,专治"cookie 是谁写的"

问题的本质:不知道 cookie 是哪来的

研究大麦抢票,接口本身不难模拟,真正的门槛是风控 cookie——cookie2sid 这几个值。它们什么时候被写、被谁写、写之前发了什么请求,不搞清楚这些,协议模拟永远差临门一脚。

网上找不到这类资料,大家只会教"抓包看参数"。我的解法是做一个 Chrome 扩展级的 cookie 溯源工具:不猜,直接监控——谁写的、什么时候写的、写之前 1 秒内页面发了哪些请求,全部记录下来自动关联。

扩展架构:三层结构

MV3 扩展分三层,各司其职:

  • injected.js:注入页面主世界,hook document.cookie 的 setter,拿 JS 写 cookie 的调用栈
  • content.js:content script 做桥梁,window.postMessage 收 injected 的数据,转发给 background
  • background.js:service worker,汇总 chrome.cookies.onChanged(浏览器层 cookie 变化)+ JS 写入事件 + 网络请求记录,做时间窗关联

核心一:hook document.cookie 拿调用栈

关键技巧:document.cookie 的 getter/setter 定义在 Document.prototype 上,用 Object.defineProperty 重写 setter,写入时顺手 new Error() 抓调用栈:

const desc = Object.getOwnPropertyDescriptor(Document.prototype, "cookie") ||
    Object.getOwnPropertyDescriptor(HTMLDocument.prototype, "cookie");

Object.defineProperty(document, "cookie", {
    configurable: true,
    get() {
        return desc.get.call(document);
    },
    set(value) {
        const parsed = parseAssign(value);   // 解析 name=value
        if (parsed && WATCH.has(parsed.name)) {
            let stack = "";
            try { stack = new Error("cookie-set").stack || ""; } catch (_) {}
            post({
                via: "document.cookie",
                name: parsed.name,
                value: parsed.value,
                href: location.href,
                stack        // 完整调用栈:哪个 js 文件、哪一行写的
            });
        }
        return desc.set.call(document, value);   // 原样放行
    }
});

拿到调用栈,就能直接定位到风控 JS 里写 cookie2 的那一行代码——这比盲逆整个混淆文件快几个数量级。

核心二:浏览器层监控

JS hook 只能看到 document.cookie 的写入,服务器通过 Set-Cookie 响应头写的 cookie 要走 chrome.cookies.onChanged

const DEFAULT_WATCH = ["cookie2", "sid"];
const HOST_FILTER = [
    "*://*.damai.cn/*", "*://*.taobao.com/*", "*://*.tmall.com/*",
    "*://*.alicdn.com/*", "*://*.mmstat.com/*",
    "*://*.alibaba.com/*", "*://*.alipay.com/*"
];

HOST_FILTER 覆盖整个阿里系域名——大麦的风控 cookie 经常是 mmstat(埋点域)或 alicdn 上的脚本写的,只盯 damai.cn 会漏。

核心三:时间窗关联算法

这是整个工具的灵魂。cookie 变化事件、网络请求、JS 写入三条数据流,按时间窗自动关联:

const NET_WINDOW_MS = 4000;   // 网络请求回溯窗口
const JS_WINDOW_MS = 2500;    // JS 事件回溯窗口
const NEAR_WINDOW_MS = 900;   // 近邻强关联窗口

逻辑:一次 cookie2 写入事件发生后,回溯 4 秒内的网络请求、2.5 秒内的 JS 事件,凡是落在 900ms 近邻窗口内的,标记为强关联——基本就能断定"是这个请求/这段脚本产出了这个 cookie"。

实测效果:大麦首页加载后 cookie2 的每次刷新,都能精确关联到具体的 mmstat 请求和对应的混淆 JS 文件行号,风控 cookie 的生成链路一目了然。

彩蛋:两个实用按钮

面板上还加了两个实用功能:

  • 续期 30 天:一键把目标 cookie 的过期时间延长 30 天,免去频繁重新登录
  • 删除会退出:一键清掉会话 cookie 快速切换账号

总结

这套"cookie 溯源"方法论的通用性很强:

  1. Document.prototype 上重写 cookie setter,new Error().stack 拿调用栈
  2. chrome.cookies.onChanged 覆盖 Set-Cookie 通道
  3. 三流数据按时间窗(4s / 2.5s / 900ms)自动关联

不只是大麦,淘宝、闲鱼、任何阿里系站点的风控 cookie 都能用这套工具直接定位生成源头。逆向的第一步永远是观测,观测清楚了,后面都是体力活。

交流微信:teawhites

By 百趣云 阅读量:6 On