bbp代码python_Python反反爬之JS混淆---回溯

写在前面

Python反反爬系列

题目

fbe7857a9af561a20bdbe8554c987ed5.png

题目网站,点我去刷题

采集全部5页的彩票数据,计算全部中奖的总金额(包含一、二、三等奖)

分析网页

老规矩,我们还是首先打开刷题网站,接着打开谷歌调试工具

查看【XHR】里面的内容

0e770953283a90b59b0f26052aa46d1d.png

可以发现通过Ajax的方式,返回了一串数据

对比网页的数字,不难发现,这些返回的数据,是页面的三等奖金额

但是,这道题让我们求的是一等奖,二等奖,三等奖的总金额

做了几道猿人学的题目,我们可以猜测,总金额可能会通过JS代码生成

这个问题,我们先留着,继续分析一下返回数据的这个URL

7f37180059082700a09e236a50c11182.png

通过观察,我们可以发现,URL中带了两个参数,一个【 m 】的加密参数,还有一个【 q 】的参数,【 q 】的参数值与时间戳类似

所以说,要想正常访问,肯定要先算出【 m 】和【 q 】的值

m 和 q的值,从何而来

我们知道上面提到的请求是通过Ajax请求返回的,这里可以分享给大家一个小技巧

在谷歌浏览器的调试工具中,我们可以通过下图的方式,直接进入到AJax的代码部分

48bb0b11829baaaca4e93a1ce1d97db8.png

620fd7bcff4af34fdde2140e7ec3ce5f.png

ec2fbfd5798d5f91973be38fc65a1778.png

来到这个页面,Ajax上面定义的一个数组,引起了我的注意,我们将它扣下来

var list = {

"page": window.page,

"m": r(t, window.o),

"q": window.i += window.o + '-' + t + "|",

};

看到这段代码,我相信大家已经大概明白了 m 和 q的值,从何而来

page:页码,因为我们请求的第一页,所以在URL中省略了,但是从第二页开始page就会出现

m:通过调用r函数,并传入,【t】和【window.o】参数,得到一串加密后的密文

q:通过 += 的方式,可以累加得到一串字符串

我们截取一段 【q】的值分析一下,window.i和window.o已经 t 是什么

q: 1-1610261917000|

通过对比我们可以发现

window.i就是这串值

window.o是1

t就是时间戳

但是,这个 += 符号有什么用呢?

我们多次请求一下第二页和第三页,你就明白啦

q: 1-1610261917000|2-1610264287000|3-1610264288000|

这是我请求第一页,第二页,第三页后,【q】的值

这个时候,可能就有小伙伴会说,window.o就是页码的值

但是,当我在第三页回到第一页的时候,【q】的值是这样的

q: 1-1610261917000|2-1610264287000|3-1610264288000|4-1610264345000|

所以说,window.o的值其实很简单,并不是页码的值,而是点击页面发起Ajax请求的次数罢了

明白了【t】和【window.o】的含义,我们就明白了通过调用r函数传入的参数是什么了

[scode type="blue"]现在我们知道了【q】值的生成过程,而【m】只知道一部分,所以我们的下一步就是寻找r函数[/scode]

寻找r函数

我们在r函数出现的哪一行代码,打一个断点

b651f7e41efbffe4275f36c99a7aa45b.png

接着按CTRL+R,刷新一下页面

我们会发现代码卡在了769这一行,我们点击右上角的箭头继续往下运行

deabea3a0adc7e2e5f4243e120e474f5.png

这个时候,代码就卡在了r函数这一行,我们点击右上角如下图的这个按钮,就可以进入到包含r函数的JS文件中,这也是题目所提到的 【 回溯 】

96f91479be075f5550e1ca72f4f17733.png

093af86e0eeac4acffc36200de706610.png

[scode type="blue"]就是这么简单,我们很顺利的找到了r函数,接着我们将代码扣下来分析一下[/scode]

分析r函数

function r(param1, param2) {

if (window.o >= 6) {

alert('不要戳这么多下,人家好痛嘛~');

location.reload();

}

return z(param1, param2);

}

代码中,出现了一个if判断, 而判断中的内容就是,如果Ajax请求(也就是点击页面中页码的次数,当然首次进入页面是默认发起了一次请求的)大于或者等于6次的话,页面就会出现如下图的弹窗,紧接着执行location.reload()函数,而这个函数,我们在前面的题目中也碰到过,就是刷新整个页面,window.o的值也会重置为1

