本文仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途。
前言
每隔一段时间,给自己安排一次逆向分析任务,是提升技术能力的有效方式。本文将分享一次完整的滑块验证码逆向分析过程,涵盖从请求抓包到参数还原的全流程。
目标站点:某知识社区平台的登录接口
一、整体流程梳理
通过浏览器开发者工具抓包分析,锁定以下关键接口:
| 序号 | 接口地址 | 作用 |
|---|---|---|
| 1 | /api/v2/getconf | 获取验证码配置信息 |
| 2 | /v4/j/up | 上传设备指纹信息 |
| 3 | /api/v3/get | 获取滑块图片及token |
| 4 | /api/v3/check | 提交滑块验证结果 |
| 5 | /user/validateAccountAndPassword | 登录验证 |
二、接口分析详解
2.1 getconf 接口 —— 配置获取
核心难点:JSONP 回调参数生成
首次请求时返回 callback isinvalid,说明缺少必要的回调参数。通过搜索 JSONP 关键字定位到参数生成逻辑:
// 原始代码逻辑d = "__JSONP" + "_" + Math.random().toString(36).slice(2, 9) + "_" + i++参数说明:
id: 验证码初始化时的 captchaId(固定值)ipv6: 固定为"false"runEnv: 环境标识,WEB 端为"10"iv: 版本号,固定为"5"callback: 动态生成的 JSONP 回调函数名
Python 实现:
import randomimport stringI = 0 # 请求序号,从0开始def generate_callback(): global I random_part = ''.join(random.choices( string.ascii_lowercase + string.digits, k=7 )) result = f"__JSONP_{random_part}_{I}" I += 1 return resultparams = { "id": "75f9f716460a422f89a628f50fd8cc2b", "ipv6": "false", "runEnv": "10", "iv": "5", "callback": generate_callback()}2.2 up 接口 —— 设备指纹上报
UUID 生成函数 G() 还原:
import randomdef generate_uuid(): """还原 JS 中的 UUID 生成逻辑""" template = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx' result = [] for char in template: if char == 'x': result.append(format(int(16 * random.random()), 'x')) elif char == 'y': result.append(format(3 & int(16 * random.random()) | 8, 'x')) else: result.append(char) return ''.join(result)2.3 get 接口 —— 获取验证图片
Hook 调试技巧:当参数来源不明时,可使用 Object.defineProperty 进行 Hook
(function() { 'use strict'; Object.defineProperty(window, 'gdxidpyhxde', { get: function() { return ""; }, set: function(value) { debugger; // 断点触发,追踪赋值来源 return value; }, });})();2.4 check 接口 —— 滑块验证
鼠标轨迹模拟:
def generate_mouse_trace(x_end): """生成模拟鼠标轨迹""" st = random.randint(60, 90) tm, dragX, X_init, length = [], [], 0, 0 while True: temp = random.randint(2, 7) X_init += temp st += random.randint(6, 9) tm.append(st) dragX.append(X_init) x_end -= temp length += 1 if x_end < 0: dragX[-1] += x_end break dragX.sort(reverse=True) Y = sorted([random.randint(0, 10) for _ in range(length)]) # [拖拽X偏移, 拖拽Y偏移, 时间差, 真实判断] return [[dragX[i], Y[i], tm[i], 1] for i in range(length)]三、技术要点总结
3.1 调试技巧
| 技巧 | 应用场景 |
|---|---|
| 断点调试 | 追踪变量赋值过程 |
| Hook 注入 | 捕获动态生成的参数 |
| 调用栈分析 | 追溯参数来源 |
| 代码美化 | 还原混淆后的逻辑 |
3.2 加密分析思路
- 找入口:通过关键字搜索定位加密位置
- 跟调用栈:向上追溯参数来源
- 断点观察:运行时查看中间值
- 简化还原:去除混淆,提取核心逻辑
四、完整流程图
用户访问登录页 ↓[getconf] 获取验证码配置 ↓[up] 上报设备指纹 ↓[get] 获取滑块图片 + token ↓用户完成滑块拖动 ↓[check] 提交验证结果 ↓该部分仅登录用户可见 账号密码登录 ↓登录成功五、结语
本次逆向分析历时较长,但通过系统的方法论最终完成了全部参数的还原。核心收获:
- 耐心 — 混淆代码需要逐行分析
- 方法 — 善用调试工具和 Hook 技巧
- 验证 — 每个环节都要单独测试
- 复用 — 同一加密函数多次出现时要识别出来
逆向工程是一门需要持续积累的技术,每一次分析都是成长的机会。
本文技术分享仅供学习参考,请遵守相关法律法规,勿用于非法用途。