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

4 阅读9分钟
![Nbczgc.png](https://v1.ax1x.com/2026/05/08/Nbczgc.png)

## 声明

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

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

## 前言

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

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

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

![NbctBf.png](https://v1.ax1x.com/2026/05/08/NbctBf.png)

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

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

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

![NbD6hQ.png](https://v1.ax1x.com/2026/05/09/NbD6hQ.png)

## 逆向目标

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

## 抓包分析

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

![NbcFYU.png](https://v1.ax1x.com/2026/05/08/NbcFYU.png)

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

![NbvPSs.png](https://v1.ax1x.com/2026/05/09/NbvPSs.png)

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

![NbvrE7.png](https://v1.ax1x.com/2026/05/09/NbvrE7.png)

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

![NbvtWI.png](https://v1.ax1x.com/2026/05/09/NbvtWI.png)

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

```python
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=(',', ':'))
```

![NbvCpL.png](https://v1.ax1x.com/2026/05/09/NbvCpL.png)

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

## 逆向分析

### 古法逆向

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

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

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

![NbD95V.png](https://v1.ax1x.com/2026/05/09/NbD95V.png)

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

![NbDkCL.png](https://v1.ax1x.com/2026/05/09/NbDkCL.png)

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

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

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

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

```JavaScript
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` 的值已经生成了:

![NbDWBY.png](https://v1.ax1x.com/2026/05/09/NbDWBY.png)

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

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

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

![NbDcgH.png](https://v1.ax1x.com/2026/05/09/NbDcgH.png)

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

### AI 逆向

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

![NbRKZY.png](https://v1.ax1x.com/2026/05/12/NbRKZY.png)

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

![NbPfkI.png](https://v1.ax1x.com/2026/05/11/NbPfkI.png)

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

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

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

> https://github.com/zhizhuodemao/js-reverse-mcp/blob/main/README_zh.md

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

```powershell
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 参考:

> https://api-docs.deepseek.com/zh-cn/quick_start/agent_integrations/claude_code

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

![NbRmb6.png](https://v1.ax1x.com/2026/05/11/NbRmb6.png)

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

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

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

![NbRpRO.png](https://v1.ax1x.com/2026/05/11/NbRpRO.png)

![NbRLZQ.png](https://v1.ax1x.com/2026/05/11/NbRLZQ.png)

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

![NbR3qf.png](https://v1.ax1x.com/2026/05/11/NbR3qf.png)

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

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

![NbRlDc.png](https://v1.ax1x.com/2026/05/11/NbRlDc.png)

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

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

// iv = b"1234567890123456"  // Python
```

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

![NbRhDZ.png](https://v1.ax1x.com/2026/05/12/NbRhDZ.png)

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

### AI 识别

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

![NbRWT7.png](https://v1.ax1x.com/2026/05/12/NbRWT7.png)

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

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

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

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

> 图片接口为 https://captcha-pc.vip.com/getImage,根据标题图片中的内容,判断需要点击的背景图片中的文字或图标的坐标,参考本地 image_title.png(标题),image_bg.png(背景图片)

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

![NbYLma.png](https://v1.ax1x.com/2026/05/12/NbYLma.png)

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

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

![NbJR2I.png](https://v1.ax1x.com/2026/05/13/NbJR2I.png)

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

## 结果验证

![NbJrQV.png](https://v1.ax1x.com/2026/05/13/NbJrQV.png)