猿人学上的一个简单js反爬题目

713 阅读2分钟

【原文】www.freebuf.com/articles/we…

  1. 判断是否打开了调试窗口 match.yuanrenxue.com/match/1 如果判断打开了调试窗口,就加一个定时器,定时debugger,以及在一个while true循环里无限debugger的方法,不仅无法进行正常调试,还浪费时间,无法正常回收的对象还会越来越多,占用内存并最终打爆浏览器,例如
setInterval(function () {
    debugger
}, 500)

或者 www.fangdi.com.cn/

(function() {
    var a = new Date();
    debugger ;return new Date() - a > 100;
}())

解决办法:

a. 右键 -> never pause here可以禁止该断点,这种方式基本能解决问题,不过要是换个环境或者在VM(比如使用eval执行的一段函数)里的,就无法去掉了

b. 另外可以找到调用这一块代码的位置,根据他的逻辑,把调用定时debugger的方法注释掉,把这个js文件保存一份到本地,通过fiddler或者charles,定向这个js为我们修改过的即可,右键要替换的js文件,本地映射

Inked屏幕截图_LI.jpg

比如改成这样

setInterval(function() {
	console.log('debugger gone')
}, 500)

c. 也可以试试 Function.prototype.constructor = function(){}, 把所有的构造函数置空

以上,a和c不能解决的,就用c方法,修改原js,基本都能过

  1. 分析接口 chrome network 或者用charles进行抓包,查看请求接口的返回,定位数据,最终抓包发现,数据通过 http://match.yuanrenxue.com/api/match/1?m=14e91653971af2fe8a0488b578a2a1d8%E4%B8%A81622025053 返回,m 参数是会变化的,所以想到这个参数每次经过js计算而来(或者也可能是某个接口返回的),m参数长这样 m: 14e91653971af2fe8a0488b578a2a1d8丨1622025053 看起来分隔符|后面的相隔时间戳,没有更多信息了,看看这个请求是从哪发起的,当然,也可以xhr断点看看

2021525-153629.png

可以看到,请求时从首页发起的,那可能参数在这里也有些端倪,找到了这一句 m=oo0O0(timestamp.toString())+window.f;var list={"page":window.page,"m":m+'丨'+timestamp/1000};

找到这里,基本就成功了,看看m是怎么生成的就好了,把这一段js拿出来,美化一下

w();
dd();

function oo0O0(mw) {
    window.b = '';
    for (var i = 0, len = window.a.length; i < len; i++) {
        console.log(window.a[i]);
        window.b += String[document.e + document.g](window.a[i][document.f + document.h]() - i - window.c)
    }
    var U = ['W5r5W6VdIHZcT8kU', 'WQ8CWRaxWQirAW=='];
    var J = function (o, E) {
        o = o - 0x0;
        var N = U[o];
        if (J['bSSGte'] === undefined) {
            var Y = function (w) {
                var m = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=',
                    T = String(w)['replace'](/=+$/, '');
                var A = '';
                for (var C = 0x0, b, W, l = 0x0; W = T['charAt'](l++);~ W && (b = C % 0x4 ? b * 0x40 + W : W, C++ % 0x4) ? A += String['fromCharCode'](0xff & b >> (-0x2 * C & 0x6)) : 0x0) {
                    W = m['indexOf'](W)
                }
                return A
            };
            var t = function (w, m) {
                var T = [],
                    A = 0x0,
                    C, b = '',
                    W = '';
                w = Y(w);
                for (var R = 0x0, v = w['length']; R < v; R++) {
                    W += '%' + ('00' + w['charCodeAt'](R)['toString'](0x10))['slice'](-0x2)
                }
                w = decodeURIComponent(W);
                var l;
                for (l = 0x0; l < 0x100; l++) {
                    T[l] = l
                }
                for (l = 0x0; l < 0x100; l++) {
                    A = (A + T[l] + m['charCodeAt'](l % m['length'])) % 0x100, C = T[l], T[l] = T[A], T[A] = C
                }
                l = 0x0, A = 0x0;
                for (var L = 0x0; L < w['length']; L++) {
                    l = (l + 0x1) % 0x100, A = (A + T[l]) % 0x100, C = T[l], T[l] = T[A], T[A] = C, b += String['fromCharCode'](w['charCodeAt'](L) ^ T[(T[l] + T[A]) % 0x100])
                }
                return b
            };
            J['luAabU'] = t, J['qlVPZg'] = {}, J['bSSGte'] = !![]
        }
        var H = J['qlVPZg'][o];
        return H === undefined ? (J['TUDBIJ'] === undefined && (J['TUDBIJ'] = !![]), N = J['luAabU'](N, E), J['qlVPZg'][o] = N) : N = H, N
    };
    eval(atob(window['b'])[J('0x0', ']dQW')](J('0x1', 'GTu!'), '\x27' + mw + '\x27'));
    return ''
}

