Js逆向验证码 ---云片滑块
本文分析了某验证码滑块系统的加密验证流程。通过抓包发现该系统使用两个接口:第一个接口返回背景图、滑块图和验证token,第二个接口提交滑动验证。分析发现关键参数i和k由加密算法生成,其中i采用AES加密(CBC模式),k使用RSA加密。文章详细介绍了如何通过逆向工程还原加密过程,并提供了滑块轨迹生成的Python代码(基于AI学习生成),包括加速度控制和随机波动模拟。最后指出验证通过后会返回Tru
url = "aHR0cHM6Ly93d3cueXVucGlhbi5jb20vcHJvZHVjdC9jYXB0Y2hh"
我们打开这个网站,进行抓包分析,发现这个滑块的验证只需要走两个接口:
其中第一个接口,返回背景图和滑块图,还有第二次接口需要验证的toekn:
多刷新几次,发现第一次接口的有三个参数是变化的
直接打断点,进行跟栈
这个加密了e,返回了我们需要的i,k。同时可以发现cbj就是this.cbManager.preAdd()生成的,跟进去发现是一个随机值的生成,那么这个可以固定也可以随机生成一个,主要还是i,k
跟进去发现这个i,k在这里生成的
这里基本上就可以确定了,我们先解决i的生成,这个有key,有iv看起来像一个DES或AES的加密,当然,不使用算法也可以的,你可以找一下这个lt是什么
那么,这里就非常明显了,这是一个webpack了,把加载器拿下来,进行导出,再补上缺少的模块就可以了,但是这个比较麻烦,这个里面加载了有20多个模块,你可以把这个代码全部拿下来,再补上环境,再进行导出使用也可以,这样还快一点。
这里我使用算法还原的方式,这个我们跟进去这个加密方法,最后走到了这个位置
我是先猜测这个是一个AES加密的,这个看起来也比较的明显,它这里没有指出来是什么模式,就直接默认的CBC模式,同样的,这个k就是一个rsa加密了
我也是使用node.js中的jsencrypt实现的,这个需要npm安装一下。看一下结果
没有问题,加密的参数是e,这个直接固定就可以了。
把这个生成的参数带上,进行请求,从返回的数据里面,把背景图和滑块图拿出来,保存到本地,再通过ddddocr或cv2识别出来距离,注意这个图片的大小和网站的大小不一样,所以需要对识别出来的距离进行调整,再分析第二次请求
需要分析的参数一样,toekn是第一次请求返回的,capchaid这个是固定的,进行跟栈,发现还是一样的位置,就是加密参数e不一样了
这里distanceX是滑动的距离进行计算得到的,fp可以固定,接下来就是这个轨迹了。
这里生成了轨迹
我是直接使用ai生成的轨迹,给ai十组轨迹数据,让它自己生成一个函数,当然,你也可以自己分析这个代码。自己写一个函数生成。
def get_track(self, distance):
"""
生成滑块轨迹数据
:param distance: 需要滑动的水平距离(像素)
:return: 轨迹数据列表 [[x, y, t], ...]
"""
# 基础参数设置
x0 = 400 # 起始x坐标
y0 = random.randint(1730, 1750) # 起始y坐标
total_points = random.randint(45, 65) # 轨迹点数
# 时间参数 (总时间与滑动距离正相关)
total_time = distance * random.uniform(8, 12)
# 生成时间序列 (中间稀疏/两端密集)
time_points = []
mid_point = total_points // 2
for i in range(total_points):
# 高斯分布权重:中间权重小(时间间隔大),两端权重大(时间间隔小)
weight = 1.5 - np.exp(-(i - mid_point) ** 2 / (2 * (mid_point / 2) ** 2))
time_points.append(weight)
# 归一化并生成时间戳
time_points = np.array(time_points)
time_points = time_points / time_points.sum() * total_time
time_stamps = [round(sum(time_points[:i])) for i in range(1, len(time_points) + 1)]
# 生成运动曲线 (S型曲线模拟加速-匀速-减速)
x_positions = []
t_norm = np.linspace(0, 1, total_points)
# Sigmoid函数变体,控制加速/减速区域
for t in t_norm:
if t < 0.3: # 加速阶段
phase = (t / 0.3) ** 1.5
elif t > 0.7: # 减速阶段
phase = 1 - ((1 - t) / 0.3) ** 1.5
else: # 匀速阶段
phase = 1
x_positions.append(round(x0 + phase * distance))
# 确保终点精确
x_positions[-1] = x0 + distance
# 生成y坐标 (带随机波动)
y_positions = [y0]
for i in range(1, total_points):
# 随机波动 + 缓慢漂移
drift = 0.1 if random.random() > 0.8 else 0
new_y = y_positions[-1] + random.randint(-2, 2) + drift
# 限制波动范围
if abs(new_y - y0) > 8:
new_y = y0 + random.randint(-3, 3)
y_positions.append(int(new_y))
# 组合轨迹数据
track = []
for i in range(total_points):
track.append([
x_positions[i],
y_positions[i],
int(time_stamps[i])
])
return track
轨迹生成后,就没什么值需要处理了,加密方式方法和第一次是一样的,变化的是加密的值。这个验证成功后会返回一个True和一个token
自己本地生成的
这个难度不大,你要是用这个webpack去扣代码的话,就需要费点时间了。
如有侵权,联系删除!!!
如有侵权,联系删除!!!
如有侵权,联系删除!!!
更多推荐


所有评论(0)