某象「刮刮乐」验证码分析
2026/5/16 12:49:10 网站建设 项目流程

某象「刮刮乐」验证码分析

本文为技术分析,探讨验证码的交互机制与数据编码方式。


一、这是什么验证码

常见的验证码无非是滑块、点选、旋转。但某象有一种比较少见的类型——刮刮乐(Scratch)

交互过程:页面展示一张被"打乱"的图片,你需要在图片上反复刮擦,直到刮出下方隐藏的内容,系统判定你是否刮在了正确的位置。

整个交互数据流分三步:

Step 1: 请求题目 → 服务器返回 {sid, type:2, 混淆图URL} Step 2: 还原图片 → 找到目标位置 Step 3: 生成数据 → 提交 → 拿token

看上去就三步,但真正有意思的藏在第二步和第三步里面。


二、请求参数概览

获取题目(GET /api/a)的关键参数

参数含义备注
ak应用标识固定值
c设备指纹 token会动态过期,不是固定值
jsvSDK版本号目前是 5.1.53
cid场景ID刮刮乐固定为 72556577
aid会话标识每轮随机生成

提交答案(POST /api/v3)的关键参数

参数含义
ac核心参数
sid第一步返回的会话ID

API 交互本身并不复杂。真正的难点是两个问题:图片里的目标在哪,以及ac 这个几百字符的字符串到底是什么


三、图片是怎么被混淆的

3.1 混淆方式

某象返回的图被纵向切成 32 个竖条(strip),打乱了顺序。人眼完全无法辨认里面的内容。

有意思的是,还原密钥直接嵌在图片URL里

https://static.xxx.com/picture/xxx/abc123def456.png └─── hash_data ───┘

文件名去掉.png后缀,就是这个 hash 字符串。

3.2 还原思路

核心是一个哈希 → 排列映射的过程——URL 文件名作为种子,通过一个特定的映射算法,生成 strip 的排列顺序。然后按这个排列把 strip 从混淆图里取出来,按正确顺序拼回去。

整个还原算法并不长,但前提是你得从某象那 4000 多行混淆过的 JS 里把映射算法还原出来。这才是真正花时间的地方。

还原为如下:

还原代码:

fromPILimportImagedefrestore_img(file_path,save_file_path,hash_data):defget_order(hash_value):defget_unique_num(i,used):num=i%32ifnumnotinused:used.add(num)returnnumreturnget_unique_num(i+1,used)used_numbers=set()data=[]forcharinhash_value:i=ord(char)unique_num=get_unique_num(i,used_numbers)data.append(unique_num)returndata image=Image.open(file_path)width,height=image.size s=width//32new_image=Image.new('RGBA',(width,height))order=get_order(hash_data)+[32]k=0foridxinorder:c=idx*s piece=image.crop((c,0,c+16,height))new_image.paste(piece,(k,0))k+=s new_image.save(save_file_path,format="PNG")print(f"✅ 还原完成 →{save_file_path}")restore_img('img.png','output.png','hashdata ')

img.png 是输入图片名称,output.png是还原后的图片名,第三个参数是前文所讲的hash data


四、怎么定位目标

图片还原后,需要在图里找到一个特定的目标区域。

传统方案各有各的问题:模板匹配泛化不了(目标的外观会变),边缘检测不稳定(还原图背景嘈杂),OCR 也不太适用(目标可能不是纯文字)。

这种场景下深度学习目标检测是一个比较自然的选择。用 YOLO 这类模型,标注几十张同类图训练一轮,模型就能学会识别目标。因为不管外观怎么变,目标的语义是不变的。


五、AC参数到底是什么

5.1 AC 不是一个简单的加密串

ac = encode([ 加密(刮擦行为轨迹), ← 完整的鼠标/触摸路径,不是几个坐标 网格覆盖编码, ← 刮擦动作覆盖了画布上哪些区域 会话令牌绑定 ← 与本次 sid 的关联 ])

5.2 前端 SDK 内部在做什么

从某象前端混淆 JS 中还原出来的逻辑链路,大致有六个步骤:

  1. 生成刮擦轨迹:不是"画一个矩形"这么简单。需要模拟人手反复涂抹的效果——蛇形路径在矩形区域内来回扫,每行有缓入缓出曲线,Y 轴有微小抖动,行尾偶尔"冲出边界再收回",时间间隔随机波动
  2. 初始化行为追踪器:将本次验证会话的 sid 绑定进去
  3. 逐帧喂入轨迹点:每个点的[x, y, t]被记录,时间戳在 JS 执行时实时计算
  4. 加密轨迹数据:JSON 序列化 → Base64(魔改字符表) → 自定义混淆 → 拼接
  5. 计算刮擦覆盖数据:把画布划分为网格,计算每个格子的笔刷覆盖面积,生成一个位图再编码为十六进制字符串。注意这个编码必须和你声称的矩形坐标自洽——对不上就拒
  6. 合并打包:所有加密结果合并为最终输出的 ac

5.3 为什么这个设计值得琢磨

这里有一个双重闭环校验的设计:

  • 第一层:行为轨迹本身要"像人"——匀速直线是机器,有缓入缓出+抖动+偶尔冲出才有人的特征
  • 第二层:轨迹覆盖的网格区域,必须与你声称的矩形坐标自洽——你说刮了 (45,78) 到 (132,156) 这块,那网格编码里的"被覆盖格子"必须确实落在这个范围内

这意味着即使你找到了正确位置,如果行为不像人、或者覆盖数据和坐标不自洽,一样过不了。

这种将"行为仿真"和"坐标校验"耦合在一起的设计,比单纯的滑块验证码复杂了不止一个量级。


六、实际会遇到哪些坑

  1. 图片宽度不被 32 整除:还原算法必须处理末尾余数,否则右边 strip 会整体错位
  2. YOLO 返回的坐标不保证顺序:x1 可能大于 x2,需要 swap,不然轨迹直接生成到反方向去
  3. 设备指纹 C 值会过期:它不是固定值,需要通过独立的 constid 接口定期刷新,否则后端直接拒绝
  4. 可能返回二次验证:你以为拿到 token 了,结果回来的是"msg": "二次验证",里面是一个完整的新题目,需要递归处理
  5. 轨迹参数直接影响通过率:缓入缓出曲线的选型、抖动幅度、冲出概率——这几个参数调不好,坐标再对也过不了
  6. 某象的 JS SDK 更新频繁:代码结构会变,今天能跑的方案明天可能需要适配

如果你对以下内容感兴趣,欢迎来知识星球(限时九折优惠):

  • AC 参数内部逻辑的深度拆解:轨迹生成的每个参数为什么这样取值、曲线选型的考量、网格覆盖编码的端到端实现
  • 设备指纹 constid 逆向研究( Canvas/WebGL/字体列表等几十个字段的组装与加密)
  • 二次验证的递归处理与死循环防控机制

https://t.zsxq.com/v60KZ

这些内容来自真实的工程实践。星球见。


声明:本文为技术分析,探讨验证码的工作机制。所述内容仅供学习研究。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询