【JavaScript 逆向】百度旋转验证码

百度旋转验证码

前言

好久没更新了暑假摆烂了好久,因为业务需要今天给大家带来某度的旋转验证。

image-20230913235124916


本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!


案例目标

v1旋转验证 #此接口需要加上代理才会出现验证 会出现302重定向 拿到location的url就OK

aHR0cHM6Ly93YXBwYXNzLmJhaWR1LmNvbS9zdGF0aWMvY2FwdGNoYS90dXhpbmcuaHRtbD9haz1iZDVlZTFlMGJhNWI5NGRiMjYwMzFlYTU5M2Y2NDk1NCZiYWNrdXJsPWh0dHBzJTNBJTJGJTJGYmFpa2UuYmFpZHUuY29tJTJGdmlldyUyRjMwMDAwMDAwLmh0bSZ0aW1lc3RhbXA9MTY5NDU2NzcxNiZzaWduYXR1cmU9NDY4ODg3NDEzNjVhOWMwNTA2NmY0Nzk4M2I1MTQ0MmI=

image-20230914001709945

image-20230913235157504

抓包分析

经过多次抓包

viewlog

'''接口请求参数'''
ak: #是固定值
callback : #时间戳回调值
'''返回值'''
as:
ds:
tk:
#后面加密会用到

image-20230913235301111

image-20230913235322154

getstyle

'''请求参数'''
callback: jQuery110205723696566632106_1694570460652
ak: #固定值
tk: #前面接口返回
scene: 
isios: 0
type: spin #类型旋转
_: 时间戳

'''返回参数'''
jQuery110205723696566632106_1694570460652({
    "code": 0,
    "data": {
        "type": "spin",
        "backstr": #后面加密会用到,
        "ext": {
            "img": #图片信息,
            "info": #图片版权信息,
            "sup": 1
        }
    }
})

image-20230913235350900

image-20230913235410234

第二次viewlog 验证接口

'''请求参数'''
callback: jQuery110208208017481037706_1694571180129
ak: bd5ee1e0ba5b94db26031ea593f64954#固定
as: d569fd29#第一个view接口返回
fs: #有关旋转角度加密
tk: #第一个view接口返回
scene: 
cv: submit
_: 1694571180132

'''返回值'''
jQuery110208208017481037706_1694571180129({
    "code": 0,
    "data": {
        "tk": #后续接口会用到,
        "as": "d569fd29",
        "ds": #后续接口会用到,
        "op": 0 #成功返回1  失败返回0
    }
})

image-20230913235459025

image-20230913235524771

c?callback

上面验证之后还有一个接口 验证了会返回url 然后就可以愉快的请求了!

image-20230913235558521

fs参数逆向

根据上面分析我们只需要分析 fs参数就行了。

image-20230913235708015

拖动验证码发现断住OK

image-20230913235915066

i = JSON.stringify(r.rzData)
o = r.encrypt(i)
s.fs = o

可以看到 r.rzData 是待加密的 经过r.encrypt就变成密文了

{
    "cl": [
        {
            "x": 871,
            "y": 248,
            "t": 1694572801344
        }
    ],
    "mv": [
        {
            "fx": 1085,
            "fy": 288,
            "t": 1694572800391,
            "bf": 2
        },
        {
            "fx": 955,
            "fy": 272,
            "t": 1694572800553,
            "bf": 2
        },
        {
            "fx": 891,
            "fy": 247,
            "t": 1694572800710,
            "bf": 2
        },
        {
            "fx": 886,
            "fy": 247,
            "t": 1694572800887,
            "bf": 2
        },
        {
            "fx": 878,
            "fy": 251,
            "t": 1694572801048,
            "bf": 2
        },
        {
            "fx": 872,
            "fy": 249,
            "t": 1694572801247,
            "bf": 2
        },
        {
            "fx": 875,
            "fy": 248,
            "t": 1694572801407,
            "bf": 1
        },
        {
            "fx": 899,
            "fy": 251,
            "t": 1694572801575,
            "bf": 1
        },
        {
            "fx": 905,
            "fy": 252,
            "t": 1694572801727,
            "bf": 1
        },
        {
            "fx": 921,
            "fy": 256,
            "t": 1694572801895,
            "bf": 1
        },
        {
            "fx": 932,
            "fy": 259,
            "t": 1694572802055,
            "bf": 1
        },
        {
            "fx": 940,
            "fy": 261,
            "t": 1694572802208,
            "bf": 1
        }
    ],
    "sc": [],
    "kb": [],
    "sb": [],
    "sd": [],
    "sm": [],
    "cr": {
        "screenTop": 0,
        "screenLeft": 0,
        "clientWidth": 1920,
        "clientHeight": 289,
        "screenWidth": 1920,
        "screenHeight": 1080,
        "availWidth": 1920,
        "availHeight": 1040,
        "outerWidth": 1920,
        "outerHeight": 1040,
        "scrollWidth": 1920,
        "scrollHeight": 1920
    },
    "simu": 0,
    "ac_c": 0.34,#有关角度
    "backstr": '前面接口返回的'
}

