js逆向-某验3代滑块验证码分析

声明

本文仅供学习参考,如有侵权可私信本人删除,请勿用于其他途径,违者后果自负!
如果觉得文章对你有所帮助,可以给博主点击关注和收藏哦!

插句个人内容:本人最近正在找工作,工作城市:广州。如果有合适的机会,希望有大佬可以内推,感激不尽。🙏
js逆向马马虎虎,app会弱一些。感兴趣的大佬可以私信本人要简历。

流程分析

本篇使用网站:

aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby9zbGlkZS1mbG9hdC5odG1s

整个滑块验证码的流程如下,其中需要注意的接口都已经标记过。
image.png

分别解释一下用途。

  • 第一个接口

无加密参数参数,返回gtchallenge两个字段,这两个字段贯穿整个流程,十分重要。
image.png

  • 第二个接口

该接口会返回很多字段,能够使用到的也就是c,此时出现了第一个w
image.png

过去旧版的第一个w和第二个w都可以选择置空,但是现在这样做已经校验不过去了。
请求参数如下gtchallenge前面一个接口已经获得了,然后就是这个w了。
image.png

  • 第三个接口

返回了滑块类型,之前一直觉得这个接口没什么用,直接就忽略了,发现怎么都不能校验过去。
image.png
同时该接口的w值也不可忽略,还是要拿下,不可写死或置空处理。

  • 第四个接口

这个接口就是校验验证码缺口的接口了,成功了就会返回success,否则就是fail,当然还有其他的一些状态,可以根据返回的状态去排查对应的问题。

逆向分析

第一个w

第一个接口处,可以在Initiator中跳进js文件打下断点一步步跟栈。
image.png

image.png
或者直接搜索i + r,然后打下断点。
image.png
ir对应生成的值拿下来就可以还原第一个w了。

先看一下r是什么内容。
image.png
先把这个函数直接拿下来,然后运行。
image.png
报错,yCtOu未定义,寻找一下是什么东西。
image.png
将需要的部分都拿下。
重新运行,继续报错。
image.png
X没有定义,继续扣代码。这样做太慢了,可以直接把整个文件copy到本地然后慢慢补。
image.png
然后就可以很轻松的找到需要的内容了。
继续运行,window未定义。
image.png
pe是什么不知道,回到网页中看一下
image.png
image.png
缺少navigator补上就完了,需要的环境大致如下:

window = global;
navigator = {
    appName:'Netscape'
}
pe = navigator

image.png
报错复制到网页上观察一下。
image.png
看样子像一个随机数,找到函数位置。
image.png
image.png
四位随机数生成四次然后进行字符串拼接。
最后结果就出来了。
image.png

o的代码:

o = $_BFo()[$_CEGDt(1108)](de[$_CEGEy(459)](t[$_CEGEy(369)]), t[$_CEGDt(1196)]())

手动解混淆:

o = $_BFo()['encrypt1'](JSON.stringify(t['$_EJV']), t["$_CCHU"])

t[‘$_EJV’]是一个大的对象,除了gt和challenge之外,其他都可以固定。

{
    "gt": "传入gt",
    "challenge": "传入challenge",
    "offline": false,
    "new_captcha": true,
    "product": "float",
    "width": "300px",
    "https": true,
    "api_server": "apiv6.geetest.com",
    "protocol": "https://",
    "type": "fullpage",
    "static_servers": [
        "static.geetest.com/",
        "static.geevisit.com/"
    ],
    "beeline": "/static/js/beeline.1.0.1.js",
    "voice": "/static/js/voice.1.2.4.js",
    "click": "/static/js/click.3.1.0.js",
    "fullpage": "/static/js/fullpage.9.1.9-r8k4eq.js",
    "slide": "/static/js/slide.7.9.2.js",
    "geetest": "/static/js/geetest.6.0.9.js",
    "aspect_radio": {
        "slide": 103,
        "click": 128,
        "voice": 128,
        "beeline": 50
    },
    "cc": 20,
    "ww": true,
    "i": "-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1!!-1"
}

t[“$_CCHU”]则是上一次省的16位随机数,需要和生成r部分保持一致的值。

然后将$_BFo()函数拿下来就得到结果。
image.png

i就简单了,将o生成的数组变成字符串。
image.png
还是缺啥补啥,最终第一个w结果。
image.png

第二个w

同样使用Initiator追溯,向上寻找堆栈,慢慢分析也可以找到。
image.png
不过比较麻烦,可以直接搜索var n = {}
调试发现断点没有经过t[$_CFEEo(1109)]();w还没有生成,所以w肯定在该函数之前生成了。
image.png
image.png

函数很长,直接看return处。
最终定位到。
image.png

手动解混淆:

p['$_HEt'](c["encrypt"](r, i["$_CCHU"]()));

实际上和第一个w的加密一样
重点看一下r,r是一个字符串,反序列化

