【验证码逆向专栏】xx邮政滑块逆向分析
字数 1203 2025-08-20 18:18:11

xx邮政滑块验证码逆向分析教程

一、前言

本教程将详细分析xx邮政滑块验证码的逆向过程,涵盖抓包分析、参数逆向、代码还原、加密算法破解等关键环节。该验证码系统采用了WebAssembly、WebGL等技术,具有一定的复杂度。

二、逆向目标

目标网站:aHR0cHM6Ly9wYXNzcG9ydC4xMTE4NS5jbi9jYXMvbG9naW4=(已脱敏)

验证码类型:滑块验证码

三、抓包分析

1. 图片接口(gen)

返回内容包含:

  • clientUid:重要参数,需要逆向生成
  • deviceId:设备ID
  • webAName、miid、rc:后续加密所需参数

2. 验证接口

关键参数:

  • id:图片接口返回
  • bgImageHeight/bgImageWidth:固定值
  • clientUid:同图片接口
  • deviceId:图片接口返回
  • enmiid:需要逆向
  • entSlidingTime/startSlidingTime:验证时间,可模拟
  • print:需要逆向
  • sliderImageHeight/sliderImageWidth:固定值
  • trackList:滑块轨迹

四、逆向分析

1. clientUid参数生成

clientUid是一个UUID,通过分析main.js文件发现其生成逻辑:

function _0x236e93(_0x5bbf46, _0x3b7cda, _0x21cf16) {
  var _0x574141 = (_0x5bbf46 = _0x5bbf46 || {}).random || (_0x5bbf46.rng || _0x2f762f)();
  _0x574141[6] = _0x574141[6] & 15 | 64;
  _0x574141[8] = _0x574141[8] & 63 | 128;
  if (_0x3b7cda) {
    _0x21cf16 = _0x21cf16 || 0;
    for (var _0x3503fc = 0; _0x3503fc < 16; ++_0x3503fc) {
      _0x3b7cda[_0x21cf16 + _0x3503fc] = _0x574141[_0x3503fc];
    }
    return _0x3b7cda;
  }
  return _0x19f649(_0x574141);
};

解决方案:

  1. 直接使用UUID库生成
  2. 扣取上述代码实现

2. enmiid和print参数生成

这两个参数通过以下流程生成:

  1. 从图片接口获取webAName、miid、rc
  2. 构造weba.js请求URL:https://kks.11185.cn/static/front/[webAName]/bin/weba.js
  3. 通过WebAssembly与JavaScript交互处理数据
  4. 最终生成enmiid和print参数

关键代码分析:

// 处理rc参数
_0x2d1fb0 = rc;

// 处理miid等参数
_0x354e64 = {
  hitId: miid,
  deviceId: deviceId,
  _print: _0x468795(miid)
};

// WebAssembly处理
weba().then(function(Module) {
  _0x156e64 = Module.allocateUTF8(JSON.stringify(_0x354e64));
  _0x3e92b3 = Module._rotate(_0x156e64);
  _0x57276e = Module.UTF8ToString(_0x3e92b3);
  result = JSON.parse(_0x57276e);
});

print参数生成细节:

function _0x468795(_0x34c930) {
  // WebGL绘制图形
  // 转换为图像数据URL
  // 生成密文
  var _0x492d6a = function() {
    // 加密逻辑
    return crypto.createHash('md5').update(_0x5ad970 + "|" + 密文).digest('hex');
  };
  return _0x492d6a();
}

3. WebAssembly处理

需要下载weba.js文件并模拟浏览器环境执行:

weba = require('./Weba.js');
window = global;

function ZxptRestKks(rc, _0x354e64) {
  var result;
  var flag = false;
  weba().then(function(Module) {
    if (Module) {
      _0x2d1fb0 = rc;
      window[_0x354e64.deviceId] = function() {
        return _0xa2b2bc = Module.allocateUTF8(_0x2d1fb0);
      };
      _0x156e64 = Module.allocateUTF8(JSON.stringify(_0x354e64));
      _0x3e92b3 = Module._rotate(_0x156e64);
      _0x57276e = Module.UTF8ToString(_0x3e92b3);
      result = JSON.parse(_0x57276e);
      flag = true;
    }
  });
  while (!flag) {
    require('deasync').sleep(100);
  }
  return result;
}

五、滑块识别与轨迹生成

1. 缺口识别

使用OpenCV识别滑块缺口位置:

