手记

【AI 逆向专栏】图标文字点选类验证码逆向、识别,对古法的全面冲击

声明

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

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

前言

当下早已是全民 AI 的时代,人工智能不再是遥不可及的科技概念,而是深度扎根在程序员日常工作里的必备搭档。

从需求梳理、代码编写、BUG 排查,到逆向分析、脚本开发以及文档撰写(比如这个前言哈哈)等等,AI 早已渗透到程序员工作的每一个环节。习惯了 AI 辅助提效的我们,早已离不开这种事半功倍的工作模式:繁琐的重复代码一键生成,难解的报错快速定位,复杂的逻辑思路瞬间梳理,极大节省了时间精力,提升了开发效率。

一旦遇上模型宕机的时刻,很多程序员都会瞬间陷入手足无措的境地,写代码没思路、排错没头绪、进度直接停滞,忍不住叫苦不迭:

这恰恰印证了 AI 如今的价值分量。它不再是可选的加分项,而是程序员提升产能、简化工作、突破效率瓶颈的刚需利器,已然成为编程路上不可或缺的得力伙伴。

咱做逆向也是一样,得跟上时代的浪潮,感受新纪元的红利,古法尤可贵,效率价更高,不论是 web 还是 app 现在都有相对成熟的 AI 方案,各大模型的能力也越来越强。不要一味守着老手艺,看 AI 的分析思路,也能学到很多新的知识点。

本文将运用 AI 技术开展加密分析工作,重点探索零标注场景下,AI 算法识别图标文字点选类验证码的能力与性能表现,拓展新的 AI 应用领域。

逆向目标

  • 目标:某某会登录图标文字点选验证码
  • 网址:aHR0cHM6Ly9wYXNzcG9ydC52aXAuY29tL2xvZ2lu
  • AI 模型:deepseek-v4-proGPT-5.5

抓包分析

进入网站,打开开发者工具抓包,选择账户登录,随便输入账密,点击登录,即会触发点选验证码:

/postLogin 接口响应返回 captchaId,即验证码标识,会作为参数用于后续发起一些请求。该接口的请求参数中,api_keypc_eversionskey 为定值,pc_edata 参数、请求头中的 authorization 以及 cookies 中的 mars_cidmars_sid 参数都是经过加密处理的,如果错误,则会响应返回 {"msg":"not authorized","code":11001},后文会具体分析这些参数:

/getURL 接口返回了获取背景、标题图片所需的 imageId 参数,请求参数中的 captchaId 是上文接口返回的,captchaType 7 为点选类验证码,data 中包含了一些指纹信息,cid 即 mars_cid

携带对应的 imageId 参数请求 /getImage 接口,即可获取到相关的验证码图片:

/check 为验证接口,需要关注的就是,请求参数 data 中的 points,即点选坐标:

data = {
    "type": [
        "browser",
        "screen",
        "mars",
        "bootstrap"
    ],
    "browser": {
    	"ua": ""
    },
    "screen": {
        "width": 1536,
        "height": 864
    },
    "mars": {
    	"cid": ""
    },
    "bootstrap": {
    "version": "vsc-3025eccc.js"
    },
    "points": [],
    "antiCacheTime": anti_cache_time
}
data = json.dumps(data, separators=(',', ':'))

  • 识别正确:{“code”:0,“message”:“SUCCESS”,“data”:{“ticket”:“xxx”,“remain”:0}}
  • 识别错误:{“code”:2004,“message”:“CAPTCHA_MISMATCH”,“data”:{“remain”:0}}

逆向分析

古法逆向

先来看看请求头中的 authorization 参数是如何生成的。怎么定位呢?咱直接掏出老手艺 ------ hook!相关脚本如下,看到的瞬间,会不会有点恍惚:

(function () {
    var org = window.XMLHttpRequest.prototype.setRequestHeader;
    window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
        if (key == 'Authorization') {
            debugger;
        }
        return org.apply(this, arguments);
    };
})();

控制台输入脚本,回车,然后点击登录,即会断住:

接着就是大伙熟悉的向上跟栈环节,跟到 encryptAjaxFun 处发现 Authorization 的值已经生成了,于此处赋值:

鼠标选中 Authorization.getSign 跟进去,跳转到以下代码处:

singString = window.sign ? window.sign.getSign(url, params) : ""

很明显,快找到真正的算法位置了,继续跟到 window.sign.getSign 中瞅瞅,果然,找到了完整的算法生成逻辑:

getSign: function(url, param, cookie) {
    var rs = "";
    var _this = this;
    var api = _this.replaceHost(url);
    var hashParam = _this.hashParam(param, url);
    var cid = _this.getCookie("mars_cid") ? _this.getCookie("mars_cid") : "";
    var sid = _this.getCookie("mars_sid") ? _this.getCookie("mars_sid") : "";
    var secret = _this.getSecret(param);
    rs = this.sha1(api + hashParam + sid + cid + secret);
    rs = "OAuth api_sign=" + rs;
    return rs
},

这里下断分析下就知道具体逻辑了,未混淆,并且是标准算法,没啥难度,几个环境参数相关联。需要注意的是 hashParam 参数的入参 param,可以下个日志断点观察下,传的不对,是无法通过验证的。

mars_cidmars_sid 也参与了 Authorization 的生成,正好 cookies 中这俩参数也是必须的,顺手分析下。直接 ctrl + shift + f 全局搜索下,定位到 mars.js 文件中,生成位置分别如下,python 复现即可:

