zp_stoken

郑重声明

  • 郑重声明:本项目的所有代码和相关文章, 仅用于经验技术交流分享,禁止将相关技术应用到不正当途径,因为滥用技术产生的风险与本人无关。

1、首先通过抓包定位数据接口

在这里插入图片描述

  • url: aHR0cHM6Ly93d3cuemhpcGluLmNvbS93YXBpL3pwZ2Vlay9zZWFyY2gvam9ibGlzdC5qc29u

  • 请求方式:get

  • 查询参数:

    {
        'scene': '1',
        'query': 'Java',			// 搜索关键字
        'city': '100010000',		// 城市id
        'experience': '',
        'degree': '',
        'industry': '',
        'scale': '',
        'stage': '',
        'position': '',
        'salary': '',
        'multiBusinessDistrict': '',
        'page': '3',				// 页码
        'pageSize': '30'			// 数据条数
    }
    
  • 请求头:

    {
    'accept': 'application/json, text/plain, */*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'zh-CN,zh;q=0.9',
    'cache-control': 'no-cache',
    'pragma': 'no-cache',
    'referer': '......',
    'cookie':'__zp_stoken__=c688eYS8QeXUiHj8Yf2Rabz9bXGglWUhQNj......',
    'sec-ch-ua': '"Chromium";v="104", ......', 
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'same-origin',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)......',
    'x-requested-with': 'XMLHttpRequest',
    }
    

2、通过多次抓包观察,发现cookie: zp_stoken是动态的,在本地用python脚本请求测试,在携带zp_stoken请求时可以成功返回数据,当不携带时返回如下。可以确定某聘后端通过zp_stoken鉴权

{"code":37,"message":"您的访问行为异常.","zpData":{"name":"2330c665","seed":"yeROdSg9sLCvTjzFFPDXCN0reVByGx8sZwDJO1fD0E1Qut6cAZVP8iAst3Ed60eeTyd8AhJv869BpeO3xNZ7ug==","ts":1662174250665}}

3、在浏览器搜索zp_stoken定位到zp_stoken的生成位置,并打断点调试,注意观察 n是第2步返回的ts,t是第2步返回的seed。
在这里插入图片描述

单步调试进入一个混淆js文件,这个文件的文件名则是第2步返回的name。

在这里插入图片描述

4、将2330c665.js复制到本地,该文件有20000多行,使用了大量的流程平坦化混淆,数值常量混淆,unicode混淆,十六进制混淆,ASCll码混淆,代码膨胀混淆,使用AST简单解一下混淆,方便调试。

在这里插入图片描述

5、使用Proxy代理自吐一部分环境,因为boos要检测this等于window,而window被代理后window就不等于this了,就会走错误分支,所以只能选择硬刚调试。

function proxy(obj, name) {
    return new Proxy(obj, {
        get(target, propKey, receiver) {
            let result = Reflect.get(target, propKey, receiver)
            let resultType = typeof result;
            resultType === 'undefined' ?
            console.error('GET', name, propKey, 
                              'return', resultType) :
            console.debug('GET', name, propKey, 
                          'return', resultType)
            return result;
        },
        set(target, propKey, value, receiver) {
            target[propKey] = value
            console.trace('SET', name, propKey, value, 
                          'return', true)
            return true
        },
    });
}
windww = global;
window = proxy(window,'window')

6、通过调试发现 2330c665.js使用了大量的

  • typeof 类型检测
  • hasOwnProperty 属性检测
  • 检测 top,self,this
  • Buffer ,module node环境检测
  • 检测代码是否格式化和源码是否被更改
  • 检测navigator,document,window对象上的属性数量
  • 检测 canvas webgl 指纹
  • 我们调试时一般会打开异常捕获断点,某聘故意在代码中投放很多异常,增加耗时,利用时间模块检测耗时,如果被检测到耗时过久,就会触发内存爆破

7、把各种环境补齐后,测试依旧不能100%成功,一定是哪里被检测到了,直接定位到cookie的最后生成位置,return Gjk(1517 - 1121, j);
在这里插入图片描述

发现 j 是一个数组,复制浏览器此处生成的 j 数组在本地i调用Gjk函数生成cookie是可用的,明显是这个数组有问题。

8、hook浏览器和本地的随机数模块和时间模块,使浏览器生成的zp_stoken固定( j 数组也会固定)

Math.random = function () {
    return 0.5
};
Date.prototype.getTime = function () {
    return 1662177494440
};
Date.prototype.now = function () {
    return 1662177494440
};

对比本地生成的 j 数组的不同,一步一步逆向 j 数组的生成过程,配合浏览器不断对比,成功找到检测点,补齐环境后,携带生成的zp_stoken请求就能100%成功。

在这里插入图片描述

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值