news 2026/10/20 21:20:30

AI自动解CTF:从流水线搭建到实战翻车实录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI自动解CTF:从流水线搭建到实战翻车实录

这两天我在练习平台上刷CTF,脑子里突然冒出一个有点中二的想法:如果我全程不用手,把这些题丢给AI去解,能做到什么程度?当天我花了一个小时把常用的几个开源模型串成一条流水线,又在本地靶场上挑了二十多道题跑了一遍。结果很有意思——有一半的题确实被AI“自动”搞定了,但也有一堆让我哭笑不得的翻车现场。这篇文章就是那几天的完整记录,包括流水线怎么搭、哪些题适合丢给AI、哪些坑我替你踩过了。

如果你也在玩CTF,或者对大模型做自动化分析感兴趣,这篇东西应该能给你省不少时间。我先把最核心的结论放这儿:纯无人值守、全自动拿高分的AI目前不存在。但把AI当成“一个聪明但经常胡说八道的新人选手”,让它先做一遍,你做审核和善后,效率会提升得非常明显。

1. 动手前先把逻辑理清:AI在CTF里到底能干什么

1.1 五类题型的能力匹配表

CTF常见的题型大概分五类:Web、Crypto、Reverse、Pwn和Misc。不同题型考察的点和AI的“体质”匹配度差别很大,我刚开始是见题就丢给AI,结果浪费了不少时间和API额度。跑了几轮之后,我给自己做了一个能力匹配表,现在翻出来给你们看看:

题型AI擅长的地方AI明显不擅长的地方自动化解题优先级
Misc编码识别、隐写工具链调用、字符串分析、流量包常见套路需要人眼反复观察的视觉细节、复杂的空间想象最高
Crypto已知算法模式识别、数学推导、脚本生成需要深度构造复杂攻击链的非常规题目高
Web读源码找漏洞点、生成payload、接口探测对业务逻辑的整体理解、需要多步交互的复杂漏洞中
Reverse阅读反编译代码、还原算法逻辑、生成等价脚本高强度混淆、VM保护类中低
Pwn生成利用脚本的初稿、解释保护机制堆利用等需要精确内存布局的复杂利用低

我实际跑下来的感觉是:Misc和基础Crypto题,AI的解法成功率远超我的预期。因为这些题本质上就是“信息提取加模式匹配”,模型见过的样本实在太多了,一眼就能认出这是base64嵌套还是RSA低加密指数。而Pwn这种需要对着寄存器状态反复调试的题,AI基本属于“理论王者、实战青铜”。

所以如果你也想搭一套自动解题工具,我建议先从Misc和Crypto题入手,不要一上来就挑战那些又难又偏的题,否则挫败感会非常强。

1.2 四段式流水线的设计思路

我一开始想的是“端到端黑盒”——把题目直接丢给AI,让它输出flag。试了几次就发现这条路走不通:题目附件经常是二进制文件,直接把整个文件塞给模型,要么超出上下文窗口,要么返回一堆乱码似的分析。

后来我把思路改成了一条四段式流水线:

  1. 题目获取器:从练习平台的接口自动拉取题目描述、附件下载地址、分值等信息。
  2. 分析器:把预处理后的题目信息打包给大模型,要求它输出“解题思路+可执行的Python脚本”。
  3. 执行器:在本地沙箱环境里运行AI生成的脚本,捕获标准输出、错误信息和退出码。
  4. 校验器:从脚本输出中用正则匹配flag格式,匹配到就自动提交答案,匹配不到就记录日志。

这个架构的核心思想是:AI负责“想”,代码负责“做”。AI的认知能力用来做题目分类、思路生成、代码初稿这些高层次的活;而真正的脚本执行、结果校验、答题提交,全部交给确定性代码来处理。这样即使AI说了一堆胡话,只要代码框架够稳,系统也不会崩,最多是该题失败,继续跑下一道。

这里有个容易被忽略的细节:**AI的输出永远不要直接用来做安全判断,必须经过执行器验证和校验器提取之后再入库。**因为模型的输出再流畅,也只是概率性的文字序列,而flag校验是确定性的,两者必须分离。

2. 全自动解题环境搭建:从拉取题目到执行脚本

2.1 自动化拉题与附件预处理

我的实验环境是本地搭建的CTF练习平台,这类平台一般都会提供题目列表的接口,方便做题者拉取题目数据。自动化拉题的过程本质上就是“模拟浏览器登录,再调接口拿数据”。我用Python的requests库写了获取器,核心逻辑很简单:

