入门反爬攻坚考试
第一题
打开页面 https://www.aqistudy.cn/
实现接口 https://www.aqistudy.cn/apinew/aqistudyapi.php
的正常请求并获取明文响应
分析
- 开着
F12
进页面 - 遇到无限debugger 一个
never pause here
下去 - 关闭所有断点
Activate breakpoint(Ctrl + F8)
,随便逛逛网站找找目标接口 - 找到了如上图,简单分析一下接口
response
内容同样为一长串加密字符- 重放请求,发现
payload
和response
都不变 - 请求类型为
XHR/fetch
,直接打断点开抓
扣代码
- 先搞定加密,定位到
pov0M2gfR
这个函数 - 简单扣一下代码,缺啥找啥,这题很简单,随便扣了两个文件
2000
行,入参加密就破解成功了 - 再搞解密,定位到了
deIZLF7oahc0DLiXbqt
这个函数 - 然后发现这个函数已经在扣加密的时候也已经扣过了,可以直接调,至此,加解密的破解我们就完成了
模拟请求
import execjs
import requests
from pathlib import Path
import json
project_dir = Path(__file__).resolve().parent
file = f'{project_dir}\\入参.js'
ctx = execjs.compile(open(file, encoding='utf-8').read())
url = "https://www.aqistudy.cn/apinew/aqistudyapi.php"
headers = {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
}
for city in ['广州', '深圳', '杭州', '北京', '上海', '南京', '重庆']:
ret = {
'city': city,
'type': 'HOUR',
'startTime': '2024-06-14 08:00:00',
'endTime': '2024-06-14 09:00:00'
}
params = ctx.call('encrypted', ret)
data = {"hXhY1B2Kd": params}
res = requests.post(
url=url,
headers=headers,
data=data
)
if res.status_code == 200:
text = res.text.strip()
data = ctx.call('deIZLF7oahc0DLiXbqt', text)
print(city, json.loads(data))
else:
print(res.text)
第二题
打开页面 https://xunkebao.baidu.com/#/searchList?searchValue=%E4%BA%BF%E7%BA%AC%E9%94%82%E8%83%BD&searchTab=all
搜索 亿纬锂能
找到接口https://xunkebao.baidu.com/crm/web/dgtsale/bizcrm/enterprise/search
用 3
种方法快速定位到接口中 headers
里的 Acs-Token
参数加密位置
方法一
Acs-Token
并非常见的参数名称,那么我们直接全局搜索,打上断点一步到位
方法二
- 该接口请求类型为
xhr
,一个XHR/fetch
断点先断到该请求处(此处没找到接口dgtsale
,找到了和题目描述一致的bizcrm
) XHR
直接断在了这里,此时我们打印一下参数,会发现还没有出现我们所需要的值。于是我们Step out of current function
往后跟一跟
方法三
Acs-Token
参数既然在headers
当中,那么我们通过hook headers
的方式跟踪headers
的赋值操作Step out of current function
往出跟一跟,也到了这个地方
追踪后续
- 根据上述三种方法找到该值出现的地方,我们从
C3
往下追到getSign
- 往下跟,加密位置应该就是这里了,入参挨个执行完
pe.gs
生成结果,这块好像都是异步调用还有箭头函数什么
第三题
解决题目 https://match2023.yuanrenxue.cn/topic/4
,给出详细可行的解决思路
分析
- 先简单分析一下请求,发现
payload
有两个参数,一个page
,一个yt4
,且每个请求无法重放,可知我们只要搞定yt4
这个参数,就可以解决该问题 - 该请求系
XHR
,直接用Initiator
跟过去,可以发现yt4
就是在match4.js
这里算出来的 - 跟着往里面扣一下,会发现实际入参只有两个,一个是固定字符串
YtNMIT/vOuJkScU6ZqG+zY3tfyyrHuzHO4glJQaz/OU=
,和一个13
位的时间戳。经过了函数_$IU
调用得到一个44
位的字符串,如y2GObvzkjaUVRtsHpldmFPmd2GXSdm0CE4OoX4ZSVmVn
- 然后这个
44
位的字符串和固定字符串YtNMIT/vOuJkScU6ZqG+zY3tfyyrHuzHO4glJQaz/OU=
和13
位的时间戳再走一遍_$pa[_$ya](_$wa, _$Ua)
即可取得最终的yt4
,如图8、9所示 - 最后【未经验证】这个请求一定要快,推测是慢了时间戳和服务端校验不一致会
403
注:经前辈指教,以上分析都是错的,该请求成功与否与参数 yt4
无关,而是由该请求的前后的请求决定。
第四题
打开页面 https://music.163.com/
,搜索 周杰伦
找到接口 https://music.163.com/weapi/cloudsearch/get/web?csrf_token=
实现该接口中的 params
和 encSecKey
算法,成功访问该接口并获取到正确数据
分析
- 接口请求类型
XHR
,一个断点直接打上去,然后看看堆栈,搞一下红框里的几行代码,入参可变的其实也就i0x
里一个搜索词
扣代码
- 首先去扣
window.asrsea
,直接跟踪定位到d
这里,前后非匿名函数扣一扣,缺啥找啥,很容易就可以在本地运行了 - 整理一下函数命名,将死参数直接写入函数内部
模拟请求
- 最后拿着我们得到的参数去模拟请求,成功获取响应,过关
第五题
打开页面 https://www.ynjzjgcx.com/register/process?type=
获取验证码,代码实现触发的滑块验证码流程,破解通过率高于 80%
分析
- 模拟一遍过程,其请求了两个接口:
- 第一步通过一个
params
参数请求了https://www.ynjzjgcx.com/prod-api/mohurd-pub/vcode/genVcode
,在手机号相同的条件下每次请求的params
不同,且其为一个172
位的字符串 - 第二步通过滑块后同样通过一个
params
参数请求了https://www.ynjzjgcx.com/prod-api/mohurd-pub/sms/sendVCodeSms
,且其也为一个172
位的字符串,有理由推测是同一种加密方式
- 第一步通过一个
XHR
请求,直接用Initiator
跟过去瞅瞅,一下就找到了这两个显眼包,入参为一个手机号- 往下简单跟几步之后发现了几个加密函数,最终结果很像最后要的
params
,重复几次请求验证证实确实如此
扣代码
- 然后我们去扣一下这里面的两个加密函数
W_e
和X_e
,W_e
是一个key=B6*40.2_C9#e4$E3
的sm4
加密算法,X_e
应该是一个rsa
加密算法 - 关于这个
rsa
加密临近交卷最核心的nextBytes
以及之后的doPublic
函数扣了很多但确实还是没有扣下来,其它部分均已知悉,详见下图