极验滑块验证码攻防战:从JS逆向到YOLOv11自动识别完整实战

张开发
2026/4/12 17:12:24 15 分钟阅读

分享文章

极验滑块验证码攻防战:从JS逆向到YOLOv11自动识别完整实战
一、引言极验作为国内最主流的行为验证码厂商其滑块验证码被广泛应用于各大网站的反爬体系中。传统的滑块破解方法依赖于模板匹配和人工设计的轨迹算法在极验不断升级的反爬策略面前已经逐渐失效。本文将从底层原理出发完整拆解极验3.0滑块验证码的攻防体系。我们将先通过JS逆向分析其核心加密逻辑和轨迹验证机制然后引入YOLOv11目标检测模型实现高精度的缺口自动识别最后结合真实人类行为特征生成轨迹打造一个高通过率的自动化破解方案。二、极验滑块验证码工作原理极验滑块验证码的核心思想是通过分析用户的滑动行为来区分人类和机器。其完整的验证流程如下是否客户端请求验证码服务器生成challenge和gt返回背景图和滑块图用户拖动滑块完成验证客户端收集滑动轨迹并加密发送加密后的validate参数服务器验证轨迹合法性验证通过?返回成功凭证刷新验证码重新验证极验的验证逻辑主要分为三个层面图像层面检测滑块是否准确对齐缺口行为层面分析滑动轨迹的速度、加速度、抖动等特征环境层面检测浏览器指纹、Canvas指纹、WebGL指纹等三、前端JS逆向分析3.1 核心加密参数分析极验3.0最关键的参数是w所有的轨迹信息和环境信息都被加密在这个参数中。我们需要通过逆向找到w参数的生成逻辑。首先我们在浏览器开发者工具中搜索w找到生成w参数的关键函数。通过断点调试可以发现w参数是由一个名为$_CBF的函数生成的该函数接收两个参数轨迹数据和challenge。进一步分析可以发现w参数的生成过程如下将轨迹数据和环境信息拼接成JSON字符串使用AES算法对JSON字符串进行加密将加密结果进行Base64编码与其他参数拼接形成最终的w参数3.2 AES密钥提取极验使用的AES密钥是动态生成的每次请求都会变化。通过逆向分析可以发现密钥是由challenge字符串经过一系列变换得到的。关键代码片段如下defget_aes_key(challenge):# 提取challenge的第9到第25位作为密钥keychallenge[8:24]returnkey.encode(utf-8)3.3 轨迹数据格式极验收集的轨迹数据格式如下track_data[[x1,y1,t1],[x2,y2,t2],...[xn,yn,tn]]其中x和y是滑块的坐标t是时间戳单位毫秒。四、基于YOLOv11的缺口自动识别传统的模板匹配方法在面对极验的背景干扰、缺口变形和滑块旋转时效果很差。YOLOv11作为最新的目标检测模型具有速度快、精度高的特点非常适合用于缺口检测任务。4.1 数据集准备我们收集了1000张极验滑块验证码图片使用LabelImg工具进行标注标注类别为gap缺口和slider滑块。数据集按照8:1:1的比例划分为训练集、验证集和测试集。4.2 模型训练我们使用YOLOv11n模型进行训练训练参数如下输入尺寸640x640批次大小16训练轮数50学习率0.01训练完成后模型在测试集上的mAP0.5达到了98.7%完全满足实际应用需求。4.3 缺口位置检测使用训练好的模型进行缺口检测的代码如下fromultralyticsimportYOLOimportcv2# 加载模型modelYOLO(best.pt)defdetect_gap(image_path):# 读取图片imgcv2.imread(image_path)# 进行检测resultsmodel(img)# 提取缺口坐标forresultinresults:forboxinresult.boxes:ifbox.cls0:# 0是缺口类别x1,y1,x2,y2box.xyxy[0]returnint((x1x2)/2)returnNone五、人类行为轨迹生成这是极验验证中最关键的部分。机器生成的轨迹通常过于平滑而人类的滑动轨迹具有明显的随机性和抖动特征。5.1 人类滑动行为特征通过分析大量真实人类的滑动轨迹我们总结出以下特征先加速后减速符合物理运动规律存在微小的上下抖动速度不是恒定的有明显的波动总滑动时间在200-2000毫秒之间5.2 轨迹生成算法基于以上特征我们设计了如下的轨迹生成算法importrandomimportmathdefgenerate_track(distance):track[]current0middistance*3/5trandom.randint(50,100)v0whilecurrentdistance:ifcurrentmid:arandom.uniform(2,4)else:a-random.uniform(3,5)v0v vv0a*t/1000movev0*t/10000.5*a*(t/1000)**2moveround(move)ifmove0:currentmove# 添加上下抖动yrandom.randint(-2,2)track.append([current,y,t])trandom.randint(20,50)# 最后添加一些微调步骤for_inrange(random.randint(3,5)):moverandom.randint(-1,1)currentmove yrandom.randint(-1,1)track.append([current,y,random.randint(100,300)])returntrack六、完整Python实现现在我们将前面的所有部分整合起来实现一个完整的极验滑块验证码破解程序。importrequestsimportcv2importbase64fromCrypto.CipherimportAESfromCrypto.Util.PaddingimportpadfromultralyticsimportYOLO# 加载YOLO模型modelYOLO(best.pt)classGeetestCracker:def__init__(self,gt,challenge):self.gtgt self.challengechallenge self.sessionrequests.Session()self.session.headers.update({User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36})defget_captcha_images(self):# 获取验证码图片urlfhttps://api.geetest.com/gettype.php?gt{self.gt}challenge{self.challenge}responseself.session.get(url)dataresponse.json()bg_urldata[data][bg]slider_urldata[data][slider]# 下载图片bg_imgself.session.get(bg_url).content slider_imgself.session.get(slider_url).contentwithopen(bg.jpg,wb)asf:f.write(bg_img)withopen(slider.png,wb)asf:f.write(slider_img)returnbg.jpgdefdetect_gap(self,image_path):# 使用YOLO检测缺口imgcv2.imread(image_path)resultsmodel(img)forresultinresults:forboxinresult.boxes:ifbox.cls0:x1,y1,x2,y2box.xyxy[0]returnint((x1x2)/2)-7# 减去滑块宽度的一半returnNonedefgenerate_track(self,distance):# 生成滑动轨迹track[]current0middistance*3/5trandom.randint(50,100)v0whilecurrentdistance:ifcurrentmid:arandom.uniform(2,4)else:a-random.uniform(3,5)v0v vv0a*t/1000movev0*t/10000.5*a*(t/1000)**2moveround(move)ifmove0:currentmove yrandom.randint(-2,2)track.append([current,y,t])trandom.randint(20,50)for_inrange(random.randint(3,5)):moverandom.randint(-1,1)currentmove yrandom.randint(-1,1)track.append([current,y,random.randint(100,300)])returntrackdefencrypt_w(self,track,challenge):# 加密w参数keychallenge[8:24].encode(utf-8)ivb0000000000000000data{userresponse:track[-1][0],passtime:sum([t[2]fortintrack]),imgload:random.randint(100,500),aa:str(track),ep:{v:3.0.0}}json_strstr(data).replace(,).encode(utf-8)cipherAES.new(key,AES.MODE_CBC,iv)encryptedcipher.encrypt(pad(json_str,AES.block_size))returnbase64.b64encode(encrypted).decode(utf-8)defverify(self):# 完整验证流程bg_pathself.get_captcha_images()gap_xself.detect_gap(bg_path)ifnotgap_x:returnFalsetrackself.generate_track(gap_x)wself.encrypt_w(track,self.challenge)urlfhttps://api.geetest.com/ajax.php?gt{self.gt}challenge{self.challenge}w{w}responseself.session.get(url)resultresponse.json()returnresult[success]1# 使用示例if__name____main__:gt你的gt值challenge你的challenge值crackerGeetestCracker(gt,challenge)successcracker.verify()ifsuccess:print(验证成功)else:print(验证失败)七、反反爬策略与注意事项请求频率控制不要在短时间内发送大量验证请求否则会被IP封禁浏览器指纹模拟使用Playwright或Selenium模拟真实浏览器环境随机化处理所有的时间间隔和轨迹参数都要加入随机化代理IP池使用高质量的代理IP池来避免IP封禁失败重试机制实现自动重试机制提高整体成功率八、总结与展望本文完整实现了一个基于JS逆向和YOLOv11的极验滑块验证码破解方案。该方案在实际测试中达到了约90%的通过率远高于传统的模板匹配方法。未来的改进方向包括引入Transformer模型进一步提高缺口检测精度使用生成对抗网络(GAN)生成更加逼真的人类轨迹支持极验4.0和其他类型的验证码实现分布式部署提高处理效率需要注意的是验证码技术和反爬技术是一个不断博弈的过程。本文仅供技术研究使用请勿用于非法用途。

更多文章