题目内容
任务六:采集全部5页的彩票数据,计算全部中奖的总金额(包含一、二、三等奖)
初步分析
1 | GET https://match.yuanrenxue.com/api/match/6?m=OTfA1luzknp0JvTbZefBFolpU8kdVfMeLq6RaU9C1dOQVziK8tm6EX0hBWXAt954thxjgweOHgz6hpWdBXyynIQdeabEpcCoe7y4ERhA112WBzgniwiXZdRoFLqf%252B%252BhHgOsn%252FXJxPcZHHuNB3XbBUGFvK6uFBOmeVB5OMCCqkoE%253D&q=1-1651903761000%7C HTTP/1.1 |
返回内容:
1 | HTTP/1.1 200 OK |
初步结论,应该就是提交参数存在加密,返回时明文
深度分析
捕捉请求,对发起请求的堆栈进行分析
非常明显,m和q的生成位置都在于此,可以打个断点,查看如何生成。
首先对m进行分析,断点后发现t应该是一个时间戳,而o应该是一个常数,具体不清楚,继续查看r函数的定义
从上面的代码来看,o应该是点击上一页和下一页所触发加一的操作,并且大于6时,整个网页会进行重新加载,使其o变成1,而r最终调用的应该是z,z应该是一种加密函数。
上面的代码来看,几乎没有任何混淆,那直接用一种暴力手法,全部复制下载在本地加载,最后附加一个console的输出!
强制运行后会发现有问题,emm…下面进入正题了,对模糊点进行分析!
1.表情加密
在代码最前面出现了一堆颜文字,这种俗称表情加密,正常人成aaencode加密
解决方案很好使,因为最终还是要放入解释器解释,所以要么在控制台二次输出,要么就是随便一个解密网站也行,比如(这个网站)[https://www.qtool.net/decode]
解密后,执行代码很简单如下
1 | window.o = 1; |
2.window 坑
正常情况下,在node环境运行,没有window环境很正常,补环境也很正常,比如下面几种方法
1 | window = {} |
但是,补完后出现这种情况,提示xxx不存在
ok,那就找到关于ASN1的地方,搜索大法
ASN1应该是一个全局变量,但是最后丢失了,原因经过一系列断点,原因在此
解决方案,去掉就好了。。。。把window重置了,浏览器环境没有影响,但是对于node环境有影响
3.加密坑
继续运行,输出了该错误
继续断点在问题出现的地方
发现node环境与浏览器环境不同,浏览器环境是128,而node下是0
调用堆栈,e来源于pe,但似乎没什么用,折叠代码,找下关于this.n
发现此处存在jsFuck混淆加密,还原
还原结果
1 | false; |
应该就是由于本地无法解析该语句
4.生成坑
经过上述运行,已经得到加密结果,比如
1 | console.log(z(1651903761000,1)) |
这时候问题又来了,每次运行都是得到上面的结果
浏览器运行,每次结果都不一样
出现这个问题,我陷入了很大的迷茫,,,本质上这是一个rsa加密没错,作者经过了魔改rsa,rsa每次加密结果都不一样确实,然后就是不断地调试调试。。。
后面发现一个事情,我每次都是重新运行,浏览器下是持续keep life状态
那么,尝试一下
发现,每次结果都不一样了,而且和浏览器对应上了,卒。
5.风控坑
经过一些列操作,封装发现风控问题了
这个时候我就很无语了,利用fiddle直接抓包,重放发现浏览器也是风控,这时候怀疑服务端校验了重放请求。
那就直接拦截fd的包,然后复制到requests里面请求,也是风控。
ok,这个时候怀疑时间问题。果然,拦截后时间如果长了点再运行放出来就会风控,而且时间只有2秒。
这个时候陷入了矛盾之中,后面想到上一个坑的状态必须时持续,于是找了个node_vm。。。。
1 |
|
果然,通过…
1 | > python -u "c:\Users\lenovo\Desktop\js攻防\回溯\temp.py" |
6.结果坑
回过头,发现返回的对应上网页的三等奖,而题目要求的时一等奖、二等奖、三等奖的总和
好家伙,于是又跟了下网页前端代码
关键处
1 | success: function(data) { |
很明显,关键处在这
1 | html += puq.replace('caipiaohao', caipiao).replace('date_twice', arg * window.page + 2020097).replace('date_value', '0' + window.page).replace('result_value3', val.value).replace('total_value', val.value * 24).replace('result_value2', val.value * 8).replace('result_value1', val.value * 15); |
解释一下,当前行的总和时三等奖乘以24(val.value * 24)
于是,顺利通关
最后
说一句,我服了风控这个老六…