import requests from pathlib import Path s = requests.Session() s.post("http://localhost:8000/api/login", json={ "username": "test_user", "password": "test_pass" }) resp = s.get("http://localhost:8000/api/tasks").json() for task in resp["data"]: name = task["name"] attachment_url = task.get("attachment_url") if attachment_url: r = s.get(attachment_url) Path(f"attachments/{name}").write_bytes(r.content)

真正花时间的是附件预处理。刚开始我把下载下来的文件直接丢给AI,结果模型分不清这是个压缩包还是图片,分析质量非常差。后来我总结了一套固定流程:先用file命令识别文件类型,再用strings提取可读字符串片段,最后把文件大小、哈希值、类型描述、字符串前若干条一起打包给AI。

file flag.png # 输出:flag.png: PNG image data, 600 x 400, 8-bit/color RGBA, non-interlaced strings flag.png | head -50

这套后处理的价值在于:AI本质上是一个文本模型,它需要一个适合文本输入的“题目摘要”。题目的原始二进制是没法直接理解的,但“PNG、600x400、RGBA通道、有异常字符串”这些描述,AI却能展开丰富的联想,告诉你“建议检查LSB通道”。这比把图片原始字节丢给它要有效得多。

2.2 提示词模板与上下文管理

提示词是整个流水线的灵魂。我试过好几个版本的模板,最后稳定在这一套结构上:

你是一名CTF解题助手。现在给你一道题目的摘要信息,请完成两个任务: 1. 分析可能的解题方向,用3-5句话说明思路。 2. 生成一段Python解题脚本,脚本必须满足: - 使用requests/struct/re等常见库 - 自行判断输入文件路径,通过sys.argv[1]接收 - 输出结果中如果包含flag,请原样打印,不要添加额外说明 题目名称:{name} 题目描述:{description} 附件信息:{file_info}

这个模板有两点很有讲究。第一,要求AI通过sys.argv接收文件路径,而不是让它硬编码文件名——这样执行器才能用统一的入口去调用不同题目的脚本。第二,明确要求“不要添加额外说明”——模型太喜欢在答案里附上“我认为这是一个RSA问题”之类的废话,这对后端的flag提取干扰极大。

上下文管理上我也踩了坑。刚开始我设置成多轮对话,AI每轮的答案都会带上前一轮的内容,结果第二三轮之后,模型经常把前面几道题的结论混到一起,输出一些莫名其妙的东西。后来我改为每一道题完全独立的单轮对话,只在系统提示词里固定角色设定,题目信息只出现在用户消息里。这样不仅答案更干净,还省了不少token开销。

2.3 让AI输出“可执行”的结构化结果

AI返回的内容如果是一大段自然语言,脚本很难直接提取代码。我试过用正则去匹配代码块——效果还行,但不够稳,因为模型偶尔会忘记用markdown代码块,或者在里面混入测试说明。

后来我换成了结构化输出:要求模型返回JSON,固定两个字段:analysis(思路分析)和code(Python脚本)。再用代码解析JSON,解析失败时退回到正则提取python代码块。

import json, re def parse_llm_response(text): try: data = json.loads(text) return data["analysis"], data["code"] except Exception: code_match = re.search(r"```python\n(.*?)```", text, re.S) if code_match: return text[:200], code_match.group(1) return text, ""

这个兜底逻辑非常重要。实测下来,JSON模式能覆盖大约七成的情况,剩下三成靠正则兜底,基本能保证执行器永远拿到一份可尝试运行的代码。让AI按固定格式输出,不是限制它的发挥,而是让后续的自动化流程有确定性的入口。

3. 实测记录:三类题目的AI解题全流程

3.1 Web题:源码分析加自动构造payload

有一道登录绕过题,题目附了后端处理登录的核心代码片段,明显是SQL注入。我把代码片段完整贴给AI,让它找漏洞点并生成利用脚本。AI的分析结论很标准:登录查询用了字符串拼接,单引号未过滤,可以直接万能密码绕过。

AI生成的脚本大概是这样:

import requests, sys url = sys.argv[1] r = requests.post(url, data={ "username": "' or '1'='1' --", "password": "x" }) print(r.text)

执行器把目标URL传进去,脚本确实返回了管理员的页面内容,校验器从响应里成功匹配到了flag。整个过程从拉题到提交不到两分钟,比我手写payload再测试快太多。

但我也碰到过AI分析对但代码跑不通的情况。有一次题目考察的是二次注入,AI思路说得头头是道,生成的代码却少了一个URL编码步骤,导致payload里的空格被HTTP请求格式吃掉。这就是为什么执行器必须把报错信息回传给AI再迭代一版,而不是简单判死。

