乐于分享
好东西不私藏

【AI 逆向专栏】古法 & AI:某程滑块验证码逆向分析

【AI 逆向专栏】古法 & AI:某程滑块验证码逆向分析

声明

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

本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【K哥爬虫】联系作者立即删除!

前言

最近收到私信,询问关于某程滑块的解法,难度不大。经过分析,完全可以通过 AI 来完成逆向,本文将对该站进行相关分析。

抓包分析

抓包可知触发验证码是由 captcha/v4/risk_inspect 接口触发的,如下:

参与请求的值有 dimensionsextend_paramsign。验证后接口返回 token、rid 以及图片信息。验证接口相比图片接口多了一个verify_msg  参数:

通过校验后 token 被激活:

古法逆向

从 risk_inspect 包入口进入,定位到如下地方:

发现了载荷中要找的几个值,生成逻辑如下:

r = _0x342058(_0x311148[_("0x72")](n), 0),a = {resolution_width: M[_("0xa5")],resolution_height: M.scrH,language: P},c = _0x342058(_0x311148.stringify(a), 0),o = _0x110baa[_("0x97")]("appid=" + s + _("0x10e") + f + "&version=" + D[_("0x4d")] + _("0x74") + r + _("0x3a") + c),G(H[_("0x75")] + H[_("0x6c")], {extend_paramencodeURIComponent(c),appid: s,business_site: f,version: D[_("0x4d")],dimensionsencodeURIComponent(r),sign: o[_("0xad")]()

第一个参数 extend_param 是通过 c = _0x342058(_0x311148.stringify(a), 0) 生成的,a 为常见的信息:

{"resolution_width"1512,"resolution_height"982,"language"""}

同时 dimensions 生成方式相同,也是通过 r = _0x342058(_0x311148[_("0x72")](n), 0) 生成。

n 大部分为指纹信息,这里做脱敏处理:

{"rt""fp=44779A-738C77-EF371C&vid=1779266823753.8bb8R2qxntXk&pageId=10320670296&r=06fed28fb6c0464c9201df7d452ba538&ip=223.104.124.240&rg    "ua":     **********************脱敏处理***********************************    "p": "pc",    "fp": "44779A-738C77-EF371C",    "vid": "1779266823753.8bb8R2qxntXk",    "identify": "a44779A-738C77-EF371C",    "guid": "09031151214445559123",    "h5_duid": null,    "pc_duid": null,    "hb_uid": null,    "pc_uid": null,    "h5_uid": null,    "infosec_openid": null,    **********************脱敏处理***********************************    "client_type": "PC",    "site": {        "type": "PC",        "url": "",        "ref": "https://www.ctrip.com/","title""登录首页","keywords"""    },"device": {"width"1512,"height"982,"os""","pixelRatio"2,"did"""    },"user": {"tid""","uid""","vid"""    }}

sign 则是通过 o = _0x110baa[_("0x97")]("appid=" + s + _("0x10e") + f + "&version=" + D[_("0x4d")] + _("0x74") + r + _("0x3a") + c) 生成的,经过分析 _0x110baa[_("0x97")] 为 md5 算法。

所以现在就剩 _0x342058 需要分析,单步跟进可以发现是 new 了一个方法,然后经过 n 函数最终生成的:

n = new _0x254c65(128,1e3);return0 === e ? n[t("0xcd")](i, x) : n[t("0x108")](i, x)

进入 n 函数中,发现是通过 encrypt 生成的,该 aes 也未经过魔改,标准算法:

return e[x("0x86")][x("0xcd")] = function(e, t{var i = x;return _0x110baa[i("0x94")].encrypt(t, this.key, {iv: _0x110baa[i("0xae")][i("0x2d")][i("0x2c")](e)            })[i("0x123")][i("0xad")](_0x110baa[i("0xae")][i("0xf")])        }        ,

最后一个校验函数与上述流程类似,多了一个 verify_msg 参数,定位到下图处,同样还是由 n 函数生成:

_0x13f650 包含了轨迹以及少部分浏览器信息,这些搞定后即可将整个验证码过掉。

篇外

实际上,手动登陆如果每次清空缓存是不会弹出验证码的,频繁点击后必出验证码。经过研究发现,dimensions 中的 fp 与 rt(即 rmstoken) 指纹参数很重要,决定了是否会触发验证码。

定位 rt 相对简单,rt 和 fp 参数都是从 M 中取值的,向上定位 M:

rt: M[_("0x71")],ua: M.userAgent,p: i,fp: M.FP,

最终找到下图位置:

跟进后发现最终生成逻辑是挂到 getRmsToken 上的:

同时还挂载到 window 里面,直接调用 rmstoken = window.RMS.getRmsToken() 即可:

rms 的定位也大同小异,trigger 中发现其被当参数传进去的,继续向上跟:

最终定位到下图处,由 cfp 函数生成:

至此,我们把环境补齐,直接调用这几个函数即可生成相关参数:

AI 逆向

对于 AI 逆向的话,能不能搞出来取决于提示词,不管是 mcp 还是静态分析都是不错的方法,同样还是丢万能提示词:

再然后就可以解放双手了,等个几分钟看一下结果:

经过验证,与古法分析的结果完全一致。相关代码将分享到知识星球中,仅供学习交流。

结果验证

( 先别划走 点个关注 Orz )

代理IP推荐

产品国内代理产品低至𝟓折起

海外代理产品低至𝟗元/𝐆

海外代理IP推荐

- 专注不限量海外代理IP服务!

- 服务超过半数人工智能、大数据企业!

- 123proxy.cn -- 海外大数据采集、爬虫应用的代理IP选择!

🌏 BestProxy 海外真实住宅IP

- 全球高纯家庭住宅IP,稳定突破海外各大平台反爬!

- 纯净指纹、长时间不掉线,支持 HTTP/SOCKS5 + 精准定位,适合大规模采集。

复制到浏览器打开,新用户享9折优惠👇

https://bestproxy.com/?keyword=4hbh51kn

点个推荐求求你啦