补环境框架:sdenv与浏览器生成cookie的一致性验证

閱讀時間:全文 1218 字,預估用時 7 分鐘
創作日期:2024-03-13
文章標籤:
 
BEGIN

反爬虫产品的反爬检测越来越高级,尤其是以瑞数vmp为代表的一类,我们用老式的技术已经很难做这一类网站的算法逆向,因为要花费的时间已经就劝退了很大一批开发人员,而且花了大量的时间最后仍旧无法完成逆向出算法的同学也大有人在。那么这个时候补环境框架的优势就很大的体现出来,那么github上有很多款补环境框架,不管补的齐不齐,就算最后产生了位数对的cookie,在使用该cookie时还是被检测到了!我们有没有思考过有没有可能是cookie本身的问题?答案是肯定的,瑞数vmp在产生cookie时就算检测出了是非法客户端(比如关键方法toString后取特征码等)也给我们看起来没有啥问题的cookie,后台拿到有问题的cookie后通过定时任务检测合法性,从而进行进一步风控。

那么如何规则这种让人心累的反爬措施?

sdenv给出了方案,即sdenv产生的cookie与浏览器产生的cookie一摸一样,这样它们后台自然就辨别不了我们是不是真的浏览器!

sdenv项目地址:https://github.com/pysunday/sdenv 🔗

验证代码在example/use-proxy目录下,可以查看目录下的README文件!该样例通过代理的方式模拟多端环境请求,从而验证多端环境产生cookie值的差异,我们使用了自研的代理工具:https://github.com/pysunday/tools-proxy 🔗 ,该工具支持被代理网站的资源收集和回放,用于数据采集开发和前端mock开发还是很方便的。当然也可以使用其它代理工具,只要链接返回对应文件即可,被代理的链接和文件关系如下:

  1. html页面:https://wcjs.sbj.cnipa.gov.cn/sgtmi(example/use-proxy/pysunday-proxy/wcjs.sbj.cnipa.gov.cn/sgtmi/format) 🔗
  2. sdenv-extend打包文件:https://wcjs.sbj.cnipa.gov.cn/c5rxzYrjRT2h/sdenv.js(example/use-proxy/pysunday-proxy/wcjs.sbj.cnipa.gov.cn/c5rxzYrjRT2h/sdenv.js/format) 🔗
  3. 网站js代码源文件:https://wcjs.sbj.cnipa.gov.cn/c5rxzYrjRT2h/cCdzB9ZjDFks.294cc83.js(example/use-proxy/pysunday-proxy/wcjs.sbj.cnipa.gov.cn/c5rxzYrjRT2h/cCdzB9ZjDFks.294cc83.js/main) 🔗

运行命令启动代理:

sd_proxy -H 0.0.0.0 -p 3000 -n playback -d pysunday-proxy --log

浏览器端使用SwitchyOmega插件进行3000端口的转发,node端命令已经内置代理的配置直接执行命令即可。

至此多端环境已经搭建完成,node执行命令控制台打印cookie:

node example/use-proxy/index.js

浏览器打开调试面板后请求https://wcjs.sbj.cnipa.gov.cn/sgtmi后在断点处打印cookie: 🔗

可以看到两端生成的cookie是一样的值,既然生成的cookie值一样那么不管什么反爬虫产品或者方法自然都不能识别是爬虫框架产生的cookie!

那么对于sdenv和浏览器的共有代码做了什么我们继续一探究竟!

可以看到html文件引入了sdenv.js,sdenv.js文件是项目sdenv-extend的打包产物,sdenv-extend只提供了一个SdenvExtend的类,并不会主动运行其它修改window或者dom的代码。

接下来可以看到初始化代码,即和浏览器端去Application手动清理效果是一样的:

document.cookie = '';
window.name = '';
window.localStorage.clear();
window.sessionStorage.clear();

然后可以看到初始化sdenv,当Object.sdenv不存在则是浏览器端,则先实例化一下,全局的SdenvExtend是前面sdenv.js文件导出的,然后将SdenvExtend赋值给sdenv,Object.sdenv().memory.SdenvExtend是node中定义的:

const sdenv = Object.sdenv ? new (Object.sdenv().memory.SdenvExtend)() : new SdenvExtend();

接着是修改客户端的一些属性值,比如网络状态、电池电量、充电状态等

sdenv.getHandle('connection')()
    .getHandle('battery')()
    .getHandle('cookie')({
        setCb: (val) => {
            if (val.includes('goN9uW4i0iKzT')) {
                cookies.push(val);
                if (cookies.length === 3) {
                    console.log(`第三次cookie值写入:${val}`);
                    debugger;
                }
            }
        }
    })
    .getHandle('dateAndRandom')({
        datas: { "firstMap": { "_newdate": 1710236537289 }, "_newdate": [...] },
        randomReturn: 0.123,
    });

其中dateAndRandom的作用比较特殊,它会处理Math.randomDate的部分方法,将运行时的数据缓存下来比如randomReturn的0.123表示Math.random()始终返回0.123,datas的值也是自动获取的,也是由于datas的值存在,因此cookieJar检测的cookie都是过期的,会自动删除,因此在node端window.onbeforeunload的事件里取不到cookie的值,此时我们将datas的值删除或者注释掉,再执行获取cookie方法和获取运行时Date数据:

删除datas后cookieJar取到cookie值了

通过Object.sdenv().utils.getDateData(copy)方法获取运行时日期数据并复制到剪切板,然后黏贴到datas就可以继续使用。

至此cookie的一致性验证就大功告成了,在开发过程中其实还会用到eval、timeout、even等SdenvExtend handle方法,可以去项目文档查看,还有dom动态渲染等问题,不过这些不影响cookie值的生成。

最后需要说明:作者没有在其它操作系统和其它版本chrome验证过,如果验证过程中有遇到任何问题请随时联系我,当然验证通过的也可以将您适配的browser代码提交PR,感谢!

FINISH

隨機文章
人生倒計時
default