3.2 Crypto题:模式识别加数学脚本生成

Crypto题是AI提升自信心最明显的一类。有一道RSA题,给了n、e、c三个大整数,e很小,经典的低加密指数攻击。AI看到参数后第一反应就是“e=3,直接对c开三次方”,然后生成了用gmpy2库开方的脚本:

import gmpy2, sys n = int(sys.argv[1]) e = int(sys.argv[2]) c = int(sys.argv[3]) m = gmpy2.iroot(c, e)[0] flag = bytes.fromhex(hex(m)[2:]).decode() print(flag)

我原本以为这种题至少要人工推导几步,结果AI直接给出了标准解法。这类题对AI来说本质上就是“题库检索”,模型在训练阶段见过太多相同套路的RSA题,只要把参数格式整理好,它几乎不会错。

Crypto题真正麻烦的是参数解析。题目给的数据可能放在文本文件里,也可能嵌在题目描述中,格式五花八门。我写了一个小函数,把题目附件中的大整数按“key = value”的形式提取出来,再按顺序传给脚本。这套处理对AI的发挥帮助极大,因为模型的优势完全建立在“参数清晰、问题明确”的前提上。

3.3 Misc题:图片隐写的探测与提取

Misc题里AI发挥最稳的是编码类题。有一次附件是个文本文件,里面是几层嵌套的base64,AI直接给出脚本循环解码,直到文本里出现flag头。这种题对模型而言没有任何门槛,只是单纯地“照章办事”。

图片隐写题就麻烦一点。题目给了一张PNG图片,AI没法直接看像素,所以我的获取器先把图片的关键信息提取出来:宽高、通道数、是否有额外数据块、strings的结果。这些信息打包给AI后,它推测可能是LSB隐写,并生成了提取脚本:

