Python利用PyExecJS库执行JS函数的案例分析

  在Web渗透流程的暴力登录场景和爬虫抓取场景中,经常会遇到一些登录表单用DES之类的加密方式来加密参数,也就是说,你不搞定这些前端加密,你的编写的脚本是不可能Login成功的。针对这个问题,现在有三种解决方式:

  • ①看懂前端的加密流程,然后用脚本编写这些方法(或者找开源的源码),模拟这个加密的流程。缺点是:不懂JS的话,看懂的成本就比较高了;
  • ②selenium + Chrome Headless。缺点是:因为是模拟点击,所以效率相对①、③低一些;
  • ③使用语言调用JS引擎来执行JS函数。缺点是:每个JS引擎执行的效果会不一致,导致一些小偏差;
  •   第③种方式中,Python语言能利用的库有PyExecJS、PyV8、Js2Py三种,PyV8使用就报错(我暂时没解决),Js2Py相当于将JS翻译成Pyhton,Js2Py对于复杂JS而言非常容易出错。所以本文主要讨论通过Python语言的PyExecJS库(切换不同的JS引擎)来执行JS函数的过程。

PyExecJS官网案例

pip 安装:

pip install PyExecJS

Demo:

import execjs

print(execjs.eval("'red yellow blue'.split(' ')"))

ctx = execjs.compile("""
  function add(x, y) {
   return x + y;
  }
 """)
print(ctx.call("add", 1, 2))

输出:

['red', 'yellow', 'blue'] 3

查看JS引擎信息

# 1.在windows上不需要其他的依赖便可运行execjs, 因为默认有个JScript库,如果要运行其他JS引擎库,就需要另外安装了。
 # windows默认执行的JS环境
  execjs.get().name
  #返回值: JScript
 # 如果想要切换,用os.environ["EXECJS_RUNTIME"] = "XXX",如果刚安装完其他JS引擎,必须配置环境变量,还可能需要重启电脑或重启IDE。
 # 如果windows上装有Node.js , 可以切换Node
  os.environ["EXECJS_RUNTIME"] = "Node"
  print(execjs.get().name)
  #返回值: Node.js (V8)
 # 如果windows上装有PhantomJSs , 可以切换PhantomJS
  os.environ["EXECJS_RUNTIME"] = "PhantomJS"
  print(execjs.get().name)
  #返回值: PhantomJS

# 2.在ubuntu下需要安装执行JS环境依赖, 作者的环境为PhantomJS
  execjs.get().name
  #返回值: PhantomJS

# 3.源码中给出, 可执行execjs的环境:
 PyV8   = "PyV8"
 Node   = "Node"
 JavaScriptCore = "JavaScriptCore"
 SpiderMonkey = "SpiderMonkey"
 JScript  = "JScript"
 PhantomJS  = "PhantomJS"
 SlimerJS  = "SlimerJS"
 Nashorn  = "Nashorn"

安装PhantomJS步骤

下载地址:

http://phantomjs.org/download.html

拷贝到脚本到你的Python环境里:

把下载下来的文件解压,找到目录里.\phantomjs-2.1.1\bin\下的phantomjs.exe,移动到使用的python文件夹下的Script中。

# 举例 Anaconda3
D:\programfiles\Anaconda3\Scripts

添加系统变量:

D:\programfiles\Anaconda3\Scriptsphantomjs.exe添加到系统变量中。

验证:

添加环境变量后,在cmd中验证可以使用phantomjs命令,说明环境搭建好了。

在python中切换成PhantomJS:

os.environ["EXECJS_RUNTIME"] = "PhantomJS"

案例1

1.访问目标网站的登录页面并查看源码

  访问 http://www.XXX.cn/login.html 查看一下在提交表单之前js对输入的账号、密码做了什么操作。(如下是伪代码)

