本文仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途。

前言

每隔一段时间,给自己安排一次逆向分析任务,是提升技术能力的有效方式。本文将分享一次完整的滑块验证码逆向分析过程,涵盖从请求抓包到参数还原的全流程。

目标站点:某知识社区平台的登录接口

一、整体流程梳理

通过浏览器开发者工具抓包分析,锁定以下关键接口:

序号接口地址作用
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 加密分析思路

  1. 找入口:通过关键字搜索定位加密位置
  2. 跟调用栈:向上追溯参数来源
  3. 断点观察:运行时查看中间值
  4. 简化还原:去除混淆,提取核心逻辑

四、完整流程图

用户访问登录页    ↓[getconf] 获取验证码配置    ↓[up] 上报设备指纹    ↓[get] 获取滑块图片 + token    ↓用户完成滑块拖动    ↓[check] 提交验证结果    ↓
该部分仅登录用户可见
账号密码登录 ↓登录成功

五、结语

本次逆向分析历时较长,但通过系统的方法论最终完成了全部参数的还原。核心收获:

  1. 耐心 — 混淆代码需要逐行分析
  2. 方法 — 善用调试工具和 Hook 技巧
  3. 验证 — 每个环节都要单独测试
  4. 复用 — 同一加密函数多次出现时要识别出来

逆向工程是一门需要持续积累的技术,每一次分析都是成长的机会。


本文技术分享仅供学习参考,请遵守相关法律法规,勿用于非法用途。

最后修改:2026 年 06 月 05 日
如果觉得我的文章对你有用,请随意赞赏