o = h.mars_sid || Mar.Random.rand()
m = Mar.Util.encryptCid(Mar.Util.pad((new Date).getTime(), 13) + "_" + Mar.Random.rand())

最后来找下 pc_edata 的生成位置,由于相关 js 文件都未经过混淆处理,所以直接全局搜索关键字,多半就能定位到大概的位置。如下图所示,此时,pc_edata 的值已经生成了:

同样的,向上跟栈即可定位到算法生成的位置,相关逻辑如下:

set.data = window.vipParamsEncrypt.encrypt(_this.skey, set.data);

跟进去,跳转到的,就是真正的加密算法,标准的 AES 加密:

可以去工具站 https://www.kgtools.cn/secret/aes 中对比验证下,至此,加密参数就都分析完成了,适合入门练手。

AI 逆向

加密算法部分,本文将用 claude code + js-reverse-mcp + deepseek-v4-pro 进行 AI 逆向尝试,至于都用到了 Claude Code,为啥不用 Claude Opus 4.7 呢?显而易见,支持国产(兜里没子儿)。

直接用 Claude Code 对接上 deepseek,让他访问网站分析,是不行的,Claude Code 内置了安全策略,存在网络安全限制,导致它无法直接访问相关接口。虽然其会尝试通过 Web Search 绕开限制,但那也是执行网络搜索,尝试从公开资料里获取相关信息,这显然是不靠谱的:

上篇 AI 逆向案例没借助 mcp,是因为先将算法逻辑所在的 js 文件保存到了本地,然后 AI 读取相关文件进行分析:

【AI 逆向专栏】某搜登录逆向,古法的末路:https://mp.weixin.qq.com/s/B2QjKHH1LoKfku3ZJpxytw

因此,本文是一个新的思路。当然,实际应用时,大伙自行选择更适合的方案。js-reverse-mcp 项目如下,按需安装环境即可:

以 Claude Code 为例,如下所示,即安装成功:

D:\xxx>claude mcp add js-reverse npx js-reverse-mcp
Added stdio MCP server js-reverse with command: npx js-reverse-mcp to local config
File modified: C:\Users\xxx\.claude.json [project: D:\xxx]

D:\xxx>claude mcp list
js-reverse: npx js-reverse-mcp - ✓ Connected

deepseek 接入 Claude Code 参考:

输入 claude ,显示如下,即配置成功:

接下来输入提示词询问即可,比如:

进入 https://xxx.vip.com/login 这个网站,选择账户登录,用户名输入 12311111111,密码输入 123123,点击登录会触发验证码,有个接口 https://xxx/postLogin,请求参数中的 pc_edata,被加密了,我需要知道他的生成逻辑。

模型会自动调用 js-reverse,涉及权限相关的,选择 yes 或者 2 即可:

如果遇到问题,模型会自行尝试解决,如若不行,还会更换方案,直到解决问题:

观察思考过程,有问题及时干预,调教、纠正,免得走岔劈了,白耗 tokens。本案例不算复杂,模型分析的一些关键点并无问题,整体还算顺利。

经过 20 分钟的思考,AI 成功用 python 还原出了 pc_edata 的加密流程,一些常量判断无误,顺手还解决了 Authorization:

测试验证下算法是否正确,入参相同的情况,pc_edata 还存在一个动态值 iv,先固定 iv:

iv = CryptoJS.enc.Utf8.parse("1234567890123456")  // JavaScript

// iv = b"1234567890123456"  // Python

经过对比测试,验证了 AI 的算法,生成的值与网页端一致:

相关算法会分享到知识星球中,以供学习交流。

AI 识别

如果算法都弄好了,在未解决识别之前,想要验证整体流程是否能跑通,怎么办呢?可以考虑将 Base64 编码的图片数据,用图形界面显示出来,然后监听用户鼠标点击,返回所有点击位置的坐标(相关脚本会分享到知识星球中)。这样,能保证传参坐标准确无误,如果验证失败,肯定就是算法存在问题,减少干扰项:

有关点选类验证码识别模型的训练,往期写过标准化流程的文章:

人均通杀点选验证码!Yolov5 + 孪生神经网络 + 图像分类:https://mp.weixin.qq.com/s/MgH1obfYrCGivgRvjTX2GA

这一套操作下来,多少还是有些成本与门槛的。本文将尝试通过 AI 大模型,不训练模型,纯靠 ocr + 算法匹配出相应的坐标位置。想自己实现,还是很需要些经验和算法功底的,感兴趣的小伙伴可以自行尝试下。

本案例,除了文字外,还叠加了一些图标,这在一定程度上,增加了视觉识别与解析的复杂度,对于 AI 来说,也是个考验。先存一组图片到本地,给定的初始提示词如下(基础):

经过漫长的思考(几十分钟),自我、人工纠正之后,能正确识别本地图片中的文字内容:

当然,想要成功率更高,肯定是需要优化提示词,根据实际情况,持续调教的,保持耐心,想要一步到位,很难。

调教过程中 deepseek 说了句:要突破这个瓶颈需要换更强的 OCR 引擎,逻辑层面已无大优化空间。这不得对比测试一下,在均采用 ddddocr + RapidOCR 技术的前提下,deepseek-v4-pro 头脑风暴了几个小时的算法,效果远不如 GPT-5.5 几十分钟(构建 + 错图优化)的产出,任重道远。

识别算法部分(DeepSeek、GPT),同样都会分享到知识星球中。

结果验证

0人推荐
随时随地看视频
慕课网APP