<html>
<head></head>
<script src="http://www.XXX.cn/js/a.js"></script>
<script>
 function password(psw, code, acc) {
  return "[p]" + CryptoJS.e(CryptoJS.MD5(CryptoJS.MD5(CryptoJS.MD5(psw).toString() + code).toString()).toString() + "@" + acc, code);
 }

 function doencodeacc(acc, code) {
  alert("[p]" + CryptoJS.e(acc, code));
 }
 doencodeacc("zhansan123456","pYr6BTle");
</script>
<body>

</body>

</html>

2.将js放到和py脚本同一级目录下

  我将整个a.js文件都粘贴到这里,方便需要实验的同学。

/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k<a;k++)c[j+k>>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535<e.length)for(k=0;k<a;k+=4)c[j+k>>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e<a;e+=4)c.push(4294967296*u.random()|0);return new r.init(c,a)}}),w=d.enc={},v=w.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++){var k=c[j>>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j+=2)e[j>>>3]|=parseInt(a.substr(j,
2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++)e.push(String.fromCharCode(c[j>>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j++)e[j>>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}},
q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q<a;q+=k)this._doProcessBlock(e,q);q=e.splice(0,a);c.sigBytes-=j}return new r.init(q,j)},clone:function(){var a=t.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:t.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},_createHmacHelper:function(a){return function(b,e){return(new n.HMAC.init(a,
e)).finalize(b)}}});var n=d.algo={};return d}(Math);
(function(){var u=CryptoJS,p=u.lib.WordArray;u.enc.Base64={stringify:function(d){var l=d.words,p=d.sigBytes,t=this._map;d.clamp();d=[];for(var r=0;r<p;r+=3)for(var w=(l[r>>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v<p;v++)d.push(t.charAt(w>>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w<
l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();
(function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<<j|b>>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<<j|b>>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<<j|b>>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<<j|b>>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])},
_doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]),
f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f,
m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m,
E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/
4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math);
(function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length<q;){n&&s.update(n);var n=s.update(d).finalize(r);s.reset();for(var a=1;a<p;a++)n=s.finalize(n),s.reset();b.concat(n)}b.sigBytes=4*q;return b}});u.EvpKDF=function(d,l,p){return s.create(p).compute(d,
l)}})();
CryptoJS.lib.Cipher||function(u){var p=CryptoJS,d=p.lib,l=d.Base,s=d.WordArray,t=d.BufferedBlockAlgorithm,r=p.enc.Base64,w=p.algo.EvpKDF,v=d.Cipher=t.extend({cfg:l.extend(),createEncryptor:function(e,a){return this.create(this._ENC_XFORM_MODE,e,a)},createDecryptor:function(e,a){return this.create(this._DEC_XFORM_MODE,e,a)},init:function(e,a,b){this.cfg=this.cfg.extend(b);this._xformMode=e;this._key=a;this.reset()},reset:function(){t.reset.call(this);this._doReset()},process:function(e){this._append(e);return this._process()},
finalize:function(e){e&&this._append(e);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(e){return{encrypt:function(b,k,d){return("string"==typeof k?c:a).encrypt(e,b,k,d)},decrypt:function(b,k,d){return("string"==typeof k?c:a).decrypt(e,b,k,d)}}}});d.StreamCipher=v.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var b=p.mode={},x=function(e,a,b){var c=this._iv;c?this._iv=u:c=this._prevBlock;for(var d=0;d<b;d++)e[a+d]^=
c[d]},q=(d.BlockCipherMode=l.extend({createEncryptor:function(e,a){return this.Encryptor.create(e,a)},createDecryptor:function(e,a){return this.Decryptor.create(e,a)},init:function(e,a){this._cipher=e;this._iv=a}})).extend();q.Encryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize;x.call(this,e,a,c);b.encryptBlock(e,a);this._prevBlock=e.slice(a,a+c)}});q.Decryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize,d=e.slice(a,a+c);b.decryptBlock(e,a);x.call(this,
e,a,c);this._prevBlock=d}});b=b.CBC=q;q=(p.pad={}).Pkcs7={pad:function(a,b){for(var c=4*b,c=c-a.sigBytes%c,d=c<<24|c<<16|c<<8|c,l=[],n=0;n<c;n+=4)l.push(d);c=s.create(l,c);a.concat(c)},unpad:function(a){a.sigBytes-=a.words[a.sigBytes-1>>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a,
this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684,
1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})},
decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d,
b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}();
(function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8,
16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j<a;j++)if(j<d)e[j]=c[j];else{var k=e[j-1];j%d?6<d&&4==j%d&&(k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;d<a;d++)j=a-d,k=d%4?e[j]:e[j-4],c[d]=4>d||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>>
8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r<m;r++)var q=d[g>>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t=
d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})();function _k(h){var e=h+"0123456789abcdef";return e.substring(0, 16);}
CryptoJS.e = function (d,p) {
 var key = CryptoJS.enc.Utf8.parse(_k(p));
 var encrypted = CryptoJS.AES.encrypt(d, key, {
  iv: key,
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
 });
 return encrypted.toString();
};