{
    "lang": "zh-cn",
    "type": "fullpage",
    "tt": "MZ(*((1(j(CM7((",
    "light": -1,
    "s": "c7c3e21112fe4f741921cb3e4ff9f7cb",
    "h": "321f9af1e098233dbd03f250fd2b5e21",
    "hh": "39bd9cad9e425c3a8f51610fd506e3b3",
    "hi": "09eb21b3ae9542a9bc1e8b63b3d9a467",
    "vip_order": -1,
    "ct": -1,
    "ep": {
        "v": "9.1.9-r8k4eq",
        "te": false,
        "$_BBp": true,
        "ven": "Google Inc. (Intel)",
        "ren": "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics (0x000046A6) Direct3D11 vs_5_0 ps_5_0, D3D11)",
        "fp": [
            "move",
            744,
            147,
            1707040727652,
            "pointermove"
        ],
        "lp": [
            "up",
            672,
            82,
            1707040728689,
            "pointerup"
        ],
        "em": {
            "ph": 0,
            "cp": 0,
            "ek": "11",
            "wd": 1,
            "nt": 0,
            "si": 0,
            "sc": 0
        },
        "tm": {
            "a": 1707040721021,
            "b": 1707040721290,
            "c": 1707040721290,
            "d": 0,
            "e": 0,
            "f": 1707040721021,
            "g": 1707040721056,
            "h": 1707040721056,
            "i": 1707040721056,
            "j": 1707040721122,
            "k": 1707040721089,
            "l": 1707040721122,
            "m": 1707040721286,
            "n": 1707040721288,
            "o": 1707040721292,
            "p": 1707040721503,
            "q": 1707040721503,
            "r": 1707040721504,
            "s": 1707040721562,
            "t": 1707040721562,
            "u": 1707040721564
        },
        "dnf": "dnf",
        "by": 0
    },
    "passtime": 1190827,
    "rp": "6fc9d795969c2c344ce5bc11e50c9916",
    "captcha_token": "1265749785",
    "otpj": "jm4jwcx7"
}

经过测试发现,其他值均可固定,但是rp的加密过程passtime参与了,所以要注意保持一致。
再看rp如何生成,向上寻找。(代码比较混乱,我也找了半天o(╥﹏╥)o)
image.png
image.png

使用到了gt、challenge以及passtime,加密长度32位,盲猜一波md5。 ![image.png](https://cdn.nlark.com/yuque/0/2024/png/39047339/1707042842696-bb495516-f94b-4b69-b857-e2177b168e7b.png#averageHue=%23f6f5f4&clientId=u7beac4ef-06cb-4&from=paste&height=367&id=u837eeb7b&originHeight=459&originWidth=778&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=52709&status=done&style=stroke&taskId=uaad1ca3c-47d4-418b-892d-69fb067be2b&title=&width=622.4) 完全一致,rp就已经生成了。 i"$_CCHU"依然是第一次生成的16位随机字符串,也需要使用同样的秘钥。不然会出现 param decrypt error`的错误。

至此w生成完毕。

第三个w

这个w网上有很多现成的文章了,直接搜索"\u0077"即可定位,也可以选择上面的方法,跟堆栈。
image.png

这个w其实和上面的加密方式一样,没什么好说的,这里就不展开了。
说一下不同的地方。

{
    "lang": "zh-cn",
    "userresponse": "9777999999979766a",
    "passtime": 266,
    "imgload": 73,
    "aa": "K,,(!!Msssyyt!)!)ttusYsx(!!($)/(/0101010110$nd)c",
    "ep": {
        "v": "7.9.2",
        "$_BIE": false,
        "me": true,
        "tm": {
            "a": 1707046714483,
            "b": 1707046715148,
            "c": 1707046715148,
            "d": 0,
            "e": 0,
            "f": 1707046714484,
            "g": 1707046714533,
            "h": 1707046714533,
            "i": 1707046714533,
            "j": 1707046714614,
            "k": 1707046714574,
            "l": 1707046714614,
            "m": 1707046714724,
            "n": 1707046714741,
            "o": 1707046715150,
            "p": 1707046715369,
            "q": 1707046715369,
            "r": 1707046715370,
            "s": 1707046715434,
            "t": 1707046715434,
            "u": 1707046715435
        },
        "td": -1
    },
    "h9s9": "1816378497",
    "rp": "6ca7d8a547390ce95dc57399fd88f50d"
}

userresponse 、aa和rp是需要处理的部分,其他固定即可。

  • userresponse 部分

image.png

H(滑动距离,34位challenge)

将H函数扣下来就可以实现该算法了。

  • aa部分

image.png
此时的aa已经生成了,向上找一层。
image.png

n[$_DAAAU(985)][$_CJJJU(1075)]有三个参数,分别是轨迹加密得到的结果,接口的cs(和34位challenge为一个接口)
然后将剩余代码补齐即可得到结果。
十次成功率80%

image.png

参考

最后

最近开通了个人公众号,有一些被博客下架的文章后续也会同步上去。
大佬们可以关注一波。
微信公众号.png

  • 22
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
根据提供的引用内容,美团滑块验证的js逆向过程如下所示: 1. 首先,需要获取主页接口的参数,包括csrf、uuid、token_id和continues等。这些参数可以在第一个链接返回的源码中找到。 2. 接下来,使用这些参数进行登入接口的请求,其中包括两个加密参数password和h5Fingerprint。 3. 然后,通过验证码获取的接口来获取验证码相关的参数,如verifyMethodVersion、slider、yodaVersion、timestamp、sign、ses和requestCode等。 4. 在获取到这些参数后,可以进行验证接口的请求。该请求需要使用到加密参数behavior和_token,以及动态参数v_c和3eac9809,同时还需要在请求头中添加Authencation。 总结起来,美团滑块验证的逆向过程可分为以下步骤: 1. 获取主页参数 2. 逆向pwd和h5Fingerprint 3. 请求page_data链接 4. 逆向Authencation、behavior和_token 5. 发起最终的验证请求 需要注意的是,以上仅是根据提供的引用内容进行的分析,具体的逆向过程可能还需要进一步的研究和分析。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【2023-03-10】JS逆向之美团滑块](https://blog.csdn.net/qq_26079939/article/details/129442967)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [美团滑块(1-18,js逆向)](https://blog.csdn.net/weixin_44772112/article/details/128721509)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值