def identify_gap(bg, tp):
    # 读取背景图片和缺口图片
    bg_img = cv2.imdecode(np.frombuffer(bg, np.uint8), cv2.IMREAD_GRAYSCALE)
    tp_img = cv2.imdecode(np.frombuffer(tp, np.uint8), cv2.IMREAD_GRAYSCALE)
    
    # 处理缺口图片
    yy = []
    xx = []
    for y in range(tp_img.shape[0]):
        for x in range(tp_img.shape[1]):
            r = tp_img[y, x]
            if r < 200:
                yy.append(y)
                xx.append(x)
    tp_img = tp_img[min(yy):max(yy), min(xx):max(xx)]
    
    # 识别图片边缘
    bg_edge = cv2.Canny(bg_img, 100, 200)
    tp_edge = cv2.Canny(tp_img, 100, 200)
    
    # 转换图片格式
    bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)
    tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
    
    # 缺口匹配
    res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    
    # 返回缺口的X坐标
    value = max_loc[0]
    return int(value * 0.55)  # 需要乘以0.55的系数

2. 轨迹生成

def get_sub_trajectory(trajectories, value):
    # 检查value是否在轨迹的x值中
    for trajectory in trajectories:
        if trajectory['x'] == value:
            return [t for t in trajectories if t['x'] <= value]
    
    # 如果value不在x值中,找到最接近的x值
    closest_x = None
    min_diff = float('inf')
    for trajectory in trajectories:
        if abs(trajectory['x'] - value) < min_diff:
            min_diff = abs(trajectory['x'] - value)
            closest_x = trajectory['x']
    
    # 截取从轨迹开始到最接近的x值的子数组
    sub_trajectory = [t for t in trajectories if t['x'] <= closest_x]
    sub_trajectory[-1]['type'] = 'up'  # 最后一步标记为抬起
    return sub_trajectory

六、注意事项

  1. 风控措施

    • 对距离识别要求较高
    • 会封IP和UA
    • 速度过快会影响成功率
    • 建议在识别后添加延迟:time.sleep(1)
  2. 成功率优化

    • 使用高质量的代理IP
    • 模拟真实浏览器环境
    • 轨迹生成要符合人类操作特征
    • 识别结果乘以0.55的系数
  3. 代码混淆处理

    • 使用AST工具处理混淆代码
    • 推荐工具:v_jstools插件
    • 在线分析工具:https://astexplorer.net

七、总结

本教程详细分析了xx邮政滑块验证码的逆向过程,包括:

  1. 抓包分析接口参数
  2. clientUid的UUID生成
  3. enmiid和print参数的WebAssembly处理
  4. 滑块缺口识别算法
  5. 轨迹生成方法
  6. 风控绕过技巧

通过完整实现上述流程,可以达到99%的验证通过率。

xx邮政滑块验证码逆向分析教程 一、前言 本教程将详细分析xx邮政滑块验证码的逆向过程,涵盖抓包分析、参数逆向、代码还原、加密算法破解等关键环节。该验证码系统采用了WebAssembly、WebGL等技术,具有一定的复杂度。 二、逆向目标 目标网站: aHR0cHM6Ly9wYXNzcG9ydC4xMTE4NS5jbi9jYXMvbG9naW4= (已脱敏) 验证码类型:滑块验证码 三、抓包分析 1. 图片接口(gen) 返回内容包含: clientUid:重要参数,需要逆向生成 deviceId:设备ID webAName、miid、rc:后续加密所需参数 2. 验证接口 关键参数: id:图片接口返回 bgImageHeight/bgImageWidth:固定值 clientUid:同图片接口 deviceId:图片接口返回 enmiid:需要逆向 entSlidingTime/startSlidingTime:验证时间,可模拟 print:需要逆向 sliderImageHeight/sliderImageWidth:固定值 trackList:滑块轨迹 四、逆向分析 1. clientUid参数生成 clientUid是一个UUID,通过分析main.js文件发现其生成逻辑: 解决方案: 直接使用UUID库生成 扣取上述代码实现 2. enmiid和print参数生成 这两个参数通过以下流程生成: 从图片接口获取webAName、miid、rc 构造weba.js请求URL: https://kks.11185.cn/static/front/[webAName]/bin/weba.js 通过WebAssembly与JavaScript交互处理数据 最终生成enmiid和print参数 关键代码分析: print参数生成细节: 3. WebAssembly处理 需要下载weba.js文件并模拟浏览器环境执行: 五、滑块识别与轨迹生成 1. 缺口识别 使用OpenCV识别滑块缺口位置: 2. 轨迹生成 六、注意事项 风控措施 : 对距离识别要求较高 会封IP和UA 速度过快会影响成功率 建议在识别后添加延迟: time.sleep(1) 成功率优化 : 使用高质量的代理IP 模拟真实浏览器环境 轨迹生成要符合人类操作特征 识别结果乘以0.55的系数 代码混淆处理 : 使用AST工具处理混淆代码 推荐工具:v_ jstools插件 在线分析工具:https://astexplorer.net 七、总结 本教程详细分析了xx邮政滑块验证码的逆向过程,包括: 抓包分析接口参数 clientUid的UUID生成 enmiid和print参数的WebAssembly处理 滑块缺口识别算法 轨迹生成方法 风控绕过技巧 通过完整实现上述流程,可以达到99%的验证通过率。