美文网首页
反爬 JavaScript加密混淆

反爬 JavaScript加密混淆

作者: 金刚_30bf | 来源:发表于2018-06-08 09:55 被阅读0次

当爬取网站时,网站会返回5XX响应码和一段JavaScript响应报文,浏览器会加载该段js ,往往在这些js中会包含定时刷新重定向、cookie等信息,刷新后,浏览器自动会使用新的cookie访问服务器获取真正的请求。

如下示例:

HTTP/1.1 521
<script>var x="toLowerCase@Jun@while@@@DOMContentLoaded@@var@@catch@a@window@for@JgSe0upZ@e@@else@eval@@@@@1528352514@length@@pathname@@Expires@@@@innerHTML@@@0xFF@@@Thu@replace@createElement@@@fromCharCode@https@@firstChild@function@@@__jsl_clearance@href@String@location@@@@0xEDB88320@@RegExp@@g@@d@match@Array@setTimeout@div@@if@0@36@search@1@@@@@@@addEventListener@@@@join@26@2@@cookie@@18@split@attachEvent@Path@return@parseInt@onreadystatechange@substr@chars@@@charCodeAt@@new@charAt@1500@reverse@@document@f@rOm9XFMtA3QKV7nYsPGT4lifyWwkq5vcjH2IdxUoCbhERLaz81DNB6@@21@@@@toString@54@false@8@07@@GMT@captcha@@challenge@try@@".replace(/@*$/,"").split("@"),y="8 16=L(){1c('R.P=R.q+R.1i.D(/[\\?|&]2f-2h/,\\'\\')',1P);20.1y='O=n.1v|1g|'+(L(){8 u=[L(16){1E i('Q.H('+16+')')},L(16){d(8 u=1g;u<16.o;u++){16[u]=1F(16[u]).28(1h)};1E 16.1u('')}],16=[[(-~((-~{}-~{}<<-~{}))+[])+(-~((-~{}-~{}<<-~{}))+[])],[(-~-~[]+[]+[[]][1g])+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})],[-~[]]+[(+[])],[-~[]]+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})],(-~-~[]+[]+[[]][1g])+[(+[])]],[[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]+[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]],[[-~[]]+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})]],[[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})]+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})]],[(-~-~[]+[]+[[]][1g])+[(+[])]],[(((-~[]<<-~[])^-~~~[])+[]+[])+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})],(-~((-~{}-~{}<<-~{}))+[])+[(+[])],(((+!+{})+[1w])/[1w]+[[]][1g])+(((+!+{})+[1w])/[1w]+[[]][1g])],[[-~[]]+[(+[])]],[(-~((-~{}-~{}<<-~{}))+[])+(((+!+{})+[1w])/[1w]+[[]][1g]),[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]+((-~-~[])*[-~-~[]]+[[]][1g]),(((-~[]<<-~[])^-~~~[])+[]+[])+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})],(-~((-~{}-~{}<<-~{}))+[])+[(+[])],[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})]+[(+[])],(((+!+{})+[1w])/[1w]+[[]][1g])+(-~((-~{}-~{}<<-~{}))+[]),(-~((-~{}-~{}<<-~{}))+[])+[-~[]],[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})]+[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]],[(-~-~[]+[]+[[]][1g])+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})],[-~[]]+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})]],[(-~((-~{}-~{}<<-~{}))+[])+(-~((-~{}-~{}<<-~{}))+[]),[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})],[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]+(-~-~[]+[]+[[]][1g]),[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})]+(((-~[]<<-~[])^-~~~[])+[]+[])],[(-~-~[]+[]+[[]][1g])+[-~((+!+{})-~-~[])+(+!+{})-~((+!+{})-~-~[])]],[[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]+(-~-~[]+[]+[[]][1g])],[[-~[]]+(((-~[]<<-~[])^-~~~[])+[]+[]),(-~-~[]+[]+[[]][1g])+[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]],[(((-~[]<<-~[])^-~~~[])+[]+[])+[(-~{}+[(-~{}-~{}<<-~{})]>>-~{})],(-~((-~{}-~{}<<-~{}))+[])+[-~[]],(((+!+{})+[1w])/[1w]+[[]][1g])+[-~-~[]-~[]-~-~[]+(+!+{})-~-~[]]]];d(8 27=1g;27<16.o;27++){16[27]=u.1Q()[[-~[]]](16[27])};1E 16.1u('')})()+';s=C, 2c-2-1A 2c:24:29 2e;1D=/;'};1f((L(){2i{1E !!c.1q;}a(f){1E 2a;}})()){20.1q('6',16,2a)}h{20.1C('1G',16)}",f=function(x,y){var a=0,b=0,c=0;x=x.split("");y=y||99;while((a=x.shift())&&(b=a.charCodeAt(0)-77.5))c=(Math.abs(b)<13?(b+48.5):parseInt(a,36))+y*c;return c},z=f(y.match(/\w/g).sort(function(x,y){return f(x)-f(y)}).pop());while(z++)try{eval(y.replace(/\b\w+\b/g, function(y){return x[f(y,z)-1]||("_"+y)}));break}catch(_){}</script>