function doencodepsw(psw, code, acc) {
   return "[p]" + CryptoJS.e(CryptoJS.MD5(CryptoJS.MD5(CryptoJS.MD5(psw).toString() + code).toString()).toString() + "@" + acc, code);
}

function doencodeacc(acc, code) {
 return "[p]" + CryptoJS.e(acc, code);
}

3. 编写Python脚本来调用js

import execjs

def get_js():
 # 打开JS文件
 f = open("a.js", 'r', encoding='utf-8')
 line = f.readline()
 htmlstr = ''
 while line:
  htmlstr = htmlstr + line
  line = f.readline()
 return htmlstr

def get_des_psswd(acc, code):
 jsstr = get_js()
 # 加载JS文件
 ctx = execjs.compile(jsstr)
 # 调用js方法 第一个参数是JS的方法名,后面的为js方法的参数
 return ctx.call('doencodeacc', acc, code)

if __name__ == '__main__':
 print(get_des_psswd("zhangsan123456", "pYr6BTle")) # pYr6BTle = ralt code (加密的盐值)

案例2

  这个案例相对会复杂一些;

1.找登录时的加密函数

看发包



  登录该站时,发现该网站先异步获取了一个公钥,然后账号跟密码都加密了,只能上调试了。建议调试都用Chrome F12,其它工具都不如他好使。

右键查看源码,发现有JS,但是太多了,过滤一下。

2.监听鼠标点击事件查看流程

一顿操作之后,跳到登录提交的函数,直接看代码

往下看看代码之后,发现代码没加混淆也没有其他防护,那就一步到位解决了,破解这个加密还不跟切菜一样简单了。

3.写代码

导入js:

将jsencrypt.js导入到python项目中,这个js有5千多行,我就不粘贴上来了。

import execjs
import os

if __name__ == '__main__':
 # 切换了JScript、Node后都无法执行JS,发现还是PhantomJS靠谱
 # os.environ["EXECJS_RUNTIME"] = "JScript"
 # os.environ["EXECJS_RUNTIME"] = "Node"
 os.environ["EXECJS_RUNTIME"] = "PhantomJS"
 print(execjs.get().name)

 js = open('jsencrypt.js', encoding='utf-8').read()
 jo = execjs.compile(js)
 pwd = jo.call('myf')
 print(pwd)

输出:

PhantomJS
Hu4Ujwqwe/PDAblIvjNyrX4NrltoRXXDdyC6+F+p0LaqPSegMZ16oIqeVPiHlh5x8zKeI2DC3DoPVf8ZlusUCQ==

不同浏览器内核版本对URL编码处理也不同[冷知识]

  当Html的表单被提交时,每个表单的参数都会被Url编码之后才能被发送。由于历史的原因,表单使用的Url编码实现并不符合最新的标准。例如对于空格使用的编码并不是%20,而是+号,如果表单使用的是Post方法提交的,我们可以在HTTP头中看到有一个Content-Type的header,值为application/x-www-form-urlencoded。大部分应用程序均能处理这种非标准实现的Url编码,但是在客户端Javascript中,并没有一个函数能够将+号解码成空格,只能自己写转换函数。还有,对于非ASCII字符,使用的编码字符集取决于当前文档使用的字符集。

