基于SecGPT-14B的CTF Web题目自动化生成与优化实践

发布时间:2026/7/27 13:23:31
基于SecGPT-14B的CTF Web题目自动化生成与优化实践 1. 项目概述当大模型遇上CTF出题最近在帮学校CTF战队做赛前集训最头疼的就是题目来源。网上公开的题目大家都刷烂了自己从头构思一套高质量的Web题从漏洞设计、环境搭建到Writeup编写没个两三天根本下不来更别说要出十套了。就在我琢磨着是不是要连续爆肝几个通宵时团队里一个学弟提到了SecGPT-14B一个专门针对安全领域微调过的大语言模型。抱着试试看的心态我用它来辅助生成CTF题目结果大大超出了预期——不仅效率飙升而且产出的题目质量相当不错甚至激发了一些我们自己都没想到的创意点。简单来说这个项目就是利用SecGPT-14B作为“核心创意引擎”和“初级开发助手”快速生成10套原创的CTF Web题目并配套完整的解题报告Writeup。整个过程我更像是一个“导演”和“质检员”负责提出需求、引导方向、审核代码以及最终的环境部署和测试。SecGPT-14B则承担了漏洞场景构思、基础代码生成、部分Writeup草拟等繁重工作。最终我们得到了一套全新的、可用于内部训练和比赛的题目库整个过程比纯手工出题节省了超过70%的时间。这不仅仅是“用AI出题”那么简单。它涉及到如何将模糊的出题需求转化为模型能理解的提示词Prompt如何评估和修正AI生成的代码安全性避免出现非预期解或自身漏洞以及如何将AI的“创意”与真实的CTF考点、难度梯度相结合。接下来我就把这十套题目的诞生过程、其中的关键技术细节以及我踩过的坑和总结的经验毫无保留地分享给大家。2. 核心思路与SecGPT-14B的“角色”定位在开始具体操作之前必须想清楚我们到底要让AI做什么以及它的能力边界在哪里。盲目地让模型“生成一道CTF题”只会得到笼统、甚至无法运行的结果。2.1 出题流程的解构与AI赋能点传统的CTF出题流程大致分为构思考点 - 设计场景 - 编写代码前端/后端 - 搭建环境 - 测试漏洞 - 撰写Writeup。SecGPT-14B可以在前三个环节尤其是“构思”和“编写”环节发挥巨大作用。构思考点与设计场景AI作为“灵感库”和“场景编剧”这是最核心也是最难的部分。我需要告诉模型“请设计一个涉及Java反序列化漏洞的Web题目场景是一个在线笔记分享系统漏洞触发点需要绕过一些常规的WAF规则。” 模型基于其庞大的安全知识库能够快速组合出多个符合要求的场景雏形比如“一个使用Apache Commons Collections 3.1的笔记系统在导出笔记功能中存在反序列化点但过滤了InvokerTransformer等关键词需要寻找替代链”。编写代码AI作为“初级开发工程师”这是AI最擅长的部分。一旦场景确定我可以要求模型“生成一个基于Spring Boot的Java Web应用包含用户登录、创建笔记、导出笔记为序列化对象的功能。在导出功能/export接口中接收POST参数data直接进行ObjectInputStream反序列化但需要添加一个简单的关键词过滤。” 模型能快速生成结构清晰、可直接运行或稍作修改即可运行的代码骨架包括pom.xml依赖、控制器、服务层等。撰写WriteupAI作为“解题思路记录员”对于标准化的漏洞AI可以基于生成的题目代码反向推导出解题步骤。我可以指令“根据上面生成的代码撰写一份详细的Writeup包括漏洞原理、利用工具如ysoserial、构造Payload的步骤以及最终获取Flag的命令。” 模型能生成逻辑通顺的Writeup草稿极大减轻了文档工作负担。注意AI无法替代的环节包括最终的环境搭建与部署Dockerfile编写、服务配置、深度的漏洞利用链测试确保Payload在真实环境中有效、非预期解的排查以及最终的题目难度与趣味性把控。这些都需要出题人深厚的实战经验。2.2 SecGPT-14B的提示词工程实战如何与SecGPT-14B有效沟通是项目成败的关键。我的经验是“角色扮演”“结构化需求”“迭代优化”。第一轮明确角色和任务你是一名经验丰富的CTF出题人。现在需要你设计一道中等难度的CTF Web题目。 核心考点服务端模板注入SSTI限制在Jinja2模板引擎。 应用场景一个简单的在线公司信息查询系统。 基本功能用户输入公司名称系统查询后渲染展示。 漏洞点在查询结果渲染时未对用户输入进行过滤直接拼接进模板。 请输出1. 题目的简要描述用于赛题介绍。2. 使用Python Flask框架的核心漏洞代码片段。3. 隐藏Flag的方式例如在根目录下的flag.txt文件中。第二轮补充细节和约束基于上一轮的构思请完善以下内容 1. 给出完整的Flask应用代码app.py包含一个首页和一个查询接口。 2. 在查询接口中模拟一个数据库查询过程可以使用字典模拟将查询到的“公司信息”与用户输入的公司名一起传递给模板。 3. 为了增加难度请过滤掉常见的SSTI测试Payload中的单双引号、os、subprocess等关键词但留下可用的绕过方法。 4. 给出一个预期的利用链说明如何通过过滤最终执行命令读取flag。第三轮生成Writeup根据你上面生成的题目代码撰写一份完整的解题WriteupWriteup。要求包括 1. 题目考点分析。 2. 漏洞点定位过程例如通过参数测试发现SSTI。 3. 绕过过滤的技巧例如使用request.args、attr过滤器、字符串拼接等。 4. 构造读取flag的Payload并获取Flag的完整步骤。通过这样多轮、逐步细化的对话SecGPT-14B能够输出质量非常高的初始素材。我生成的10道题有超过一半的初版代码和Writeup草稿都源于这种交互模式。3. 十套原创Web题目详解与SecGPT实战下面我挑选其中三道最具代表性的题目拆解SecGPT-14B是如何辅助完成的并附上我作为出题人的修改和优化思路。3.1 案例一有“洁癖”的文件上传系统题目名称Upload It, But Clean It核心考点条件竞争漏洞、文件名逻辑缺陷AI辅助生成过程 我向SecGPT-14B提出的需求是“设计一道关于文件上传的题目不要是简单的黑名单绕过。希望结合条件竞争比如上传一个webshell但服务端会有后台线程删除非图片文件。”模型给出的初始设计非常有趣一个允许上传头像的页面后端使用multiprocessing启动一个清洁线程每隔很短时间如0.5秒扫描上传目录删除扩展名不在白名单.jpg,.png内的文件。漏洞在于删除文件前会先检查文件魔数Magic Number如果文件内容以图片头开始则暂时放过。这就为条件竞争创造了空间上传一个内容为GIF89a?php system($_GET[‘c’]);?的文件在清洁线程检查魔数通过后、但尚未进行后续清理的极短时间内访问这个文件即可执行代码。我的优化与踩坑代码安全加固AI生成的初始代码中上传路径是相对路径./uploads。我将其改为绝对路径并确保目录权限正确避免路径遍历等非预期漏洞。竞争窗口调整AI设定的0.5秒扫描间隔对于本地网络环境竞争太容易。我将其改为随机间隔0.1秒到0.3秒并增加了清洁线程执行前的短暂随机睡眠模拟真实环境的不确定性提高题目难度。Flag放置AI建议将flag放在Web根目录。我改为放在系统临时目录/tmp/flag_{random}下并要求选手通过执行命令来读取这样更符合CTF的常规操作。Writeup补充AI生成的Writeup缺少对条件竞争原理的深入解释和利用脚本示例。我补充了Python多线程攻击脚本的完整代码并解释了为什么使用Content-Length: 0的请求进行轰炸有时更有效。最终题目核心代码片段Flask:import os, threading, time, random from werkzeug.utils import secure_filename UPLOAD_FOLDER /app/uploads ALLOWED_EXTENSIONS {png, jpg, jpeg} def cleaner_thread(): while True: time.sleep(random.uniform(0.1, 0.3)) # 随机间隔增加难度 for filename in os.listdir(UPLOAD_FOLDER): filepath os.path.join(UPLOAD_FOLDER, filename) try: with open(filepath, rb) as f: header f.read(6) # 只检查文件头不检查完整扩展名 if not header.startswith((bGIF89a, b\xff\xd8\xff, b\x89PNG\r\n)): os.remove(filepath) print(fCleaned: {filename}) except: pass # 启动清洁线程 threading.Thread(targetcleaner_thread, daemonTrue).start() app.route(/upload, methods[POST]) def upload_file(): if file not in request.files: return No file part file request.files[file] if file.filename : return No selected file if file and . in file.filename: filename secure_filename(file.filename) filepath os.path.join(UPLOAD_FOLDER, filename) file.save(filepath) return fFile uploaded: {filename}. It might be cleaned soon! return Invalid file3.2 案例二基于JWT的“时间旅行”投票系统题目名称Time Travel Vote核心考点JWT密钥混淆攻击、算法替换AI辅助生成过程 我要求SecGPT-14B设计一道关于JWT的题目考点不能是简单的密钥爆破。模型提出了一个“时间旅行投票”的概念系统使用JWT记录用户的投票时间和次数每个用户每小时只能投一票。JWT使用RS256算法非对称加密签名。题目会提供一个伪造的“管理员”功能接口该接口错误地使用了HS256算法对称加密来验证JWT并且使用的密钥是公开的RSA公钥。我的优化与踩坑漏洞场景真实性AI最初的设想是直接提供一个/admin接口。我将其修改为更隐蔽的场景在“查看投票历史”的API响应头中泄露了一个用于“内部调试”的接口/api/debug/verify_token这个接口使用了错误的验证逻辑。这样更符合“漏洞发现”的过程。密钥处理AI生成的代码中公钥以字符串形式硬编码。我改为从文件读取并确保公钥文件可通过Web目录访问如/static/public.pem这是常见的配置失误场景。工具链明确在Writeup中我详细补充了如何使用python-jose库或在线工具将RSA公钥作为HMAC密钥将算法从RS256改为HS256重新签名JWT的过程。并强调了需要修改的字段如role: user-role: admin。非预期解防范检查AI生成的代码确保除了算法混淆外没有其他途径如SQL注入、目录遍历可以获取flag或提升权限。最终漏洞接口代码片段# 错误的调试接口 - 使用HS256验证但密钥是公钥 app.route(/api/debug/verify_token, methods[POST]) def debug_verify(): token request.json.get(token) with open(/app/static/public.pem, r) as f: PUBLIC_KEY f.read() try: # 错误地使用HS256算法和公钥进行验证 payload jwt.decode(token, PUBLIC_KEY, algorithms[HS256]) return jsonify({valid: True, payload: payload}) except Exception as e: return jsonify({valid: False, error: str(e)}) # 正确的投票接口 - 使用RS256验证 app.route(/api/vote, methods[POST]) def vote(): token request.headers.get(Authorization).split( )[1] with open(/app/private.pem, r) as f: PRIVATE_KEY f.read() try: payload jwt.decode(token, PRIVATE_KEY, algorithms[RS256]) # 检查投票时间间隔逻辑... return jsonify({success: True}) except: return jsonify({error: Invalid token}), 4013.3 案例三盲注的“智能”搜索引擎题目名称SearchBlinder核心考点基于时间盲注的SQL注入、WAF绕过AI辅助生成过程 这道题我希望考察高阶的SQL注入。我给SecGPT-14B的指令是“设计一个搜索功能存在SQL注入但没有任何错误回显且过滤了空格、union、select等关键词。只能通过时间盲注来利用。”模型给出的设计很巧妙一个图书搜索系统后端使用Python的SQLite数据库。过滤函数将用户输入中的空格替换为空并黑名单过滤了union、select、or、and等关键词不区分大小写。漏洞点在于过滤发生在字符串替换之后但未递归过滤。例如过滤union后如果Payload是ununionion中间的union被移除剩下的字符又会组合成新的union。同时利用SQLite的LIKE子句或CASE WHEN结合sleep函数或randomblob消耗时间来实现时间盲注。我的优化与踩坑过滤逻辑强化与绕过AI最初的过滤规则比较简单。我增加了多层过滤和正则表达式但故意留下了可绕过的缺陷例如使用/**/、%0a换行符替代空格以及上述的“词语重组”绕过。时间函数选择SQLite没有sleep()函数。AI起初使用了randomblob(N)来消耗时间。我经过测试发现randomblob(10000000)在特定环境下时间差异不够明显。最终采用了更稳定的方法让查询执行一个复杂的子查询或CASE WHEN语句其中包含大量计算或字符串拼接通过计算长度的差异来制造时间延迟。编写交互式利用脚本这是Writeup的核心。我基于AI提供的利用思路手写了一个Python自动化脚本演示如何逐位爆破数据库名、表名、字段名和flag。脚本中详细处理了网络延迟、超时重试等问题这比AI生成的伪代码更有教学价值。部署注意事项SQLite的并发读写能力弱。在Docker部署时我需要确保每个请求使用独立的数据库连接避免因时间盲注的长时查询导致服务阻塞。关键过滤与注入点代码import sqlite3, re, time def waf_filter(input_str): # 过滤关键词 blacklist [union, select, or, and, from, where, sleep, benchmark] for word in blacklist: pattern re.compile(word, re.IGNORECASE) input_str pattern.sub(, input_str) # 递归过滤但只进行一次留下绕过可能 # 例如ununionion - 第一次过滤后变成union return input_str app.route(/search) def search(): query request.args.get(q, ) filtered_query waf_filter(query) # 漏洞未对%0a等换行符进行过滤且过滤非递归 conn sqlite3.connect(books.db) cursor conn.cursor() # 存在注入的查询 sql fSELECT * FROM books WHERE title LIKE %{filtered_query}% try: start time.time() cursor.execute(sql) results cursor.fetchall() elapsed time.time() - start # 如果查询时间超过2秒可能触发了时间盲注但页面仍返回正常结果或无结果 return render_template(results.html, booksresults, queryquery) except Exception as e: return Search error., 5004. 从AI输出到可部署题目的关键处理步骤SecGPT-14B生成的代码是“草稿”直接部署多半会出问题。以下是必须进行的处理步骤我称之为“出题人质检四步法”。4.1 代码安全性与功能完整性审查AI生成的代码可能存在功能缺失或安全漏洞对出题本身而言是坏事。检查依赖与环境AI生成的requirements.txt或pom.xml可能版本过旧或存在冲突。需要根据部署环境如Python 3.9, OpenJDK 11手动调整依赖版本。补全缺失功能AI可能只生成核心漏洞代码缺少用户注册、登录、前端页面等辅助功能。需要手动补全确保题目是一个可交互的完整应用。消除非预期解目录遍历检查所有文件读取操作是否限制了路径。源码泄露确保.git、.DS_Store、备份文件如app.py.bak不被访问。默认凭据修改所有默认数据库密码、后台密码。信息泄露检查错误信息是否过于详细如完整的SQL异常、堆栈跟踪。添加题目标识与Flag在合适的位置如数据库、文件系统、环境变量插入Flag并确保漏洞利用链最终能稳定读取到它。4.2 Docker化部署与环境隔离为了确保题目环境一致且易于分发Docker化是必须的。编写Dockerfile基于轻量级镜像如python:3.9-slim、openjdk:11-jre-slim构建。步骤包括安装依赖、复制代码、设置工作目录、暴露端口、启动命令。使用Docker Compose如果题目涉及多个服务如Web前端数据库使用docker-compose.yml进行编排定义网络和依赖关系。环境变量配置将数据库连接字符串、密钥、Flag等敏感信息通过环境变量传入容器而不是硬编码在代码中。这既安全又便于在赛时动态更换Flag。健康检查在Dockerfile或Compose文件中添加健康检查指令确保服务完全启动后再对外访问。示例DockerfilePython Flask应用FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . ENV FLAGflag{this_is_a_sample_flag} ENV SECRET_KEYchange_this_in_production EXPOSE 5000 CMD [gunicorn, --bind, 0.0.0.0:5000, app:app]4.3 Writeup的精细化打磨AI生成的Writeup是很好的起点但需要注入灵魂。补充漏洞原理深度AI可能只陈述“是什么”需要补充“为什么”。例如在JWT题目中详细解释RS256和HS256算法的区别以及为什么公钥作为HMAC密钥会导致漏洞。细化操作步骤将“使用工具爆破”细化为“使用sqlmap时具体的--tamper脚本选择、--level和--risk参数设置以及如何观察响应时间差异”。提供完整的利用脚本对于时间盲注、条件竞争等题目提供一个可直接运行或稍作修改即可运行的Python/PHP攻击脚本并附上详细注释。总结考点与拓展在Writeup最后总结本题考察的知识点并给出类似漏洞在真实世界中的案例如某些历史CVE以及进一步的学习资源如OWASP相关指南。4.4 难度平衡与趣味性调整这是纯经验领域AI无法替代。设置合理的Hint如果题目太难可以在页面源代码、网络请求响应头、或者一个不起眼的/robots.txt文件中给出适当提示。控制解题的“爽点”确保漏洞利用过程有清晰的步骤和正反馈。例如在文件上传题目中选手通过竞争成功访问到webshell时应能立即执行命令而不是又遇到新的障碍。故事化场景给题目起一个有趣的名字编写一段吸引人的背景故事能极大提升选手的参与感。SecGPT-14B在生成故事性描述上很有天赋可以加以引导利用。5. 实战中遇到的问题与解决方案在整个项目过程中我遇到了不少典型问题这里记录下来供大家参考。5.1 AI的“幻觉”与知识截止问题SecGPT-14B虽然强大但仍有局限性。问题在生成一道关于“Node.js原型链污染”的题目时模型给出的利用代码使用了lodash库的_.defaultsDeep函数这确实是经典案例。但它给出的修复建议是“升级到最新版lodash”而最新版可能仍有其他污染向量。同时它可能不知道近几年新出现的特定框架如Fastify、NestJS的污染点。解决方案永远要人工验证。对于AI提供的漏洞点和修复方案我必须亲自查阅官方文档、安全公告和最新的CVE列表。对于不熟悉的领域需要交叉比对多个来源。我的原则是AI提供“创意”和“草稿”我负责“验证”和“定稿”。5.2 生成代码的“玩具化”与生产环境差距AI生成的代码多为单文件示例离可部署的生产级应用有距离。问题生成的Flask应用可能把路由、业务逻辑、配置全写在一个app.py里没有错误处理没有日志数据库连接也是硬编码。解决方案进行代码重构。将应用拆分成符合MVC或类似结构的模块。添加完整的异常处理但注意在CTF题目中错误信息不能太详细。配置通过文件或环境变量读取。这步工作虽然繁琐但能让你对题目有百分百的掌控力也是提升自身工程能力的好机会。5.3 漏洞利用链的稳定性和可复现性这是出题的核心AI无法保证。问题AI设计的时间盲注Payload在模型自己的“想象”中可能成功但在真实数据库如MySQL vs SQLite和网络环境下时间延迟可能不稳定导致利用脚本失败。解决方案严格测试。必须搭建与比赛完全一致的环境相同的Docker镜像、系统版本、依赖库版本对每道题的漏洞利用链进行至少20次以上的成功复现测试。记录下平均响应时间为编写稳定的攻击脚本提供依据。对于条件竞争这类“看运气”的题目要确保在合理的并发请求下成功率在80%以上。5.4 防止非预期解与“一题多解”的权衡问题一道题目的漏洞利用路径应该是设计好的那一条。但AI生成的复杂代码可能会无意中引入其他漏洞如二次注入、XSS等或者存在多种方法到达同一个终点。解决方案同行评审。在题目最终定稿前邀请战队里其他有经验的成员进行“黑盒”和“白盒”测试。让他们在不看源码的情况下尝试解题同时自己也反复进行代码审计。对于发现的非预期解要么将其修复如果它过于简单或破坏了原考点要么考虑将其作为一个“彩蛋”或“额外加分点”但这需要清晰的规则说明。6. 经验总结与未来展望通过这个项目我深刻体会到像SecGPT-14B这样的垂直领域大模型已经成为安全从业者特别是CTF出题人的“力量倍增器”。它并非取代我们而是将我们从重复性的脑力劳动如搭建基础代码框架、撰写格式化文档中解放出来让我们能更专注于漏洞设计的精巧性、场景的真实性和比赛的整体体验设计。我个人最大的体会是提示词的质量直接决定了产出的质量。你需要像一个资深的安全专家一样去思考和拆解问题然后把清晰的、结构化的任务描述交给AI。你给它的输入越专业、越具体它反馈给你的结果就越可靠、越有创意。未来我计划将这套方法进一步系统化。例如建立一个“CTF出题提示词库”针对不同类型的漏洞SSTI、反序列化、XXE等总结出最优的提示词模板。同时探索将AI辅助出题与自动化部署、动态Flag生成平台相结合实现从“创意”到“可赛题”的一键式流水线。这或许能让我们这样的高校战队甚至小型比赛主办方都能轻松拥有高质量、持续更新的题目库。最后给想尝试的同学一个忠告AI出题的第一原则是“信任但验证”。把它当作一个不知疲倦、知识渊博的初级助手而你自己必须永远是那个把握方向、负责最终质量的架构师。当你抱着这个心态去使用它时你会发现创造那些让选手们抓耳挠腮又拍案叫绝的CTF题目竟然可以如此高效且充满乐趣。

相关新闻

最新新闻

日新闻

周新闻

月新闻