前言
各位看官好哇,近期没有发布新内容了,今天给大家带来一篇文字点选验证码的逆向实战,接下来开始正文。
一、定位验证码校验接口
1.1 触发验证码
首先,我们打开目标网站,找到文字点选验证码的位置:
1.2 抓取校验接口
打开开发者工具(F12),人为进行一次点选验证(可以故意验证失败),目的是抓取验证码的校验接口。下图红色箭头处就是本次验证码校验的接口:
1.3 查看请求参数
点击进入校验接口,在载荷中可以看到本次校验所需的请求参数。红框内的参数就是本次需要逆向分析的关键参数:
">
二、定位加密函数
2.1 通过启动器追踪调用链
在网络面板中点击校验接口,进入启动器菜单,找到 app 开头的 JS 文件并点击:
2.2 查看请求构建代码
点击后会自动跳转到对应的 JavaScript 函数位置,红框内就是本次校验验证码接口的请求参数构建代码:
2.3 添加断点
在关键位置添加断点,然后重新点选验证码触发校验接口:
2.4 单步执行
点击下图中箭头指向的按钮(单步跳过),继续执行到下一个断点处:
三、分析加密逻辑
3.1 理解 pointJson 的生成逻辑
我们先来看这行关键代码:
pointJson = t.secretKey ? o((0, n.default)(t.checkPosArr), t.secretKey) : (0, n.default)(t.checkPosArr)
在 JavaScript 中,?: 是一个三元运算符,意思是:
- 当
t.secretKey 为真值时,pointJson = o((0, n.default)(t.checkPosArr), t.secretKey)
- 否则,
pointJson = (0, n.default)(t.checkPosArr)
我们将鼠标悬停在 t.secretKey 上查看其值,可以看到 t.secretKey = "I6U2jTypdZgh5aCC",说明走的是第一个分支:
pointJson = o((0, n.default)(t.checkPosArr), t.secretKey)
3.2 跟进加密函数 o
接下来我们把鼠标移到 o 函数上,红框内显示了 o 方法的函数地址,点击即可跳转到该函数内部:
3.3 在加密函数内添加断点
跳转到 o 函数后,继续添加断点调试:
3.4 确认加密方式
继续单步执行,进入下一个断点:
到这里,我们可以看到:
- 加密内容:对应文字的坐标数据(
checkPosArr)
- 密钥来源:
t.secretKey(从 get 接口的响应中获取)
整个加密流程已经走通。可以看到它使用的是 AES 加密,加密模式为 ECB,填充方式为 Pkcs7。
四、Python 复现加密
接下来我们用 Python 来实现这个 AES 加密:
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
def encrypt_data(t, e):
"""
t: 待加密的明文(文字坐标)
e: 密钥
"""
i = e.encode('utf-8')
s = t.encode('utf-8')
cipher = AES.new(i, AES.MODE_ECB)
encrypted_data = cipher.encrypt(pad(s, AES.block_size))
return str(base64.encodebytes(encrypted_data), encoding='utf8').replace('\n', '')
五、验证结果
使用 requests.post 发送校验请求进行验证。
关键参数说明:
captchaType:固定值 clickWord
token 和 secretKey:从 get 接口的响应中获取
最终,脚本和网页的校验结果对比如下:
总结
本次逆向的整体流程:
- 抓包定位校验接口
- 断点追踪找到加密函数
- 分析逻辑确认 AES-ECB + Pkcs7 填充
- Python 复现加密并验证通过
声明: 本文章内容仅供学习交流使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关。本文章未经许可禁止转载,禁止任何修改后二次传播。擅自使用本文讲解的技术而导致的任何意外,作者均不负责。若有侵权,请联系作者删除。