e1f6438228d155c0e5833826db74f86f.png

接着将传入的参数,二次传递给z函数并执行

我们来看一下z函数中的代码

function z(pwd, time) {

var n = _n("jsencrypt");

var g = (new n);

var r = g.encode(pwd, time);

return r;

}

这段代码的注意内容是:

实例化了jsencrypt对象

使用jsencrypt中的encode方法,进行了加密,并且返回,也就是【m】的值

jsencrypt就是一个基于rsa加解密的js库,反正就是一段操作,返回一段密文,感兴趣的同学可以自行百度,我这里就不展开讲了

我们就可以通过运行这个JS文件,从而得出m的值

到这里,相信大家已经明白了m 和 q的值,都是怎样产生的了

但是,在包含r函数的JS文件中,是有混淆过的代码的

大致浏览一下文件中的代码你就会发现这样三处混淆代码

dc6796e28869b000d4038545d427bdc6.png

11cc6db343e40ab64af07b4df6335af9.png

4de26db4a6338b77289710872ca16e53.png

所以说, 要想通过JS文件得出m的值,就需要先将混淆的代码翻译过来

翻译混淆过的代码

通常像这种混淆过的代码,如果不是一个函数的话,我们是可以通过谷歌调试工具中的Console,运行出结果的

比如说这段混淆代码,其实就是JS中的一些运算