总结

以上所述是小编给大家介绍的Python利用PyExecJS库执行JS函数的案例分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • Python如何调用JS文件中的函数

    Python 调用JS文件中的函数方法如下 1.安装PyExecJS第三方库 2.导入库:import execjs 3.调用JS文件中的方法 Passwd = execjs.compile(open(r"web.js").read().decode("utf-8")).call('loginHandle','steam') 语句解析,open后跟所执行的js文件位置,call后第一个单引号引起来的为所执行的js文件的某个function, 第二个单引号是前面函数的

  • Python Json模块中dumps、loads、dump、load函数介绍

    Json模块dumps.loads.dump.load函数介绍 1.json.dumps() json.dumps()用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数. import json name_emb = {'a':'1111','b':'2222','c':'3333','d':'4444'} jsObj = json.dumps(name_emb) print(name_emb) print(jsOb

  • Python中还原JavaScript的escape函数编码后字符串的方法

    遇到一个问题需要用Python把JavaScript中escape的中文给还原,但找了大半天,也没有找到答案,只好自己深入研究解决方案. 我们先来看在js中escape一段文字的编码 复制代码 代码如下: a = escape('这是一串文字'); alert(a); 输出: 复制代码 代码如下: %u8FD9%u662F%u4E00%u4E32%u6587%u5B57 咋一看,就感觉有点类似json格式,我们来看看标准的json格式编码同样的汉子"这是一串文字" 复制代码 代码如下:

  • Python利用PyExecJS库执行JS函数的案例分析

      在Web渗透流程的暴力登录场景和爬虫抓取场景中,经常会遇到一些登录表单用DES之类的加密方式来加密参数,也就是说,你不搞定这些前端加密,你的编写的脚本是不可能Login成功的.针对这个问题,现在有三种解决方式: ①看懂前端的加密流程,然后用脚本编写这些方法(或者找开源的源码),模拟这个加密的流程.缺点是:不懂JS的话,看懂的成本就比较高了: ②selenium + Chrome Headless.缺点是:因为是模拟点击,所以效率相对①.③低一些: ③使用语言调用JS引擎来执行JS函数.缺点是

  • python利用requests库模拟post请求时json的使用教程

    我们都见识过requests库在静态网页的爬取上展现的威力,我们日常见得最多的为get和post请求,他们最大的区别在于安全性上: 1.GET是通过URL方式请求,可以直接看到,明文传输. 2.POST是通过请求header请求,可以开发者工具或者抓包可以看到,同样也是明文的. 3.GET请求会保存在浏览器历史纪录中,还可能会保存在Web的日志中. 两者用法上也有显著差异(援引自知乎): 1.GET用于从服务器端获取数据,包括静态资源(HTML|JS|CSS|Image等等).动态数据展示(列表

  • python利用 keyboard 库记录键盘事件

    今天也不知道是想了什么,突然就想要试试看我有效击键时的手速到底有多快.为此,需要记录下来击键的记录.于是找到了 Python 的 keyboard 库. 安装非常简单,只需执行 pip install keyboard 即可. 键盘事件录制 保存并执行如下代码 import keyboard import time keyboard.hook(lambda e: print(e, time.clock())) keyboard.wait('Ctrl') 这里,我们利用 keyboard.hook

  • Python利用Matplotlib库实现绘制饼形图

    目录 1.plt.pie() 2. 饼图基本 3. 饼状图进阶 4. 环形图 5. 内嵌环形图 1.plt.pie() 饼图 常常用来显示 整体中各部分所占的比例,在python-matplotlib库中通过plt.pie()方法来实现. 其主要参数如下: x --------每一块饼图的比例组成的序列.可以是一个列表.如果其中元素的值加起来大于一,则会通过归一化处理后的结果. explode -------- 指每一块饼距离圆心的距离.默认为0.如果大于0,则饼即会分裂出来,即“分裂饼形图”效

  • python利用标准库如何获取本地IP示例详解

    标准库 Python拥有一个强大的标准库.Python语言的核心只包含数字.字符串.列表.字典.文件等常见类型和函数,而由Python标准库提供了系统管理.网络通信.文本处理.数据库接口.图形系统.XML处理等额外的功能. Python标准库的主要功能有: 1.文本处理,包含文本格式化.正则表达式匹配.文本差异计算与合并.Unicode支持,二进制数据处理等功能 2.文件处理,包含文件操作.创建临时文件.文件压缩与归档.操作配置文件等功能 3.操作系统功能,包含线程与进程支持.IO复用.日期与时

  • Python 利用pydub库操作音频文件的方法

    最近使用Python调用百度的REST API实现语音识别,但是百度要求音频文件的压缩方式只能是pcm(不压缩).wav.opus.speex.amr,这里面也就wav还常见一点,但是一般设备录音得到的文件都是mp3,这就要把mp3转换为wav,由于python的效率并不高,很多实现都是使用C++或者Java,不过GitHub上有一个项目pydub(https://github.com/jiaaro/pydub/tree/master/pydub)可以暂时解决问题. 安装pydub 直接执行以下

  • Python利用Turtle库绘制一个小老虎

    目录 导语 1.定义库以及初始化界面 2.画出左右两只耳朵 3.画出小老虎头部轮廓 4. 画出老虎的两只眼睛 5.画出老虎的鼻子和嘴巴 6.画出小老虎的左右肢体和脚趾 7.在需要的位置写上我们的新年祝福 8. 显示倒数3,2,1 9.显示我们需要的文字 10.设定代码运行入口,调用目标函数 成果展示 导语 哈喽铁汁们好久不见吖~小编已经复工了于是马不停蹄赶来给大家准备新年礼物算开工礼物吧! 海龟来作图 虎年就是要画老虎 2022不用纸和笔~ 今晚画老虎~ 一二三四五 老虎宝宝示意图 虎年怎么能少

  • Python利用Turtle库绘制一颗樱花树

    后唐李煜曾说道,樱花落尽春将困,秋千架下归时.漏暗斜月迟迟,花在枝.樱花落尽的时候春天也将过去了,秋千架下归去时.天上的斜月姗姗来迟,花还在枝头. 关于python画图相关的,我们一直使用的是turtle来画,用专业的非标准库来做专业的事儿.将需要使用到的内置库或者非标准库全部都导入到当前的代码块中. from time import sleep # 用于控制程序运行时的阻塞停顿 from turtle import * # 绘图相关接口 import random # 生成随机数 设置全局需要

  • python使用js2py库运行js代码

    目录 一.js2py库概述 二.抽取js代码运行结果 三.提取js语句内变量和对象等 四.其他 在日常使用Python做爬虫,一般会用到以下手段: 请求URL,返回HTML文本,然后通过xpath.css或者re,提取数据 有些网页的数据通过AJAX异步请求加载,此时找到对应的接口,调用并直接使用接口返回的数据 有时候如果网站反爬或安全机制比较高时,则会做一些验证或者加密,比如cookie内必须携带token等信息,而这些信息是通过混淆过的js代码计算得出的. 针对1,应该是爬取大多数没有任何安

  • Python利用pywin32库实现将PPT导出为高清图片

    目录 一.安装库 二.代码原理 三.使用效果 四.所有代码 一.安装库 需要安装pywin32库 pip install pywin32 二.代码原理 WPS高清图片导出需要会员,就为了一个这个小需求开一个会员太亏了,因此就使用python对ppt进行高清图片导出. 设置format=19即可: ppt.SaveAs(imgs_path, 19) 三.使用效果 输入一个文件路径 path = 'D:\\自动化\\课件.pptx' 最后的效果: 会在路径下创建一个‘’课件‘’文件夹 里面是所有转换

随机推荐