from PIL import Image import sys, re img = Image.open(sys.argv[1]) pixels = img.load() width, height = img.size bits = "" for y in range(height): for x in range(width): r, g, b = pixels[x, y][:3] bits += str(b & 1) data = int(bits, 2).to_bytes(len(bits) // 8, byteorder="big") flag = re.findall(rb"flag\{[^}]+\}", data) print(flag[0].decode() if flag else "no flag")

这个脚本实际跑下来确实提取到了flag,虽然中间做了一个“按位拼接后转为字节”的假设,但AI恰好猜对了编码顺序。我的体会是:对Misc这类题,AI的“联想能力”比精确推理更有价值。它不需要完全理解隐写原理,只要能从常见的工具名和现象联想到“该试LSB了”,就已经帮了大忙。

4. 翻车实录:AI解题的常见坑和排查技巧

4.1 幻觉代码怎么治:报错反馈闭环

AI生成的代码最大的问题不是思路错,而是调用了根本不存在的函数或库。有一道Reverse题,AI生成的脚本用了ida_bytes.get_bytes,这个接口在常见的Python环境里根本不存在。执行器一跑就报ImportError,系统直接记录失败。

后来我加了一个“报错反馈”机制:执行器捕获Python异常后,把异常信息追加到原来的提示词后面,再让AI重新生成一版代码,最多迭代三次。这一招效果立竿见影,不少题目从“一次性失败”变成了“第二次就通过”。

for attempt in range(3): code = get_code_from_llm(task_info, last_error) result = run_in_sandbox(code, task_attachment) if result["success"]: break last_error = result["stderr"][-500:]

这种“执行—报错—再生成”的闭环,本质上就是把AI当成一个可以对话的开发者,用编译器和解释器的报错作为它的“实时反馈”。你不能指望AI一次写对,但你可以指望它在看到错误信息后改对。

4.2 编码地狱:被吞掉的flag和可读性处理

这个问题浪费了我最多的时间。AI生成的脚本里如果有print(binary_data),Python会把字节串打印成b'flag{xxx}',校验器的正则如果没处理b''前缀就永远匹配不到。类似的问题还有:模型在flag前后加了多余的换行、用Unicode引号代替ASCII引号、Windows换行符导致正则边界失效。

我的解决方案是全校验器统一用这一个正则:

import re flags = re.findall(r"flag\{[^}]+\}", output, flags=re.IGNORECASE)

并且在保存输出前先做一次bytes.decode(errors="ignore")的容错处理。这样不管脚本输出的是字节串还是文本,最终都能被正则抓到。规则越简单越好,不要试图在提取阶段处理所有编码细节。

4.3 超时、并发与队列管理

自动解题过程中,总有一些AI生成的脚本陷入死循环,比如扫描端口时用了无超时的socket连接,或者正则回溯复杂度过高。如果执行器没有超时机制,整个队列会被一道题卡死。

我的做法是每个脚本最多跑60秒,超时直接kill,然后用subprocess.run(timeout=60)捕获超时异常,记录日志后继续下一题。并发控制方面,因为用的是开源模型接口,并发太大会直接触发限流,所以我把并发数限制在2个任务同时执行,每道题之间再间隔1秒。这个节奏跑下来最稳定,既不浪费算力,也不容易触发服务端的访问限制。

还有一个不起眼但很重要的细节:执行日志一定要落盘。我把每道题的提示词、AI原始回复、生成的代码、运行输出、最终结果全部存成JSON行文件。这样即使某道题失败了,回头复盘时也知道是分析错了、代码错了还是输出解析错了,而不是对着终端里滚过的日志干瞪眼。

5. 最后说点大实话

我在实验里一共跑了二十多道题,最终统计出来AI独立完整解出的大概四成,加上我人工介入辅助后差不多能到七成。这个成绩不算惊艳,但已经足够让我把“AI能不能打CTF”这个问题从“不能”改口成“看题型”。

我个人最大的体会是:AI在CTF里的定位不是解题者,而是“超快的信息检索员+代码初稿生成器”。那些纯机械的环节——读题、查编码、写脚本骨架、调库函数——AI做得又快又好,把原本属于人的精力释放了出来。于是人从“什么都自己干”变成了“审核AI的分析、修正它的方向、处理它搞不定的边界情况”。这个过程里,人并没有被AI替代,而是被AI推向了更高层的判断位。

最后再分享一个小技巧:这条流水线稍加改动,就能用来当CTF训练的“陪练”。在执行器前面加一句提示词“请不要直接给完整答案,先给提示”,AI就从一个答题者变成了助教。我用这种方式带过几个刚入门的朋友,他们普遍反馈比对着题解硬啃要友好得多。工具是死的,思路是活的。这个方向后续我还会继续折腾,等跑出更多有意思的结果,再来跟大家同步。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 21:14:56

重读《TCP/IP详解》第2版:用问题导向笔记吃透TCP重传与拥塞控制

今年年初,我给自己排了一个很朴素的任务:把《TCP/IP详解(第2版)》卷一重新读一遍,并且整理一份能当检索面板用的目录式笔记。起因很实在——一次线上接口偶发变慢,抓包看到满屏重复ACK和重传包,…

作者头像 李华
网站建设 2026/10/20 21:10:04

Pulsar与开源集市:消息中间件在COSCon的碰撞与参与指南

又到周末了。这周朋友圈里很多开源圈的朋友都在转同一个消息:Pulsar 与 COSCon‘25 开源集市碰头。有人问我:“Pulsar 不是搞消息系统的吗,它去开源集市摆摊干什么?”这个疑问其实问到了点子上。这篇文章想一次性把三件事讲清楚&a…

作者头像 李华
网站建设 2026/10/20 21:09:36

深入解析向量:从动态数组原理到手写实现与性能优化

1. 向量到底是什么:从“能自动扩容的数组”说起很多人第一次接触“向量”这个词,是在线性代数课上,脑子里浮现的是一支带箭头的线段。但在数据结构与算法的语境里,向量是另一回事——它本质上就是一个能自动扩容的动态数组。你不需…

作者头像 李华
网站建设 2026/10/20 21:09:32

PHY62XX开发环境搭建:从工具链配置到可复现烧录

简介:本资源是奉加微PHY62XX系列芯片(含PHY6212/6222/6252及手环、红外遥控等衍生方案)的全栈开发资料汇总包,面向嵌入式IoT开发者、硬件工程师及量产项目研发人员,一站式解决BLE SoC选型评估、固件开发、OTA升级、PCB…

作者头像 李华
网站建设 2026/10/20 21:09:23

子比主题ACG美化插件开发指南:样式加载、CSS注入与避坑

简介:面向WordPress子比(Zibll)主题站长的ACG二次元风格美化插件,以开源免授权方式提供,适合二次元社区或动漫资源站快速搭建独特视觉风格。插件集成100余项美化功能,通过后台开关即可开启,兼容…

作者头像 李华
网站建设 2026/10/20 21:05:56

社交网络分析:社区发现与影响力传播模型实战指南

干这行的朋友应该都有同感:你拿到的数据往往是一堆用户关系表,而业务问的问题通常是"这个网络里有多少个圈子""谁是核心节点""如果投放一笔资源进去,能扩散成什么样"。这三个问题,对应的正是社交网…

作者头像 李华