// 第二段
window.url = '/api/match/1';
request = function () {
    var timestamp = Date.parse(new Date()) + 100000000;
    var m = oo0O0(timestamp.toString()) + window.f;
    var list = {
        "page": window.page,
        "m": m + '丨' + timestamp / 1000
    };
    $.ajax({
        url: window.url,
        dataType: "json",
        async: false,
        data: list,
        type: "GET",
        beforeSend: function (request) {}, success: function (data) {
            data = data.data;
            let html = '';
            let us_sign = `<div class="b-airfly"><div class="e-airfly"data-reactid=".1.3.3.2.0.$KN5911.0"><div class="col-trip"data-reactid=".1.3.3.2.0.$KN5911.0.0"><div class="s-trip"data-reactid=".1.3.3.2.0.$KN5911.0.0.0"><div class="col-airline"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0"><div class="d-air"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0.0:$0"><div class="air"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0.0:$0.0"><span data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0.0:$0.0.1">中国联合航空</span></div><div class="num"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0.0:$0.1"><span class="n"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0.0:$0.1.0">KN5911</span><span class="n"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0.0:$0.1.1">波音737(中)</span><noscript data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0.0:$0.1.2"></noscript></div></div><noscript data-reactid=".1.3.3.2.0.$KN5911.0.0.0.0.1"></noscript></div><div class="col-time"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1"><div class="sep-lf"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.0"><h2 data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.0.0">13:50</h2><p class="airport"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.0.1"><span data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.0.1.0">大兴国际机场</span><span data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.0.1.1"></span></p></div><div class="sep-ct"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.1"><div class="range"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.1.0">3小时40分钟</div><div class="line"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.1.1"></div></div><div class="sep-rt"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.2"><noscript data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.2.0"></noscript><h2 data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.2.1">17:30</h2><p class="airport"data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.2.2"><span data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.2.2.0">宝安机场</span></p></div><noscript data-reactid=".1.3.3.2.0.$KN5911.0.0.0.1.3"></noscript></div></div></div><div class="col-price"data-reactid=".1.3.3.2.0.$KN5911.0.1"><p class="prc"data-reactid=".1.3.3.2.0.$KN5911.0.1.0"><span data-reactid=".1.3.3.2.0.$KN5911.0.1.0.0"><i class="rmb"data-reactid=".1.3.3.2.0.$KN5911.0.1.0.0.0">&yen;</i><span class="fix_price"data-reactid=".1.3.3.2.0.$KN5911.0.1.0.0.1"><span class="prc_wp"style="width:48px">price_sole</span></span></span></p><div class="vim"data-reactid=".1.3.3.2.0.$KN5911.0.1.1"><span class="v dis"data-reactid=".1.3.3.2.0.$KN5911.0.1.1.$0"></span></div></div><div class="col-fold"data-reactid=".1.3.3.2.0.$KN5911.0.2"><p class="fd"data-reactid=".1.3.3.2.0.$KN5911.0.2.0">收起</p></div></div><noscript data-reactid=".1.3.3.2.0.$KN5911.1"></noscript></div>`;
            let choice = ['中国南方航空', '吉祥航空', '奥凯航空', '九元航空', '长龙航空', '东方航空', '中国国际航空', '深圳航空', '海南航空', '春秋航空', '上海航空', '西部航空', '重庆航空', '西藏航空', '中国联合航空', '云南祥鹏航空', '云南英安航空', '厦门航空', '天津航空', '山东航空', '四川航空', '华夏航空', '长城航空', '成都航空有', '北京首都航空', '中华航空', '意大利国家航空公司', '印度百捷航空', '越南航空', '远东航空', '印度航空公司', '印度捷特航空有限公司', '以色列航空公司', '意大利航空', '伊朗航空公司', '印度尼西亚鹰航空公司', '英国航空公司', '西方天空航空', '西捷航空', '西班牙欧洲航空公司', '西班牙航空公司', '中国南方航空', '吉祥航空', '奥凯航空', '九元航空', '长龙航空', '东方航空', '中国国际航空', '深圳航空', '海南航空', '春秋航空', '上海航空', '西部航空', '重庆航空', '西藏航空', '中国联合航空', '云南祥鹏航空', '云南英安航空', '厦门航空', '天津航空', '山东航空', '四川航空', '华夏航空', '长城航空', '成都航空有', '北京首都航空', '中华航空', '意大利国家航空公司', '印度百捷航空', '越南航空', '远东航空', '印度航空公司', '印度捷特航空有限公司', '以色列航空公司', '意大利航空', '伊朗航空公司', '印度尼西亚鹰航空公司', '英国航空公司', '西方天空航空', '西捷航空', '西班牙欧洲航空公司', '西班牙航空公司'];
            let op = 1;
            let jic = ['北京首都国际机场', '上海虹桥国际机场', '上海浦东国际机场', '天津滨海国际机场', '太原武宿机场', '呼和浩特白塔机场', '沈阳桃仙国际机场', '大连周水子国际机场', '长春大房身机场', '哈尔滨阎家岗国际机场', '齐齐哈尔三家子机场', '佳木斯东郊机场', '厦门高崎国际机场', '福州长乐国际机场', '杭州萧山国际机场', '合肥骆岗机场', '宁波栎社机场', '南京禄口国际机场', '广州白云国际机场', '深圳宝安国际机场', '长沙黄花机场', '海口美亚机场', '武汉天河机场', '济南遥墙机场', '青岛流亭机场', '南宁吴墟机场', '三亚凤凰国际机场', '重庆江北国际机场', '成都双流国际机场', '昆明巫家坝国际机场', '昆明长水国际机场', '桂林两江国际机场', '西安咸阳国际机场', '兰州中川机场', '贵阳龙洞堡机场', '拉萨贡嘎机场', '乌鲁木齐地窝堡机场', '南昌向塘机场', '郑州新郑机场', '北京首都国际机场', '上海虹桥国际机场', '上海浦东国际机场', '天津滨海国际机场', '太原武宿机场', '呼和浩特白塔机场', '沈阳桃仙国际机场', '大连周水子国际机场', '长春大房身机场', '哈尔滨阎家岗国际机场', '齐齐哈尔三家子机场', '佳木斯东郊机场', '厦门高崎国际机场', '福州长乐国际机场', '杭州萧山国际机场', '合肥骆岗机场', '宁波栎社机场', '南京禄口国际机场', '广州白云国际机场', '深圳宝安国际机场', '长沙黄花机场', '海口美亚机场', '武汉天河机场', '济南遥墙机场', '青岛流亭机场', '南宁吴墟机场', '三亚凤凰国际机场', '重庆江北国际机场', '成都双流国际机场', '昆明巫家坝国际机场', '昆明长水国际机场', '桂林两江国际机场', '西安咸阳国际机场', '兰州中川机场', '贵阳龙洞堡机场', '拉萨贡嘎机场', '乌鲁木齐地窝堡机场', '南昌向塘机场', '郑州新郑机场'];
            if (window.page) {} else {
                window.page = 1
            }
            $.each(data, function (index, val) {
                html += us_sign.replace('price_sole', val.value).replace('中国联合航空', choice[op * window.page]).replace('大兴国际', jic[parseInt(op * window.page / 2) + 1]).replace('宝安机场', jic[jic.length - parseInt(op * window.page / 2) - 1]);
                op += 1
            });
            $('.m-airfly-lst').text('').append(html)
        }, complete: function () {}, error: function () {
            alert('数据拉取失败。可能是触发了风控系统,若您是正常访问,请使用谷歌浏览器无痕模式,并且校准电脑的系统时间重新尝试');
            alert('生而为虫,我很抱歉,请刷新页面,查看问题是否存在');
            $('.page-message').eq(0).addClass('active');
            $('.page-message').removeClass('active')
        }
    })
};
request()

以上,这段js稍微封装整理一下即可,每次生成一个m