仔细分析上述js代码, 其定义了变量x,y ,z ,真正有用的是后面eval里的代码,但具体什么鬼我们看不出来。 最好的方式是加载改段js ,看看其返回的真正信息。

    soup = BeautifulSoup(resstr, "lxml")
    
    fstr = soup.script.string
    print(fstr)
    fstr = fstr.replace('try{eval(','try{return(')

    pjsctx = execjs.get("Phantomjs")
    
    c1=pjsctx.compile(fstr)
    
    evaled_func=c1.call('f') 

使用BeautifulSoup解析响应报文, 取js代码, 将eval替换为return , 使用execjs的Phantomjs环境编译并执行之。

结果如下:

var _1w=function(){setTimeout('location.href=location.pathname+location.search.replace(/[\?|&]captcha-challenge/,\'\')',1500);document.cookie='__jsl_clearance=1528423274.136|0|'+(function(){var _2a=[function(_1w){return eval('String.fromCharCode('+_1w+')')},(function(){var _1w=document.createElement('div');_1w.innerHTML='<a href=\'/\'>_d</a>';_1w=_1w.firstChild.href;var _2a=_1w.match(/https?:\/\//)[0];_1w=_1w.substr(_2a.length).toLowerCase();return function(_2a){for(var _d=0;_d<_2a.length;_d++){_2a[_d]=_1w.charAt(_2a[_d])};return _2a.join('')}})()],_d=[[[(+!'')]+(~~{}+[])+[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])],(4+[]+[])+[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])],[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]]+[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])],[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]]+[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]],(-~[-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))]]+[]+[[]][0])+[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])],[(+!'')]+[2]+[(+!'')],[(+!'')]+(~~{}+[])+[2],(-~[-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))]]+[]+[[]][0])+[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])],(((+!'')+[-~-~[]]>>-~-~[])+(+!'')+(+!'')+(+!'')+(+!'')+[])+[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]]],[[(+!'')]+(4+[]+[])],[[(+!'')]+[2]+[2],(-~[-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))]]+[]+[[]][0])+((2^-~[])+[]),(-~[-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))]]+[]+[[]][0])+[-~!/!/+(+!'')+((-~{}<<-~{})^-~[])],[-~!/!/+(+!'')+((-~{}<<-~{})^-~[])]+(~~{}+[]),[-~!/!/+(+!'')+((-~{}<<-~{})^-~[])]+(4+[]+[]),[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])]+(~~{}+[]),(-~[-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))]]+[]+[[]][0])+(~~{}+[]),((2^-~[])+[])+(((+!'')+[-~-~[]]>>-~-~[])+(+!'')+(+!'')+(+!'')+(+!'')+[]),[-~!/!/+(+!'')+((-~{}<<-~{})^-~[])]+(~~{}+[]),[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]]+[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]],[(+!'')]+[2]+[2],[(+!'')]+(~~{}+[])+[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])]],[(4+[]+[])],[(((+!'')+[-~-~[]]>>-~-~[])+(+!'')+(+!'')+(+!'')+(+!'')+[])+[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])],[(+!'')]+(~~{}+[])+(4+[]+[]),(((+!'')+[-~-~[]]>>-~-~[])+(+!'')+(+!'')+(+!'')+(+!'')+[])+[-~!/!/+(+!'')+((-~{}<<-~{})^-~[])],(-~[-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))]]+[]+[[]][0])+[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]],[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]]+[-~(-~[]-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))])]],[[(+!'')]+(~~{}+[])],[((2^-~[])+[])+(((+!'')+[-~-~[]]>>-~-~[])+(+!'')+(+!'')+(+!'')+(+!'')+[]),[-~!/!/+(+!'')+((-~{}<<-~{})^-~[])]+[(+!'')],[((+!'')+[(-~{}<<-~{})])/[(-~{}<<-~{})]]+(-~[-~[[(+!'')+(+!'')]*(((+!'')+[-~-~[]]>>-~-~[]))]]+[]+[[]][0])]];for(var _1w=0;_1w<_d.length;_1w++){_d[_1w]=_2a.reverse()[[(+!'')]](_d[_1w])};return _d.join('')})()+';Expires=Fri, 08-Jun-18 03:01:14 GMT;Path=/;'};if((function(){try{return !!window.addEventListener;}catch(e){return false;}})()){document.addEventListener('DOMContentLoaded',_1w,false)}else{document.attachEvent('onreadystatechange',_1w)}

这同样是一段加密混淆后的js , 但是已经可以初步看到,timeout 、document.cookie等信息。
同样我们可以加载并编译这段js , 由于目标是获取设置的cookie , 所以对js进行处理 :

        si = evaled_func.index("'__jsl_clearance=")
        ei = evaled_func.index(";if((function(){")
        print(si,ei)
        s2 = evaled_func[si:ei]
        s3 = "var f = function(){ return " + s2
        print(s3)
        
        s3ctx = pjsctx.compile(s3)
        r1 = s3ctx.call("f")

至此可以获取其设置的cookie 。

主要是使用 pyexecjs 和 Phantomjs 执行js代码。

但是由于在js的处理上涉及到字符串匹配、截取、拼接等操作,如果服务器每天变换相关关键字, 将会使上述代码不可用 。

相关文章

网友评论

      本文标题:反爬 JavaScript加密混淆

      本文链接:https://www.haomeiwen.com/subject/smyosftx.html