某美滑块验证码别乱捅!一不小心就反爬了.
“
阅读本文大概需要 7 分钟。
大家好,我是 TheWeiJun!经过一段时间的等待,我终于回来了。在这段间隙里,我毫无保留地投入精力,为大家精心打造了一篇关于某美验证码逆向分析的文章。如果你希望第一时间阅读我的最新内容,请务必关注我的公众号!尽管在这篇内容更新后,因个人安排的需要,我将稍作休息几个月。然而我坚信,这篇文章会让你欲罢不能。废话不多说,让我们一同探索吧!
特别声明: 本公众号文章只作为学术研究,不作为其他不法用途;如有侵权请联系作者删除。
立即加星标
每月看好文
趣味模块
小江, 一位出色的IT工程师,常常被频繁的 IP 请求所困扰,滑块验证码像难缠的门神一样挡在他前进的路上。然而,他不甘心被困扰,于是决心寻找解决之道。通过还原算法、模拟轨迹、识别滑块距离,他逐渐揭开了滑块验证码的神秘面纱。经过不懈的努力,他终于成功破解了滑块的诡计,让这个烦人的问题不再是他的困扰。小江的故事鼓舞着许多人,教导我们无论面对多大的挑战,只要用心探索,就能找到通向胜利的路径。 (GPT 故事情节虚构) 小江 公众号如下:
一、前言介绍
滑块验证码(Slider Captcha),又称拼图验证码或滑动验证码,是一种常见的验证机制,旨在防止机器人和恶意攻击者对网站进行自动化操作。与传统验证码不同,滑块验证码需要用户通过将一个滑块拖动到正确的位置来完成验证。
通常,滑块验证码由两部分组成:一个背景图像和一个滑块。在验证过程中,用户需要按照提示将滑块拖动到正确的位置。为了防止针对验证码的攻击,滑块验证码会使用多种技术来检测用户的行为模式并确定是否存在异常行为,例如反复尝试拖动滑块或使用自动化脚本进行操作。
某美验证码的应用非常广泛,像某书、某街就是使用了某美滑块来进行风控的,当爬虫没有使用代理 ip、ip 质量比较差或者单个代理ip使用次数过多的时候,就会出现滑块验证码,严重的时候还会出现无限滑块的情况。总之,滑块验证码是一种常见的验证机制,因其易于使用和安全性高而被广泛应用于各种网站和应用程序中。
二、网站分析
1、抓包分析,打开我们本次分析的网站,拖动滑块到任意位置。然后查看请求流程如下:
2、标红的 框主要是 滑块生成接口和滑块请求的验证接口以及滑块图片。 我们先查看下 register 滑块图片生成接口, 截图如下:
说明: 因为 register 接口有两个,此刻我们需要确认 fverify 验证码校验接口使用的是哪一个 register 接口?这里我们先留个疑问。
3、紧接着我们查看下 fverify 验证码校验接口,截图如下所示:
4、因为滑块没有通过,触发了 REJECT 机制。紧接着我们分析下 fverify 的 payload 参数结构体,截图如下:
说明: 查看 fverify 请求结构体,我们确认 rid 和第一次 register 请求接口 response 中的 rid 一致,我们可以确定本次验证请求和 register 第一个接口相关联。
5、接下来,我们将滑块滑动通过校验,查看下验证成功的 response 结果,截图如下:
总结: 我们只需要对 fverify 接口的 payload 参数体进行算法还原,然后验证接口返回为 PASS 即可完成滑块逆向分析。那么接下来,让我们进入参数逆向环节吧。
三、参数逆向
1、 我们多次触发 fverify 接口请求,观察参数变动,最终确定以下参数会变动:
2、接下来,对上面五个参数进行初判断:
-
callback sm_ 拼接毫秒级时间戳。
-
rid 此参数通过 register 接口返回。
-
ee 以往经验感觉是轨迹加密值。
-
ra 加密值,不是坐标就是时间。
-
ml 加密值,不是坐标就是时间。
总结: 我们可以忽略 callback、rid 参数,只需要逆向分析 ee、ra、ml 即可完成对滑块算法的还原,接下来我们开始堆栈分析进行断点调试吧。
3、我们通过 fverify 接口的堆栈定位 js 文件,由于网站使用了定时函数,断点断在发请求出的话堆栈不好跟踪,所以可以选择在 setTimeout 函数前的每个堆栈都下一个断点,观察下加密参数最早在哪边出现的。截图如下:
4、打好断点后,再次滑动代码,我们可以发现在"_0x9baf4e"位置,已经有加密参数生成,截图如下:
5、那么全局搜索一下这个变量,看下是在哪里进行赋值的。接着搜索定位到了变量赋值的地方,是通过调用 this['getMouseAction']() 生成的加密对象。我们继续跟进,看看这个函数是如何进行加密的。
6、继续断点跟进后,由下图可知,加密参数的生成位置出来了,截图如下:
7、跟进ml参数断点,此刻我们可以确定 ml、ee、ra 参数使用的是 DES 加密算法,截图如下:
8、分析下加密代码,加密函数主要就是使用了对称加密算法 des 来进行加密,同时也能清晰的观察到传入的参数和密钥,简化出来的目标参数生成逻辑伪代码如下:
总结: 参数分析流程到这里就结束了,接下来我们进入算法还原环节。分别对 DES 加密算法还原、滑块距离计算、滑块轨迹模拟进行还原吧。
四、算法还原
1、在 Console 中拿到 ml 参数的横向滑动距离 102/300,以及DES 的密钥 key:2a29ac9a,编写算法如下:
import base64
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad
def des_encrypt(key, text):
"""使用DES算法对文本进行加密"""
key = key.encode('utf-8')
text = text.encode('utf-8')
cipher = DES.new(key, DES.MODE_ECB)
padded_text = pad(text, DES.block_size)
encrypted_bytes = cipher.encrypt(padded_text)
encrypted_base64 = base64.b64encode(encrypted_bytes).decode('utf-8')
return encrypted_base64
if __name__ == '__main__':
key = '2a29ac9a'
text = str(102/300)
ori_encrypt = "mJRZFPayX/Y="
print(text, des_encrypt(key, text), ori_encrypt)
运行代码后,我们查看 pycharm 中,结果输出如下:
科普: 通过上图,我们发现 des 加密算法不是常规的 des 加密。des 默认块填充为 DES.block_size=8(字节),如果需要填充 5 个字节,那么填充的内容将是 b'\x05\x05\x05\x05\x05',其中 \x05 表示字节的十六进制值为 5,解密时会检测并移除这种填充。而我们查看 JS 中 des 加密逻辑,发现此处填充的内容为 x00,于是我们修改代码如下图所示:
我们再次运行代码后,可以看到 python 还原的值和 js 中加密的值结果一致,截图如下:
2、参数加密算法搞定后,紧接着我们来搞定滑块 x 坐标距离,我们使用 OpenCV 来识别图片,计算滑动距离。编辑完整代码如下:
3、在得到 x 坐标滑动距离后,我们进行轨迹模拟,经过反复的修正轨迹,最终确定代码如下:
import random
def generate_tracks(distance):
"""生成轨迹"""
tracks = []
initial_velocity = 0
time_interval = 1
current_distance = 0
target_midpoint = distance * 3 / 4
exceed_threshold = 20
initial_height = 1
0, initial_height])
while current_distance < (distance + exceed_threshold):
if current_distance < target_midpoint / 2:
acceleration = 15
elif current_distance < target_midpoint:
acceleration = 20
else:
acceleration = -30
acceleration /= 2
initial_velocity = initial_velocity
displacement = initial_velocity * time_interval + 0.5 * acceleration * (time_interval * time_interval)
current_distance += int(displacement)
initial_velocity += acceleration * time_interval
height_change = random.randint(-5, 5)
height = tracks[-1][1] + height_change
depth = tracks[-1][2] + 100 + random.randint(0, 10)
(distance + exceed_threshold))), height, depth])
while exceed_threshold > 0:
exceed_threshold -= random.randint(0, 5)
height_change = random.randint(-5, 5)
height += height_change
depth += 100 + random.randint(0, 10)
(distance + exceed_threshold))), height, depth])
return tracks
4、以上三步流程搞定后,我们编辑增加 ml、ee、ra 参数流程生成代码如下:
5、加密算法还原、滑块距离识别、滑块轨迹模拟完成后,我们结合完整流程发送 20 次接口请求,验证效果截图如下:
总结: 滑动成功率还是挺高的,18/20=90%;如果想要追求更高的通过率的话,可以进一步优化下图像识别和轨迹模拟这两方面。
五、思路总结
回顾整个分析流程,本次重点主要概括为以下几点:
- DES 魔改算法还原实现
- 滑块缺口位置坐标定位
- 滑块数组轨迹模拟生成
- 混淆代码中确定加密位置
本篇分享到这里就结束了,欢迎大家关注下期文章,我们不见不散☀️☀️✌️
END
作者简介
我是TheWeiJun,有着执着的追求,信奉终身成长,不定义自己,热爱技术但不拘泥于技术,爱好分享,喜欢读书和乐于结交朋友,欢迎扫我微信与我交朋友💕 分享日常学习中关于爬虫及逆向分析的一些思路,文中若有错误的地方,欢迎大家多多交流指正💕
点分享
点收藏
点点赞
点在看