话接上头,上一篇讲了一下简单的js反爬,还可以通过python重写解密过程。
这一篇的js,相对烧饭,反正我是没有解密出来, 只是使用js模块执行,得出结果。其缺点是执行速度较慢。
这里再说一下解密js的目的是得到js中隐藏的cookie,以便访问网站,从而得到html源码。
使用环境:python3 requests js2py
一、requests请求得到的js如下:
<script>var x="Array@@@@@@DOMContentLoaded@@0xFF@@Path@@19@function@location@@@@@split@__jsl_clearance@eval@Wed@@parseInt@@35@rOm9XFMtA3QKV7nYsPGT4lifyWwkq5vcjH2IdxUoCbhERLaz81DNB6@@reverse@@@pathname@g@@@false@@@href@0xEDB88320@@@@36@21@@attachEvent@f@@2@charCodeAt@@8@toLowerCase@@fromCharCode@@new@return@challenge@02@@1500@var@captcha@@@1@@else@1552440921@addEventListener@for@d@7@@@catch@@@document@RegExp@@@@a@JgSe0upZ@div@13@if@try@0@@window@cookie@search@length@Mar@onreadystatechange@@createElement@@@match@@firstChild@while@String@https@495@toString@innerHTML@Expires@join@@setTimeout@@@@GMT@replace@e@substr@charAt@chars@@3".replace(/@*$/,"").split("@"),y="230 20=24(){432(\'30.130=30.113+30.342.442(/[\\\\?|&]231-221/,\\\\\'\\\\\')\',224);312.341=\'41=242.421|333|\'+(24(){230 112=[24(20){220 42(\'414.212(\'+20+\')\')},24(20){244(230 112=333;112<20.343;112++){20[112]=100(20[112]).422(140)};220 20.430(\'\')}],20=[[(1003+[])+[301],(-~(+!-[])+1003+[]+[[]][333])+[~~!/!/],[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))]+[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))],[301]+[301]],[[-~~~{}]+[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))]],[[301]+[301]],[((-~!/!/<<-~!/!/)+[])+[~~!/!/]],[((201)*[(-~(+!-[])<<-~[])]+[[]][333])+(-~(+!-[])+1003+[]+[[]][333]),((201)*[(-~(+!-[])<<-~[])]+[[]][333])+[301],[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))]+[301]],[[-~~~{}]+((-~~~{}-~~~{})*[-~~~{}-~~~{}]+[]+[])],[(-~(+!-[])+1003+[]+[[]][333])+(1003+[])],[((-~!/!/<<-~!/!/)+[])+(-~{}+((-~!/!/<<-~!/!/)^-~[])+(-~~~{}+[~~[]])/[-~~~{}-~~~{}]+[])],[[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))]+(-~(+!-[])+1003+[]+[[]][333]),((201)*[(-~(+!-[])<<-~[])]+[[]][333])+((-~~~{}-~~~{})*[-~~~{}-~~~{}]+[]+[]),[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))]+(-~{}+((-~!/!/<<-~!/!/)^-~[])+(-~~~{}+[~~[]])/[-~~~{}-~~~{}]+[])],[[-~~~{}]+(-~(+!-[])+1003+[]+[[]][333]),((-~!/!/<<-~!/!/)+[])+(-~{}+((-~!/!/<<-~!/!/)^-~[])+(-~~~{}+[~~[]])/[-~~~{}-~~~{}]+[]),[-~~~{}]+((201)*[(-~(+!-[])<<-~[])]+[[]][333])],[(-~{}+((-~!/!/<<-~!/!/)^-~[])+(-~~~{}+[~~[]])/[-~~~{}-~~~{}]+[])+[~~!/!/]],[[-~~~{}]+((-~!/!/<<-~!/!/)+[])],[[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))]+[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))],(1003+[])+[301],(-~(+!-[])+1003+[]+[[]][333])+[~~!/!/],[301]+[~~!/!/],((-~~~{}-~~~{})*[-~~~{}-~~~{}]+[]+[])+(-~{}+((-~!/!/<<-~!/!/)^-~[])+(-~~~{}+[~~[]])/[-~~~{}-~~~{}]+[]),((201)*[(-~(+!-[])<<-~[])]+[[]][333])+[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))]],[((-~!/!/<<-~!/!/)+[])+[~~!/!/]],[((-~~~{}-~~~{})*[-~~~{}-~~~{}]+[]+[])+(-~{}+((-~!/!/<<-~!/!/)^-~[])+(-~~~{}+[~~[]])/[-~~~{}-~~~{}]+[]),((201)*[(-~(+!-[])<<-~[])]+[[]][333])+(1003+[]),((201)*[(-~(+!-[])<<-~[])]+[[]][333])+(-~{}+((-~!/!/<<-~!/!/)^-~[])+(-~~~{}+[~~[]])/[-~~~{}-~~~{}]+[]),(1003+[])+[301],(-~(+!-[])+1003+[]+[[]][333])+[-~~~{}],[[(-~!/!/<<-~!/!/)]*((-~[]+[(-~!/!/<<-~!/!/)]>>(-~!/!/<<-~!/!/)))]+((201)*[(-~(+!-[])<<-~[])]+[[]][333])]];244(230 440=333;440<20.343;440++){20[440]=112.110()[[-~~~{}]](20[440])};220 20.430(\'\')})()+\';424=43, 330-344-23 222:102:141 441;21=/;\'};331((24(){332{220 !!340.243;}304(443){220 122;}})()){312.243(\'12\',20,122)}241{312.143(\'400\',20)}",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>\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n'
依然是一串没有任何断点的字符串,其中有效的格式化后如下:
<script>
var x = "@length@@@@onreadystatechange@Jgk@@@0xEDB88320@chars@Array@rOm9XFMtA3QKV7nYsPGT4lifyWwkq5vcjH2IdxUoCbhERLaz81DNB6@window@@a@@function@@@JgSe0upZ@Mon@setTimeout@8@as@@reverse@1552300852@else@@YvGgpD@@if@cookie@while@var@captcha@eval@d@fromCharCode@@@f@return@try@createElement@36@firstChild@addEventListener@@@@String@@1500@e@Mar@@@Path@hantom@replace@1@GMT@@@@substr@join@@pathname@div@@D@challenge@search@g@false@innerHTML@__p@split@@0@match@11@19@new@7@@Expires@@attachEvent@762@@for@@DOMContentLoaded@@@GHC@catch@@gD@headless@href@RegExp@charCodeAt@location@toLowerCase@40@@hmmWQQ@__jsl_clearance@https@0xFF@parseInt@document@@@toString@6@52@@@charAt@2@@".replace(/@*$/, "").split("@"),
y = "A P=i(){n(\'22.1Q=22.1i+22.1n.19(/[\\\\?|&]B-1m/,\\\\\'\\\\\')\',12);2b.y=\'27=s.1E|1u|\'+(i(){A P=[[((+!-{})+[~~!/!/])/[-~![]-~![]]],[((+!-{})<<(+!-{}))+((+!-{})<<(+!-{}))-~((-~![]-~![]<<-~{}))],[-~![]-~![]+[-~![]-~![]]*((((+!-{})<<(+!-{}))^-~![]))],((2k<<-~{})+[]+[[]][1u]),[(+!-{})]+((+[])+[[]][1u]),(2f+[]+[[]][1u]),(1z+[[]][1u]),[(+!-{})],((+[])+[[]][1u]),(-~[-~![]-~![]]+[]+[[]][1u]),(-~-~![]+[])];1G(A 1J=1u;1J<P.2;1J++){P[1J]=[\'7%\',(2f+[]+[[]][1u]),\'1l\',(-~[-~![]-~![]]+[]+[[]][1u]),[e.1P+[]+[]][1u].2j(-~![]-~![]+[-~![]-~![]]*((((+!-{})<<(+!-{}))^-~![]))),\'1O\',(2f+[]+[[]][1u])+[e[\'1r\'+\'18\'+\'p\']+[[]][1u]][1u].2j(-~[-~![]+([-~![]-~![]]+~~{}>>-~![]-~![])]),\'26\',\'1L\',[[((+!-{})<<(+!-{}))]/~~!/!/+[[]][1u]][1u].2j(-~~~{}+((+!-{})<<(+!-{}))-~~~{}+((+!-{})<<(+!-{})))+[((+!-{})<<(+!-{}))+((+!-{})<<(+!-{}))-~((-~![]-~![]<<-~{}))]+[[((+!-{})<<(+!-{}))]/~~!/!/+[[]][1u]][1u].2j(-~~~{}+((+!-{})<<(+!-{}))-~~~{}+((+!-{})<<(+!-{}))),\'v\'][P[1J]]};I P.1g(\'\')})()+\';1B=m, 1w-14-1x 1w:24:2g 1b;17=/;\'};x((i(){J{I !!e.N;}1M(13){I 1p;}})()){2b.N(\'1I\',P,1p)}t{2b.1D(\'6\',P)}",
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)
}));
consolt.log(result)
break
} catch (_) {
}
</script>
如果你能够看到这个,说明你已经遇到这个问题,且久久思索没有得到答案,所有费话我就不多说了。
这段代码我也没有怎么看明白。
只知道核心的一段是:
while (z++) try {
eval(y.replace(/\\b\\w+\\b/g, function (y) {
return x[f(y, z) - 1] || ("_" + y)
}));
consolt.log(result)
break
} catch (_) {
}
在原来内容中把上一段改成:
while (z++) try {
var result; # 增加
result = (y.replace(/\\b\\w+\\b/g, function (y) { # 改变
return x[f(y, z) - 1] || ("_" + y)
}));
consolt.log(result)
break
} catch (_) {
}
result; # 增加的目的是为了得出结果
然后在python使用js2py执行js代码会得到如下结果:
<script>
setTimeout('location.href=location.pathname+location.search.replace(/[\?|&]captcha-challenge/,\'\')', 1500);
document.cookie = '__jsl_clearance=1552284686.928|0|' + (function () { # 这一段js的字符串拼接明显是我们想要的内容
var _32 = [((2 << -~{}) + [] + [[]][0]), ((+[]) + [[]][0]), (7 + [[]][0]), (-~-~![] + []), [(+!-{})] + ((2 << -~{}) + [] + [[]][0]), [(+!-{})] + ((+[]) + [[]][0]), [(+!-{})] + (-~-~![] + []), [(+!-{})] + (6 + [] + [[]][0]), [((+!-{}) + [~~!/!/]) / [-~![] - ~![]]], [(+!-{})] + (-~[-~![] - ~![]] + [] + [[]][0]), [(+!-{})], (6 + [] + [[]][0]), [-~![] - ~![] + [-~![] - ~![]] * ((((+!-{}) << (+!-{})) ^ -~![]))], (-~[-~![] - ~![]] + [] + [[]][0]), [((+!-{}) << (+!-{})) + ((+!-{}) << (+!-{})) - ~((-~![] - ~![] << -~{}))], [(+!-{})] + [(+!-{})], [(+!-{})] + [((+!-{}) + [~~!/!/]) / [-~![] - ~![]]]];
for (var _20 = 0; _20 < _32.length; _20++) {
_32[_20] = [[!-{} + [[]][0]][0].charAt((+!-{})) + ({} + [[]][0]).charAt(((+!-{}) << (+!-{})) + ((+!-{}) << (+!-{})) - ~((-~![] - ~![] << -~{}))), 'm', (-~-~![] + []), [-~![] - ~![] + [-~![] - ~![]] * ((((+!-{}) << (+!-{})) ^ -~![]))] + ((+[]) + [[]][0]), 'AmJ', 'XSMm', [[((+!-{}) << (+!-{}))] / ~~!/!/ + [[]][0]][0].charAt(-~~~{} + ((+!-{}) << (+!-{})) - ~~~{} + ((+!-{}) << (+!-{}))), 'Gq%', 'wPSg', '%', [{} + [] + []][0].charAt([(+!-{})] + ((+[]) + [[]][0])), (-~[-~![] - ~![]] + [] + [[]][0]), 'CT', (!!window['_p' + 'hantom'] + [] + [[]][0]).charAt(~~'') + (+[(+!!window['_p' + 'hantom']), (+!!window['_p' + 'hantom'])] + [] + []).charAt(-~-~![]), 'B', 'D', [((+!-{}) + [~~!/!/]) / [-~![] - ~![]]] + [(+!-{})]][_32[_20]]
};
console.log("return",_32.join(''))
return _32.join('')
})() + ';Expires=Mon, 11-Mar-19 07:11:26 GMT;Path=/;'
console.log(document.cookie)
if ((function () {
try {
return !!window.addEventListener;
} catch (e) {
return false;
}
})()) {
document.addEventListener('DOMContentLoaded', _32, false)
} else {
document.attachEvent('onreadystatechange', _32)
</script>
按如下代码执行,可得到最终结果
import re
imort js2py
def get_cookie(html):
# print("in get cookie")
begin1 = time.time()
js_1 = re.findall("<script>(.*?)</script>",html, re.S)[0] # 正则匹配出第一次js代码
js_1 = js_1.replace('eval', 'var a;a=') + ";a;" # 对匹配出来的js结果 进行改装
result_1 = js2py.eval_js(js_1) # 执行 js代码
js_2 = re.findall("cookie=(.*?)};if\(\(", result_1, re.S)[0] # 在结果中匹配出我们需要的内容
result_2 = js2py.eval_js(js_2) # 第二次执行js代码
print('执行js代码耗时:',time.time()-begin1)
return result_2
得到的结果如下:
__jsl_clearance=1552387887.385|0|OUhENikGDlaAwRWUZRWG172lkAU%3D;Expires=Tue, 12-Mar-19 11:51:27 GMT;Path=/;
O了,加入cookie,可正常得到html源码!