最新boss直聘 __zp_stoken__ 生成

本代码请仅用于 纯技术研究的 用途,请勿用于商业用途或 非法用途,如果因使用者非法使用造成的法律问题与本作者无关!
仅供学术研究,如有侵权请即时通知,文章会在第一时间内删除!

某直聘在 12 月期间好像,对他的 __zp_stoken__ 生成进行了更新
此次更新后有以下特征

  1. 动态代码 -- 和以前一样,是动态的代码。以前是每次请求代码都不一样,这次是每天变化代码
  2. 动态环境检测 -- 加入了动态环境检测,导致若没找到动态点请求成功率会非常低
  3. 代码混淆 -- 跟进阿里系列,加入了大控制流,使得调试代码成本增大

上面是整体代码和之前的区别。接下来开始分析

此次分析使用补环境的方式来实现模拟生成。并且最后达到了 100% 的成功率。先展示成果。

fff20a033a5b48b08dd53073344673f2.png

厚码展示。

开始补环境

请求逻辑这边就不进行分析了。其大致逻辑就是先请求一次对应的链接,在 set-cookie 中拿到 name, ts, seed 这三个参数,然后传入我们的 js 进行加密得到 token 再携带请求一次便可拿到正确数据

我们直接开始代码分析

定位

我们直接使用 hook cookie 的方式定位生成的地方

// ==UserScript==
// @name        Hook Cookie
// @namespace   http://tampermonkey.net/
// @version     0.1
// @description try to take over the world!
// @author      You
// @include     *
// @grant       none
// @run-at      document-start
// ==/UserScript==

(function () {
    'use strict';
    var cookie_cache = document.cookie;
    Object.defineProperty(document, 'cookie', {
        get: function () {
            return cookie_cache;
        },
        set: function (val) {
            console.log('Setting cookie', val);
            // 填写cookie名
            if (val.indexOf('__zp_stoken__') != -1) {
                debugger;
            }
            var cookie = val.split(";")[0];
            var ncookie = cookie.split("=");
            var flag = false;
            var cache = cookie_cache.split("; ");
            cache = cache.map(function (a) {
                if (a.split("=")[0] === ncookie[0]) {
                    flag = true;
                    return cookie;
                }
                return a;
            })
            cookie_cache = cache.join("; ");
            if (!flag) {
                cookie_cache += cookie + "; ";
            }
            return cookie_cache;
        }
    });
})();

7fe1f770c35c45b6b95bee65e492d993.png

使用油猴导入上面的代码,在这边清除网站数据刷新,便可直接定位到目的地。

d1cc67ec14b844c591e166a46226b971.png

ff55e0b1a0d04d42a50d016323203cbf.png

进入会发现,蛙趣,一个大控制流,这样直接调试的话很费时间,所以我们先选择解部分混淆来便于调试。

解混淆结果如下

71bf7c9f3ed24d3f98b12f115692c75f.png

虽然不是很完美,但是也已经够看了。有需要的可以找我获取,可提供解混淆后的代码。

然后进行替换就可以开开心心的调试了。

补环境

4ae57eef579742a0924d9155ed1c4f67.png

在调试的时候注意这种调用方式,这种一般就是在进行环境检测

之前写的一部分笔记

hl = n["call"](undefined, ql);

zl = hl in La;

gl = o["call"](undefined, wl);

ml = gl in La;

Sl = y["call"](undefined, bl);

 

有很多类似这样的代码 ["call"](undefined, ....) 这些代码里面最多就是检测一个函数是否存在,进行 typeof 运算,然后返回一个字符串

我们主要是需要这个字符串,那么现在就先不往里面看了,之后再看

 

而且这段操作是

a = window["a"]

b = typeof a

c = !b

其实即便 b 是 undefined 他也是 false 所以好像是不需要管的

 

再次分析,又好像是当 M = p["call"](undefined, R); 传入的第二个参数是个奇怪的字符串的时候,便是返回一个字符串,就可以不用往里面看了

 

z["call"](undefined, m, We);

这种传入的 m 是数组 We 是某个环境值,会将这个环境值添加到 m 数组中

 

只有一个 undefined 参数的,极有可能就是环境检测的

然后就进行一步一步的调试,发现他所需要的环境便可以达到 100% 成功率了。

部分检测点

光这样感觉没有干货啊,说点他的检测点吧

检测 document.all

这是一个老生常谈的检测了,现在已经有成熟的方案来处理了

我这边使用的是 node 插件来实现的,很简单就能实现他对 typeof document.all 的检测了。

但是,对 document.all 的检测不仅于此

他同时检测了 document.all 和 appendchild 之间的强关系

同时有下面这一段检测,这是检测的最小单元,你们可以先试试

function test() {
    var type = typeof document.all
    if (type === "undefined") {
        var all_len = document.all.length;
        var a = document.createElement("a");
        document.body.appendChild(a);
        var b = document.all[all_len]
        if (a === b) {
            delete document.all[all_len];
            var c = document.all[all_len];
            if (a === c) {
                document.body.removeChild(a);
                var d = document.all[all_len];
                if (d === undefined) {
                    return "成功";
                }
            }
        }
    }
    return "失败";
}

console.log(test())

返回成功便成功通过检测

检测 top 和 window 之间的关系

玩过老版本的都知道,其实 top 和 window 在改直聘中并不是同一个对象,其原因是其开了一个 f 窗口来加密的这个参数

所以我们对他们分开赋值便可解决

使用 Object.keys 检测了 window 和 document 的元素

这个很好解决 我们直接重写 Object.keys 方法即可。

结语

就分析到这了,再多就不行了

最终你将会得到 100% 成功率的 补环境 代码。加油特种兵。

“加速行业进步,破除行业垄断”

 

预告下期:akm~

 

 

 

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值