__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 参数