后面结果测试clmv 都不校验,所以这个解决旋转角度即可

image-20230914000243802

当然没有! 我们需要的是图片的旋转角度但是前端是拖动滑的距离呀? 这肯定有个距离和角度转换的公式?

搜索ac_c: 我们发现是滑动距离÷固定值=ac-c得到的 所以需要识别出滑动距离可以直接计算或者直接上角度

o = r.clientX - i.currentX,
i.percentage = parseFloat(o / a).toFixed(2),

image-20230914000414794

image-20230914000514872

接下来就是 r.encrypt(i)

image-20230914000632192

image-20230914000717155

image-20230913235029956

const CryptoJS = require("crypto-js");

//前面接口返回
var as = "15c9fec9",
e = '数据'

// 传入接口的as->str   加密数据e->JSON
function encrypt(as, e) {
    var t = as + "appsapi0"
        , n = CryptoJS.enc.Utf8.parse(t)
        , i = CryptoJS.enc.Utf8.parse(JSON.stringify(e))
        , r = CryptoJS.AES.encrypt(i, n, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return r.toString()
}

//console.log(encrypt(as,e))

完全是标准的AES加密,老铁们直接干就完事了,准备溜了!

总结

参数逆向就到这里了,没想到某度的验证码连魔改加密,混淆代码都没有用有点小小失望!

给大家看看结果

image-20230913234918035

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
好的,以下是一个基本的验证码实现,使用了HTML、CSS和JavaScript: HTML部分: ```html <div id="captcha"> <canvas id="canvas"></canvas> <input type="text" id="captchaInput" placeholder="输入验证码"> <button id="refreshBtn">刷新</button> <button id="submitBtn">提交</button> </div> ``` CSS部分: ```css #captcha { display: flex; flex-direction: column; align-items: center; } canvas { border: 1px solid #ccc; } input, button { margin-top: 10px; padding: 5px; font-size: 16px; } button { cursor: pointer; } ``` JavaScript部分: ```javascript // 获取canvas元素 const canvas = document.getElementById('canvas'); // 获取刷新按钮元素 const refreshBtn = document.getElementById('refreshBtn'); // 获取提交按钮元素 const submitBtn = document.getElementById('submitBtn'); // 获取输入框元素 const captchaInput = document.getElementById('captchaInput'); // 获取2D上下文 const ctx = canvas.getContext('2d'); // 定义验证码字符集 const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; // 定义随机数函数 function random(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } // 生成随机验证码 function generateCaptcha() { // 生成随机的四个字符 let captcha = ''; for (let i = 0; i < 4; i++) { captcha += charset[random(0, charset.length - 1)]; } // 绘制验证码到canvas上 ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.font = 'bold 30px sans-serif'; ctx.fillText(captcha, 10, 35); // 返回验证码字符串 return captcha; } // 初始化页面 function init() { // 设置canvas宽高 canvas.width = 200; canvas.height = 50; // 生成初始验证码 const captcha = generateCaptcha(); // 点击刷新按钮生成新的验证码 refreshBtn.addEventListener('click', function() { const captcha = generateCaptcha(); }); // 点击提交按钮检查验证码是否正确 submitBtn.addEventListener('click', function() { if (captchaInput.value.toLowerCase() === captcha.toLowerCase()) { alert('验证码正确'); } else { alert('验证码错误'); } }); } init(); ``` 以上代码实现了一个基本的验证码功能,当点击刷新按钮时会生成新的验证码,当点击提交按钮时会检查输入框中的值是否与当前验证码相同。注意,这只是一个非常简单的实现,实际中还需要考虑更多的安全和易用性问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值