__csr 代表 Cross-Site Request,通常用于跨站点请求。
在请求接口的参数中,会看到一个叫做 __csr 的参数。

全局搜索的时候,找到一个 StaticSiteData
模块,__csr
对应的键名是 csr_key
。

这里找到了 csr_key
的赋值方式 d("CSRBitMap").toCompressedString()

把开头的 d
换成 require
调用 CSRBitMap
模块就能获取到 __csr
参数的结果了。

直接定位到 CSRBitMap
模块,分析一下是怎么实现的。这里的 h
变量是一个空数组,通过 a
函数将内容写入到 h
变量中,但是目前不知道 a
传入的是什么内容,所以在这里添加断点,然后刷新页面看看传入的是什么参数。

这里显示 a
传入了一个数字 16。点击右侧 「Call Stack」 中的 「handlePayload」继续往下跟踪。

刚才传入的数字 16 是从 csrUpgrade
这里来的,那么下次传入的结果就会是 1, 8, 73... 以此类推。

在页面上搜索 csrUpgrade
就找到来源了,使用下面的代码就可以获取到这段 csrUpgrade
并且格式化数组。
document.head.outerHTML.match(/(?<=csrUpgrade":":).*?(?=")/g).join(',').split(',')

那么跟着断点往下分析,传入这段 csrUpgrade
数据后 a
又传入了 303。点击右侧 「Call Stack」 中的 「U」继续往下跟踪。

刚才传入的数字 303 是从一个 css 中满足 c == 2
这个条件的 p 属性这里来的。
使用下面的代码就可以从 css 中过滤出 c
等于 2 的 p 属性的结果,并且格式化成数组。
document.body.outerHTML.match(/(?<=type":"css","src":"https.*?","c":2,"p":":).*?(?=")/g).join(',').split(',')

后面的分析方法类似,就不细节说明了,直接看结果。
这段 css 传入后,又传入了一段 csrUpgrade
。不过这次是从 body 中获取到的。使用下面的代码就可以获取到这段 csrUpgrade
并且格式化数组。
document.body.outerHTML.match(/(?<=csrUpgrade":":).*?(?=")/g).join(',').split(',')

这里基本上可以得出是通过网页 head 和 body 中的 csrUpgrade
和 css 中 c
等于 2 的 p 属性通过 toCompressedString
生成出来的。toCompressedString
的实现方法参考:逆向 Facebook 接口 __dyn 参数