吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2641|回复: 39
上一主题 下一主题
收起左侧

[Web逆向] 某美官网案例滑块逆向

  [复制链接]
跳转到指定楼层
楼主
zzyzy 发表于 2025-7-5 14:44 回帖奖励
本帖最后由 zzyzy 于 2025-7-5 14:49 编辑

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!


目标:实现滑块验证。
网站aHR0cHM6Ly93d3cuaXNodW1laS5jb20vdHJpYWwvY2FwdGNoYS5odG1s


1.又到周末了,开始今天的滑块分析,直接进官网中demo在线体验,找到滑块验证。


2.抓包主要分析两个接口,一是获取验证码图片接口,二是进行校验的接口。
    图片的获取参数很少,主要看两个captchaUuid和organization,其实两个都可以固定,callback后面时间戳,固不固定都行。

   
    organization 是一个标识,在一个js文件中,固定值就行。captchaUuid直接全局搜索,有一个getCaptchaUuid函数。代码是经过ob混淆的,前半部分是当前年月日时分秒,后半部分是从 _0x2e8d92  = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'   随机获得十八位。


3.标准的ob解混淆,我这在网站看到一个在线网站,测试一下可以用,网站就不发啦,直接搜就有的,可能会超时,多等待会。

[JavaScript] 纯文本查看 复制代码
'generateTimeFormat': function _0x4c6363() {
        var _0x430757 = new Date(),
            _0x2378e5 = function _0x3174a6(_0x47652b) {
          return +_0x47652b < 10 ? '0' + _0x47652b : _0x47652b["toString"]();
        };

        return _0x430757["getFullYear"]()["toString"]() + _0x2378e5(_0x430757['getMonth']() + 1) + _0x2378e5(_0x430757["getDate"]()) + _0x2378e5(_0x430757["getHours"]()) + _0x2378e5(_0x430757["getMinutes"]()) + _0x2378e5(_0x430757["getSeconds"]());
      },
      'getCaptchaUuid': function _0x1c52e3() {
        var _0x41580c = '',
            _0x2e8d92 = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",
            _0x24bf2f = _0x2e8d92['length'];

        for (var _0x117c27 = 0; _0x117c27 < 18; _0x117c27++) {
          _0x41580c += _0x2e8d92['charAt'](Math['floor'](Math["random"]() * _0x24bf2f));
        }


4.这是解混淆后代码,看着就是比之前好看。(ast好啊,还是待写,dddd),主要还是看校验接口,参数多一些。


5.校验成功结果中 riskLevel: "PASS"  失败是 "riskLevel":"REJECT"。请求参数看着有什么,其实加密方式都一样,就key和明文不一样。可以直接全局搜索 'tm' ,结果有三个。为啥搜它呢,密文长度独特,每次都会更新。看着都引人注目。


6.可以解混淆后代码,本地替换,或者fidder或者,插件替换都行。注意是代码要压缩成一行,因为里面有自定义格式化检测isJsFormat,每次加密明文的时候,为true会更改key值为_0x45d705 --> 是一个时间戳加域名。


7.当然看原文也可以的,回到上面分析tm的参数由来,在switch之前有很多参数。请求参数的生成都是从过getEncryptContent方法。


_0x54ba18 = _0x2f5942[_0x4a8786(0x2c7)]       鼠标轨迹
_0x53e48a = _0x2f5942[_0x4a8786(0x8da)]      滑动开始时间
_0x278de4 = _0x2f5942[_0x4a8786(0xaa9)]      滑动结束时间
_0x4f9d04 = _0x2f5942['mouseEndX']               滑动距离
_0x4f5460 = _0x2f5942[_0x4a8786(0x1d9)]      图片宽度
_0x41b1a4 = _0x2f5942['trueHeight']               图片高度
_0x3ef349 = _0x2f5942[_0x4a8786(0x602)]       空数据 fr 的明文
_0x20abcb = _0x2f5942[_0x4a8786(0x83e)]     滑块宽度

8.进到getEncryptContent 里面是一个switch控制流,主要注意一下key,和加密过程。这是一个des标准的加密算法 mode 是 ECB,padding 是 ZeroPadding,不需要 iv,在线网站测试或者py的标准库。


9.因为有很多参数,在break前打上日志断点,看方便,在根据请求参数一一对应,可以看到有部分参数的明文是固定的,注意的就是tm tb 和ly ,对应着轨迹, 距离比背景宽度,和滑动时间。


10.距离识别我这使的是ddddocr,学习来说够用了,需要注意的是,背景图片的比例,下载下来的是600*300,在官网显示的是300*150,识别的距离除以2就行。
11.关于key的获取,都在ob混淆的大数组中,根据版本不同相应的改变,现在来看版本是 v1.0.4-184/captcha-sdk.min.js



12.使用在线ob解混淆后代码看的很清晰了,版本不更新key应该不会变吧,等后面跟踪一下,我这使用python还原,下面是一些方法代码。

[Python] 纯文本查看 复制代码
def generate_slider_track(target_distance):
    track = []
    current_distance = 0
    current_time = 0
    y_offset = 0
    track.append([0, random.randint(0, 10), 0])
    while current_distance < target_distance:
        # 时间步长随机,模拟不均匀采样,90~110ms之间
        time_step = random.randint(90, 110)
        current_time += time_step

        # 横向步长,接近目标时减小步长
        if target_distance - current_distance > 10:
            x_step = random.randint(4, 10)
        else:
            x_step = random.randint(1, 4)

        current_distance += x_step
        if current_distance > target_distance:
            current_distance = target_distance

        # 纵向浮动在-5到5之间,模拟抖动
        y_offset = random.randint(-5, 5)
        track.append([current_distance, y_offset, current_time])

    return track


def DESEncrypt(key, text):
    key_bytes = key.encode('utf-8')
    des = DES.new(key_bytes, DES.MODE_ECB)
    padded_text = text.encode('utf-8')
    pad_len = 8 - (len(padded_text) % 8)
    if pad_len != 8:
        padded_text += b'\x00' * pad_len
    encrypted_bytes = des.encrypt(padded_text)
    # 返回Base64编码字符串
    return base64.b64encode(encrypted_bytes).decode('utf-8')


def random_str():
    return ''.join(random.choice('ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678') for _ in range(18))


def get_distance(bg, tp, save_path=None):
    det = DdddOcr(det=False, ocr=False, show_ad=False)
    res = det.slide_match(tp, bg, simple_target=True)
    if save_path is not None:
        # 将背景图片的二进制数据加载为Pillow Image对象
        left, top, right, bottom = res['target'][0], res['target'][1], res['target'][2], res['target'][3]
        bg_image = Image.open(io.BytesIO(bg))
        draw = ImageDraw.Draw(bg_image)
        draw.rectangle([left, top, right, bottom], outline="red", width=2)
        bg_image.save(save_path)
        print(f"已保存标注后的图片到: {save_path}")
        return res
    return res


13.轨迹-加密-随机字符串-距离识别,好了,完结撒花,又是愉快的周末,基本流程就这些了,测试一下,结果正确,这个demo分析完了,感谢大佬们观看。














免费评分

参与人数 12吾爱币 +12 热心值 +8 收起 理由
JiangtaoChiu + 1 验证码逆向确实难,真大佬,感谢分享。
Lsais + 1 谢谢@Thanks!
tomoon + 1 热心回复!
niugle + 1 我很赞同!
muzili520 + 1 + 1 我很赞同!
sanqiuye + 1 + 1 我很赞同!
lin5789 + 1 我很赞同!
timeni + 1 + 1 谢谢@Thanks!
beihai1314 + 1 + 1 热心回复!
抱歉、 + 1 用心讨论,共获提升!
buluo533 + 2 + 1 用心讨论,共获提升!
helian147 + 2 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
lightsuper001 发表于 2025-7-20 16:20
[Python] 纯文本查看 复制代码
def generate_slider_track(target_distance):
    track = []
    current_distance = 0
    current_time = 0
    
    # 初始点
    y_offset = random.randint(-5, 5)
    track.append([0, y_offset, current_time])
    
    # ===== 三阶段运动模型 =====
    # 1. 加速阶段 (0-15%距离)
    acceleration_end = int(target_distance * 0.15)
    while current_distance < acceleration_end:
        time_step = random.randint(40, 70)
        current_time += time_step
        x_step = random.randint(4, 8)  # 较大步长
        current_distance = min(current_distance + x_step, target_distance)
        y_offset += random.randint(-2, 2)
        y_offset = max(-10, min(10, y_offset))
        track.append([current_distance, y_offset, current_time])
    
    # 2. 匀速阶段 (15%-85%距离)
    main_phase_end = int(target_distance * 0.85)
    while current_distance < main_phase_end:
        time_step = random.randint(80, 120)
        current_time += time_step
        x_step = random.randint(5, 9)  # 中等步长
        current_distance = min(current_distance + x_step, target_distance)
        y_offset += random.randint(-3, 3)
        y_offset = max(-15, min(15, y_offset))
        track.append([current_distance, y_offset, current_time])
    
    # 3. 减速阶段 (最后15%)
    while current_distance < target_distance - 3:  # 预留3px给微调
        time_step = random.randint(100, 150)
        current_time += time_step
        x_step = random.randint(2, 4)  # 小步长
        current_distance = min(current_distance + x_step, target_distance)
        y_offset += random.randint(-4, 4)  # 增大抖动模拟紧张
        y_offset = max(-20, min(20, y_offset))
        track.append([current_distance, y_offset, current_time])
    
    # ===== 关键优化:精准到达和停留 =====
    # 确保精确到达目标
    if current_distance < target_distance:
        current_time += random.randint(80, 120)
        current_distance = target_distance
        y_offset += random.randint(-2, 2)
        track.append([current_distance, y_offset, current_time])
    
    # 停留阶段(3-5个点)
    stay_points = random.randint(3, 5)
    for _ in range(stay_points):
        current_time += random.randint(100, 200)  # 较长间隔
        
        # 微小抖动(±1px),80%概率保持目标位置
        if random.random() < 0.8:
            final_distance = target_distance
        else:
            final_distance = target_distance + random.randint(-1, 1)
        
        y_offset += random.randint(-2, 2)
        track.append([final_distance, y_offset, current_time])
    
    return track



我自己用AI写了一个滑块轨迹,成功率提高了好多
沙发
buluo533 发表于 2025-7-5 16:57
3#
 楼主| zzyzy 发表于 2025-7-5 17:13 |楼主
4#
buluo533 发表于 2025-7-5 17:17
zzyzy 发表于 2025-7-5 17:13
你才是大佬,向你学习

又多学了一门验证码手艺
5#
yxf515321 发表于 2025-7-6 10:07
感谢大佬分享,厉害了
6#
Tily 发表于 2025-7-6 12:35
感谢分享。学到了
7#
wasd71 发表于 2025-7-6 13:24
不错 多看看你们的思路
8#
zhenyuan27 发表于 2025-7-6 16:33
感谢分享,学到了
9#
whyzl20 发表于 2025-7-7 09:07
活到老学到老。感谢楼主。
10#
lingtian_shi 发表于 2025-7-7 15:13
厉害了,虽然还有一些不太明了,但是整体思路已经很清晰了。膜拜
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-7-20 17:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表