@本文来源于公众号:csdn2299,喜欢可以关注公众号 程序员学府
这篇文章主要介绍了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