[][(![] + [])[!+[] + !![] + !![]] + ([] + {})[+!![]] + (!![] + [])[+!![]] + (!![] + [])[+[]]][([] + {})[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]] + (![] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+[]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (!![] + [])[+[]] + ([] + {})[+!![]] + (!![] + [])[+!![]]]((+!![] + []) + (!+[] + !![] + !![] + !![] + !![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![] + []) + (+!![] + []) + (!+[] + !![] + !![] + !![] + !![] + []) + (+[] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![] + []) + (+[] + []))(!+[] + !![] + !![] + !![] + !![] + !![] + !![]) == ([][(![] + [])[!+[] + !![] + !![]] + ([] + {})[+!![]] + (!![] + [])[+!![]] + (!![] + [])[+[]]][([] + {})[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]] + (![] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+[]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (!![] + [])[+[]] + ([] + {})[+!![]] + (!![] + [])[+!![]]]((+!![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![] + []) + (!+[] + !![] + []) + (+!![] + []) + (!+[] + !![] + !![] + !![] + !![] + []))(!+[] + !![] + !![] + !![] + !![] + !![]) & [][(![] + [])[!+[] + !![] + !![]] + ([] + {})[+!![]] + (!![] + [])[+!![]] + (!![] + [])[+[]]][([] + {})[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]] + (![] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+[]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (!![] + [])[+[]] + ([] + {})[+!![]] + (!![] + [])[+!![]]]((+[] + []) + [][(![] + [])[!+[] + !![] + !![]] + ([] + {})[+!![]] + (!![] + [])[+!![]] + (!![] + [])[+[]]][([] + {})[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]] + (![] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+[]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (!![] + [])[+[]] + ([] + {})[+!![]] + (!![] + [])[+!![]]]((!![] + [])[+!![]] + ([][[]] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + ([][[]] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+!![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![] + !![] + !![]] + ([][[]] + [])[+[]] + ([][[]] + [])[+!![]] + ([][[]] + [])[!+[] + !![] + !![]] + (![] + [])[!+[] + !![] + !![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (+{} + [])[+!![]] + ([] + [][(![] + [])[!+[] + !![] + !![]] + ([] + {})[+!![]] + (!![] + [])[+!![]] + (!![] + [])[+[]]][([] + {})[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]] + (![] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+[]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (!![] + [])[+[]] + ([] + {})[+!![]] + (!![] + [])[+!![]]]((!![] + [])[+!![]] + ([][[]] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + ([][[]] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+!![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![] + !![] + !![]] + (![] + [])[!+[] + !![]] + ([] + {})[+!![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (+{} + [])[+!![]] + (!![] + [])[+[]] + ([][[]] + [])[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]])(+!![]))[!+[] + !![] + !![]] + ([][[]] + [])[!+[] + !![] + !![]])(!+[] + !![] + !![] + !![] + !![])([][(![] + [])[!+[] + !![] + !![]] + ([] + {})[+!![]] + (!![] + [])[+!![]] + (!![] + [])[+[]]][([] + {})[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]] + (![] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+[]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (!![] + [])[+[]] + ([] + {})[+!![]] + (!![] + [])[+!![]]]((!![] + [])[+!![]] + ([][[]] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + ([][[]] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+!![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![] + !![] + !![]] + ([][[]] + [])[!+[] + !![] + !![]] + (![] + [])[!+[] + !![] + !![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (+{} + [])[+!![]] + ([] + [][(![] + [])[!+[] + !![] + !![]] + ([] + {})[+!![]] + (!![] + [])[+!![]] + (!![] + [])[+[]]][([] + {})[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]] + (![] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+[]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (!![] + [])[+[]] + ([] + {})[+!![]] + (!![] + [])[+!![]]]((!![] + [])[+!![]] + ([][[]] + [])[!+[] + !![] + !![]] + (!![] + [])[+[]] + ([][[]] + [])[+[]] + (!![] + [])[+!![]] + ([][[]] + [])[+!![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![] + !![] + !![]] + (![] + [])[!+[] + !![]] + ([] + {})[+!![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (+{} + [])[+!![]] + (!![] + [])[+[]] + ([][[]] + [])[!+[] + !![] + !![] + !![] + !![]] + ([] + {})[+!![]] + ([][[]] + [])[+!![]])(+!![]))[!+[] + !![] + !![]] + ([][[]] + [])[!+[] + !![] + !![]])(!+[] + !![] + !![] + !![] + !![] + !![] + !![] + !![])(([] + {})[+[]])[+[]] + (!+[] + !![] + !![] + !![] + !![] + !![] + !![] + []) + (!+[] + !![] + !![] + !![] + !![] + !![] + !![] + !![] + [])) + ([][[]] + [])[!+[] + !![]] + ([][[]] + [])[!+[] + !![] + !![]] + (+{} + [])[+!![]] + ([][[]] + [])[!+[] + !![]] + ([] + {})[!+[] + !![]] + ([][[]] + [])[!+[] + !![] + !![]] + ([][[]] + [])[!+[] + !![] + !![]] + ([][[]] + [])[!+[] + !![] + !![] + !![]] + ([] + {})[!+[] + !![] + !![] + !![] + !![]] + (+{} + [])[+!![]] + ([][[]] + [])[!+[] + !![] + !![] + !![]] + ([][[]] + [])[!+[] + !![] + !![]])(!+[] + !![] + !![]));

将这些代码输入到Console中,就可以得出结果

f65d9870612115586c619b40f4e58862.png

在这道题目的三处混淆中,都可以通过这种方式翻译出来

而第一张图片的混淆,其实很有意思,看着也挺有意思的

它这种属于JavaScript的表情包加密,我们可以通过这个网站进行翻译解密工具

将需要解密的代码复制过去,然后点击aaencode解密,就可以得到结果【window.o = 1;】

becb241738444932b42b1cf497437a03.png

我这里就不放结果的截图,大家可以去试一试

还有一处混淆过的代码,你可以通过Console得出结果,我这里就不再赘述

全部翻译完成后,我们将结果与混淆的代码进行替换,接着道鬼鬼调试工具进行测试验证

验证加密结果

我们将处理过的代码粘贴到鬼鬼调试工具中

然后,在前面的地方,加一行代码 var window = this;

因为在代码中,很多地方用到了 window 变量,不声明的话,会报错

f1f779aa2cbcd5355a2f11bddaae4edc.png

在上面的截图中,可以发现我注释了一行代码 //window = {};

这行代码就是将window变为空,上面我也提到了,很多地方都需window,所以要将其注释

接着,我们加载全部代码,传入参数执行r函数,可以发现得到了我们想要的结果

60b1c5d8d5fd9aa11e45acaa0538fd50.png

[scode type="blue"]到目前为止,我们已经可以通过Python代码得到【m】和【q】的值了,但是还有一个问题我们还没有解决[/scode]

求出中奖总金额

在文章开头,我们还留着一个问题

AJax返回的数据,是页面的三等奖金额

但是,这道题让我们求的是一等奖,二等奖,三等奖的总金额

所以,我们回到Ajax代码中(截取了部分代码)

如果你对Ajax的内容不是很熟悉的话,可以看看我这篇文章Python反反爬之CSS加密---样式干扰

在这篇文章中,我对ajax部分的代码解释得很详细,这里我就不多赘述

$.ajax({

url: window.url,

dataType: "json",

async: false,

data: list,

type: "GET",

beforeSend: function (request) {},

success: function (data) {

if (window.page) {}

else {

window.page = 1

}

// 请求成功后返回的数据,也就是页面中三等奖的金额

data = data.data;

let html = '';

let arg = 1;

let puq = `

date_twice2020-10-date_valuecaipiaohaototal_valueresult_value1result_value2result_value30`;

let arr_arg = [1, 8, 7, 3, 5, 7, 10, 2, 9, 4];

// 通过循环三等奖的金额,进行一系列的操作,呈现出页面的各种数值

// 我们可以不用详细的去分析,直接看下面的replace部分

$.each(data, function (index, val) {

let caipiao = `

arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8`;

let arr = [5, 1, 7, 6, 3, 2, 4, 7];

for (let c = 1; c <= 8; c++) {

caipiao = caipiao.replace('arg' + c, (Math.floor(((arr_arg[arg] << 2) / 5 + c) * c / 3) + 1) + arr[window.page])

}

// 这里的代码,主要是将页面的数值进行替换

html += puq.replace('caipiaohao', caipiao)

.replace('date_twice', arg * window.page + 2020097)

.replace('date_value', '0' + window.page)

.replace('result_value3', val.value)

// total_value 指的就是页面中的 总销售额字段

// val.value 指的就是 三等奖金额

// 也就是说,总销售额,就是三等奖的金额乘以24

.replace('total_value', val.value * 24)

// result_value2 二等奖

.replace('result_value2', val.value * 8)

// result_value1 一等奖

.replace('result_value1', val.value * 15);

arg += 1

});

$('.resbbp').text('').append(html)

}

[scode type="blue"]通过上述代码的注释,我们可以知道,每一行的总销售额,也就是我们所求的总金额,其实就是三等奖的金额乘以24[/scode]

[scode type="green"]所以,我们就可以获取每页的三等奖金额总和,最后乘以24就可以得出这道题目的答案 ::aru:pouting:: [/scode]

解出答案

在写Python代码之前,我们还需要完成最后一个步骤

7f37180059082700a09e236a50c11182.png

我们知道想要正常请求URL拿到数据,需要三个参数(page,m,q)

而前面我们翻译完成的JS文件,返回的结果只有m的值,而没有返回时间戳

所以,我们只需要将z函数改下一下即可

// 修改前

function z(pwd, time) {

var n = _n("jsencrypt");

var g = (new n);

var r = g.encode(pwd, time);

return r;

}

// 修改后

function z(pwd, time) {

var n = _n("jsencrypt");

var g = (new n);

var r = g.encode(pwd, time);

var answer_arr = [r,pwd]

return answer_arr;

}

现在,我们就可以愉快的写Python代码,爬取数据,解出答案啦

由于JS文件代码太多(2000多行),我就不粘贴出来,点击我可以进行下载

# @BY     :Java_S

# home.php?mod=space&uid=238618   :2021/1/10 13:36

# @Slogan :够坚定够努力大门自然会有人敲,别怕没人赏识就像三十岁的梵高

import time

import execjs

import requests

def get_cipher(timestamp, page):

# 导入JS,读取需要的js文件

with open(r'JS/js6.js', encoding='utf-8', mode='r') as f:

JsData = f.read()

# 加载js文件,使用call()函数执行,传入需要执行函数即可获取返回值

[cipher, limit] = execjs.compile(JsData).call('get_cipher', timestamp, page)

limit = f'{page}-' + str(timestamp) + '|'

return cipher, limit

def get_data(page):

cipher, limit = get_cipher(int(time.time()) * 1000, page)

url = 'http://match.yuanrenxue.com/api/match/6'

params = {

'page': page,

'm': cipher,

'q': limit

}

headers = {

'Host': 'match.yuanrenxue.com',

'Referer': 'http://match.yuanrenxue.com/match/6',

'User-Agent': 'yuanrenxue.project',

}

response = requests.get(url=url, headers=headers, params=params)

answer = [i['value'] for i in response.json()['data']]

print(f'第{page}页的三等奖:{answer}')

return answer

if __name__ == '__main__':

total = []

for i in range(1,6):

total += get_data(i)

total = sum(total)*24

print(f'五页中奖的总金额:{total}元')

bac8019c1741b3ed8e3cfa08e406e56f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值