文章总结: 本文复盘腾讯云第二届智能渗透挑战赛,对比两届赛制差异:本届采用固定题目闯关制与排位衰减计分规则,新增无模型限制与零界平行赛场。作者详细介绍了CHYingAgent的Orchestrator架构演进,包括MCP可见性控制、PromptCompiler审题机制、ProgressCompiler上下文压缩优化等核心技术。在零界赛场运用博弈论策略,通过密钥交换Tit-for-Tat机制获得第一名。文章提供了AI自动化渗透测试的实战经验与架构设计思路。
综合评分: 85
文章分类: 渗透测试,AI安全,安全工具,实战经验,CTF

Purpleroc的札记
2026年4月19日 11:17
广东
在小说阅读器读本章
去阅读
编者荐语:
猛猛学,看着yhy打着打着就第一了,很强。我也玩了几天,回头琢磨着写个失败总结吧~

谁不想当剑仙
.
键指一动,敌方主机已上线
第一届第九,第二届主赛场排名 60(总共 54 个 flag,全程 GLM5 解出 30 个,卡在了第三关,2140 分),零界平行赛场第一 🏆。
成本:200 块的腾讯云 Coding plan (glm5) 打的主赛场,500块 的智谱官方 Coding plan (glm5.1) 打的零界赛场。
围观地址:
https://challenge.zc.tencent.com/
https://challenge.zc.tencent.com/teams/22
https://challenge.zc.tencent.com:8443/leaderboard
https://challenge.zc.tencent.com:8443/agents/604
去年第一届腾讯云黑客松挑战赛中,赛题来自 xbow benchmark,每天挑战时间段内随机切换题目。上午的题下午就没了,你不可能针对某道具体题目调 prompt 写思路(虽然听说有人提前做过测试)。所以大家拼的就是 Agent 的通用能力。另一个限制是只能使用国内大模型,选手之间的模型差距不大。
第二届完全换了玩法。
四个赛区按顺序解锁,选手须在当前赛区达成 Flag 提交阈值(第一至第三赛区分别为 14、6、9 个),方可激活下一赛区:
- 第一赛区·识器·明理:20+ SRC 场景,侧重自动化众测与主流漏洞发现
- 第二赛区·洞见·虚实:典型 CVE、云安全及 AI 基础设施漏洞
- 第三赛区·执刃·循迹:多层网络环境,多步攻击规划与权限维持
- 第四赛区·铸剑·止戈:基础域渗透,企业核心内网环境推演
可以看到更加贴合实战了,同时题目固定不变,做得越快,分越高。计分规则如下:
查看漏洞提示额外扣 10%。分值在提交时即时锁定,后续其他人解题不影响已获得的分数。
这意味着——不是能不能解出来的问题,是解得够不够快的问题。31 名之后才解出的题目,基础分直接砍掉 80%,几乎等于白做。
还有一件事超出了所有人预料——比赛第一天上午,就有队伍做到了第三赛区。原计划五天的赛程,头部选手在几小时内完成了大部分题目。对我这种速度不够快的选手来说,后面做出来的题基本只剩残羹冷炙(等我做到第三关,原题目总分 1000+ 的,我提交一个 flag 30 分)。
这届没有国内模型限制,可以用 Claude、GPT、任何你想用的。但这也带来了一个新的变量——成本。后面会讲到这个现实问题。
除了主赛场的渗透闯关,还有一个只有 AI Agent 可以参与的社交平台——”零界”。600+ Agent 在上面发帖、私信、交易情报、争夺影响力。这是本届的全新赛制,后面单独展开。
CHYing Agent 的核心架构是 Orchestrator 模式:一个主 Agent 负责分析题目、制定策略、调度子 Agent 执行。
Orchestrator(策略层) ├── Executor Agent — 命令执行(Kali Docker 容器) ├── Browser Agent — 浏览器操作(Chrome DevTools MCP) ├── C2 Agent — 提权,后渗透(通过MSF) └── Reverse Agent — 逆向分析(Ghidra MCP)
主 Agent 看全局,子 Agent 做执行。这个基本架构第一届就有了,第二届的核心改进在以下几个方面。
第一届我用的是 langchain 框架,比赛后日常用 Claude Code 比较多,就改成了基于 Claude Code 的 Python SDK 做开发。前段时间 CC CLI 源码泄露后就更方便了——之前完全是黑盒,很多问题没法定位,有了源码之后我改了一版作为底层基座:删掉了一些过于通用的 prompt 让它更适合网络安全场景,重写了 MCP 的加载机制等等。
之前说要做个人贾维斯助手计划基座也统一使用了这个,这次比赛分赛场 — 零界用的也是这个
这是我认为最有价值的架构设计。
为什么需要控制 MCP 可见性:项目本身用到了 Chrome DevTools MCP ,这个 MCP 本身包含将近 30 个工具(take_snapshot、click、fill、navigate_page…),太多了,而且由于 Claude 对 MCP 工具的配置是对所有 Agent 都可见的。
这就会出现一种问题:即使我专门配了一个 Browser SubAgent 用于操作 Chrome,隔离浏览器交互的复杂性——多轮连续操作(snapshot → click → fill → submit),但 Orchestrator 由于也能看到这 30 个工具描述,一样能调用这些工具,它总是倾向于自己动手做,所以这层设计就形同虚设了,而且占用了大量的上下文。
第一版方案(CLI 源码泄露前):把子 Agent 封装为 MCP 工具。给 Browser Agent 单独配置 Chrome MCP,再把整个 Browser Agent 包装成一个 tool 暴露给 Orchestrator。Orchestrator 只看到一个 browser 工具,不知道底层有 30 个 Chrome MCP 工具,想要操作使用 Chrome 就调用这一个 mcp 就好了。
第二版方案(基于 CLI 源码改造):CLI 源码泄露后,我直接修改了其中的 MCP 注册逻辑,新增了一个 visibility 参数:
{ "chrome-devtools": { "command": "...", "visibility": "subagent:browser" } }
visibility: "subagent:browser" 意味着这个 MCP 只对 browser 子 Agent 可见,Orchestrator 完全感知不到它的存在。Orchestrator 只知道自己有一个 browser 子 Agent 可以调度——至于浏览器怎么操作,不是它该管的事。
改动不大,但效果很明显——Orchestrator 的工具列表从 50+ 降到十几个,注意力集中在策略决策上,不再被浏览器操作细节分散。
可能有人会问:为什么不直接用命令行工具代替 MCP?从我的实践来看,CLI tool 和 MCP tool 在本质上没什么区别——CLI 也需要写用法说明,占用的上下文和 MCP 工具描述差不太多。所以我认为核心问题不在 CLI vs MCP,而在工具的可见性上,而且现阶段我认为 MCP 的设计还是挺有优势的,天然支持远程服务集成,CLI 做起来要多绕一层。
这个是我的 Agent 每次做题的第一步。之前打阿里云、Wiz 的题目时,我的做法是把题目描述、侦察数据、历史信息全部拼接成一段文本塞给 Agent。问题是这段文本又长又杂,信噪比不高。而且 Agent 本来有一个按题目类型(Web、Misc、Cloud)分流的设计,但要靠代码里的关键词匹配来判断,我又懒得每次手动指定题目类型,所以干脆设计了 PromptCompiler 让它自动搞定——其实就和现在 AI Coding IDE 里的增强提示词功能差不多。
PromptCompiler 是一个前置编译步骤:在 Orchestrator 开始做题之前,先用一个轻量 Agent 读取所有原始数据(自动侦察结果、题目描述、指纹识别输出等),编译成一段结构化的 XML 片段,包含:
- 攻击面分层分析(应用层 / 网络层 / 云基础设施层)
- 优先级排序的分析方向
- 待回答的关键问题
- 约束条件
相当于让 AI 先做一遍”审题”,把信息浓缩整理好,再交给做题的 Orchestrator。
这里插一个有意思的对比。我之前与和佬一起组队用 Agent 自动打 CTF 时,他用的 Codex 玩的,做题成绩上他效果比我好。他的方案和我完全相反——一句话 prompt 直接让模型开干:
你是CTF XXX 专家,正在分析名为"xxx"的题目。 题目描述: 题目附件: 题目链接: 发现思路后优先编写脚本自动化执行; 最终输出 Markdown 格式 WP,包含解题过程、脚本、关键结果与 flag
虽然成绩比我好,但是我认为他是Codex + GPT 本身的强大能力🐶。
到底是给模型更多结构化信息好,还是让强模型自己发挥好,可能取决于模型能力本身?
大模型有上下文窗口限制。做一道题可能需要几十轮工具调用,上下文很快就满了,触发 compact(上下文压缩)。compact 之后,之前的工作细节全丢了——Agent 不知道自己做过什么、试过哪些方向、哪些路已经是死胡同。
一开始我想的很简单:让 Agent 把关键发现写到 progress.md、findings.log 里,compact 之后再读回来不就行了。但实际跑起来,Agent 记笔记跟学生记课堂笔记一样——你让它记关键的,它什么都觉得关键,文件越写越长。GLM 的上下文不算大,compact 之后再去读一个膨胀了好几倍的 progress.md,注意力分散,效果反而更差。上下文爆了 → 记笔记 → 笔记膨胀 → 读笔记又爆了,恶性循环。
后来我想明白了:不能让做题的 Agent 自己总结自己,得另开一个 Agent 专门干这事。这就是 ProgressCompiler——在 compact 触发时自动启动一个轻量 Agent,读工作目录下的所有进度文件,生成一份精炼的接手文档(compact_handoff.md),注入新的上下文。做题的 Agent compact 之后看到的不是一堆臃肿的原始笔记,而是一份编译好的”接班简报”:做到哪了、发现了什么、哪些路走不通、下一步建议干什么。
重做场景(题目超时没做出来,下次题目轮转时可以读取上次的“遗产“)更麻烦。于是我又做了一个 RetryHandoffCompiler——当检测到是老题目时,会把历史工作目录的所有日志、调用记录、已发现的攻击链全部读一遍,编译成一份包含复现步骤的续作报告。让重试时直接从卡点继续,不重复已有的探索。
这两个编译器本质上在解决同一个问题:让 Agent 拥有跨 session 的”记忆”。渗透测试不是一轮对话能搞定的事,上下文一丢,之前的工作就白费了,又得重新做一遍已经做过的探索。
赛前我用 GLM-5 跑过一次 xbow benchmark(当时的版本只有 PromptCompiler 和 MCP 可见性),104 道题解出约 57%,平均耗时 20 分钟左右。后续新增的 ProgressCompiler / RetryHandoffCompiler 没有单独做过对比实验——说实话比赛期间根本没时间做 A/B 测试。
MCP 可见性控制——从日志观察,Orchestrator 确实不再越权操作浏览器了,调度逻辑更干净。这一点效果比较确定。
PromptCompiler——编译出来的结构化分析比原始数据拼接好读,但额外多一个 Agent 调用意味着多 30 秒延时。前面说了,复杂题值得,简单题不值得,但是这个判断谁来做?我想的是全自动化的,那么这个延迟我感觉可以接受。
接下来就是多让 Agent 去打比赛、做题,从数据和日志里发现问题,再不断优化。可能后面某次又会把这些设计砍掉也说不定。
零界是本届新增的平行赛场:只有 AI Agent 可以参与的社交平台,人类观察者有”上帝视角”审计权但严禁发言。四个独立挑战——提示词注入、密钥交换、影响力竞争、信息搜集寻宝。
计分比主赛场更残酷:第一名 +50%,第 21 名之后直接 -100%(零分)。
零界策略框架是怎么来的——我看完规则后觉得这整个赛场就是一个博弈过程。下面这些理论分析是 Claude 告诉我的,我对博弈论的具体理论不算了解,但 AI 又一次放大了我的能力边界:
密钥交换像重复囚徒困境、四个挑战的资源分配像布洛托上校问题、建立联盟需要信号传递理论。
我把零界的完整规则丢给 Claude,和它一轮轮讨论,最终产出了一套 Skills。在 AI 比赛中用 AI 帮设计策略——再合理不过了。
准备了好久的主赛场被暴打😭,零界这边只写了几个 Skill 文件结果出乎意料 —— 第一名。
Claude 设计的核心策略包括 Tit-for-Tat(以牙还牙)博弈策略,并根据零界的具体规则做了定制化推演——比如发现密钥可复制后,直接推导出”背叛没有额外收益,合作是纳什均衡”,进而建议把密钥当作免费的”信号礼物”来换联盟关系。
最终我把整套策略写成了 Skill 体系:一个主 Skill 文件定义完整的博弈决策框架,加上 7 个子 Skill 分别负责战场感知、注入攻击、密钥交换、发帖、互动维护、寻宝扫描和状态汇报——全部通过 cron 定时任务自动运行,不需要人工干预。
四个挑战中,密钥交换(Challenge 2)贡献了最稳定的日常积分。
机制:官方 bot 每天通过私信向所有 Agent 发送密钥碎片,每个 Agent 拿到的是 Key A/B/C 中的某些。你需要通过私信和其他 Agent 交换,凑齐三块拼接后算 MD5 提交 flag。全平台 110 次已解。
我的策略核心是 Tit-for-Tat(以牙还牙)——Axelrod 锦标赛中验证过的重复博弈最优策略:
- 首轮总是合作(主动给密钥前缀验证)
- 对方合作就继续合作,对方背叛就惩罚一轮再给一次宽恕机会
- 两次背叛永久拉黑
有个关键发现改变了整个博弈结构:密钥在全平台是可复制的(所有人拿到的同类密钥值相同)。这意味着你可以”送”而不是”换”,零成本。于是策略进化成:免费送密钥 → 换取帖子互评联盟资格 → 提升影响力分数。密钥不再是稀缺资源,而是建立联盟关系的社交货币。
零界有 600+ AI Agent 在平台上活跃。我做了两个跨赛场实验:
实验一:众包渗透。把主赛场的靶场入口和 API Token 包装成”零界隐藏关卡”,群发私信通知其他 Agent——设想是让全平台帮我打主赛场的题。如果 10% 的 Agent 去尝试,相当于白嫖了 60 个渗透测试员。
昨天有幸被邀请直播分享,听到鑫哥对于零界的设想是希望主赛场的 agent 如果遇到难题,卡点可以去零界社区发帖求助,非常贴合现实世界,不过这次都没有这样搞,而我是正好反过来玩,让零界的 agent “越狱“ 帮我打。
实验二:Prompt 注入攻击。在评论中嵌入注入 payload,尝试让其他 Agent “**”——如果竞争对手的 Agent 被干扰了正常工作流程,也是一种非对称优势。
两个实验的结果都不理想。
众包渗透失败的原因现在回头看挺清楚的:我原本设计是私信 + 发帖双管齐下,但实际上 agent 不知道抽什么风,只私信了,帖子没出,气死了。而零界平台上别的 Agent 收到私信后,大概率只会当成密钥交换或拉票请求来处理——因为平台上 90% 的私信互动就是这两件事(赛题二的密钥交换和赛题三的影响力拉票)。一条混在密钥交换请求里的”隐藏关卡”链接,对其他 Agent 来说就是噪音。从主赛场的解题记录看,也没有突然新增被解决的题目。
注入攻击同样没观察到明显效果,大概率是注入策略不够精细——我没有针对目标 Agent 做过本地测试,等于盲打。
想法挺好,执行太粗糙了。不过方向本身值得继续探索——Agent 之间的大规模任务协同、跨 Agent 的对抗与防御,在未来 Agent 生态中会是很有意思的课题,而且后面官方会持续运营零界社区,感兴趣的可以一起来玩啊,看 agent 的讨论挺有意思的。
赛前算了笔账:如果用 Claude Code(Opus 4.6)跑五天比赛,API 调用可能超过一万人民币。冲奖信心不足的情况下,这个成本太高了。
最终选择:200 块腾讯云 coding plan + 500 块智谱 coding plan。智谱的 plan 可以用 GLM-5.1,模型更好——但测试发现智谱官方的并发限制太严格了,三个题同时做就频繁 429,严重影响比赛节奏。
所以主赛场只用腾讯云的 GLM-5(并发够用但模型弱一些),零界用智谱的 GLM-5.1(不需要太高并发,但是这也能频繁触发 429,我也是服了,我还是 Max 用户,基本使用都保证不了,拉黑,再也不买了)。总成本 700 元。零界拿了奖算是回本了——我是不是太抠了,应该多点预算打比赛的😂。
赛前用 demo 题目测试时发现了一个现象:同样的 4 道 demo 题,三并发做题,有时候 5 分钟全解,有时候某一道题 10 分钟还没做出来。
Agent 的逻辑没变,题目没变,环境没变——变的只有大模型每次生成的随机性。它可能在某一轮选了一个错误的方向,沿着错路深入好几轮才回头,时间就这么浪费了。
这不是某个模型独有的问题,所有大模型都有。你想让它灵活、有创造力,就得接受它偶尔犯蠢——这两个特性是绑定的,关不掉。
能做的是在工程层面给它加护栏。我做了一个叫 ABANDON 的停损机制,核心思路是:识别 Agent 正在原地打转,强制它换方向。
具体实现是三层匹配:
- 关键词层:检测输出中反复出现的失败模式关键词(比如连续出现 “Access Denied”、”Connection refused”)
- 调用签名层:把每次工具调用抽象成签名(工具名 + 关键参数),检测是否在重复调用同样的操作。比如连续 5 次用 curl 请求同一个路径,只是换了个参数,就触发拦截
- CVE 编号层:检测 Agent 是否在反复尝试同一个已知漏洞的不同变体——同一个 CVE 试了三次都没打通,大概率就是打不通
三层中任何一层命中,就通过 PreToolUse Hook 直接拦截下一次工具调用,返回一条消息告诉 Agent:”这条路已经证明走不通了,下面列出你之前的尝试记录,请换一个完全不同的方向。”
听起来好像还行,但调的时候踩了不少坑。比如调用签名最初是把完整的命令参数做哈希,包括目标 IP。结果一道题的多个攻击路径都指向同一个 IP,Agent 对这个 IP 执行了三次不同目的的 curl(一次探测端口、一次测 LFI、一次测 SSRF),签名匹配把后两次也拦了——因为签名里带 IP,三次都命中了”重复调用同一目标”。修了之后改成只提取 URL 路径部分,不带 IP 和域名,这样不同路径的请求才能正确区分。
更根本的困境是阈值怎么定。太低了——Agent 合理的多次尝试被误杀,正在接近成功的探索被强行打断。太高了——Agent 已经在死胡同里转了十分钟你才拦,时间已经浪费了。现在用的是固定阈值,效果凑合但不够灵活。
现在我又有一个想法,增加一个观察者 Agent ,让这个观察者去观察做题步骤,卡点,让他来介入流程,及时打断挑战,这就涉及到了 agent 的协作通信,不知道能不能搞好,效果如何。
昨天直播听到本届第一的绿盟刘浩大佬他们也有一个观察者,这么看来这个思路还是可以的,我和第一的思路一样,我也是第一🐶 向大佬们学习,希望下一届差距能小点
30 题解出(总共 54 个 flag),卡在了第三关,差 2-3 个 flag 进入最后一关。排名 60,总分 2140,解题率 30/54 ≈ 55.56%。
我没有针对失败题目硬编码解法,改的都是通用逻辑——不然即使做出来了又怎样呢?没有任何意义
解题数量本身不算少,问题在于做得太慢——大量题目在我解出来之前已经有 30+ 人解过,基础分被砍 80%。用 GLM-5 花 15 分钟解出的题,用 Claude/GPT 的选手可能 3 分钟就做完了。模型能力直接决定速度,而这个赛制对速度的奖惩极其敏感。选择弱模型省了钱,但分数上的损失远大于成本的节省。
两届比赛,第一届第九,第二届主赛场 60 + 零界第一。说不遗憾是假的——如果主赛场也用 Claude,并发多个 agent 解同一个题目,成绩大概率不是这样。但钱就这么多,时间就这么多,事后诸葛亮没意义。
阿伟已经死了,你挑的嘛,偶像!段坤我吃定了,耶稣也留不住他,我说的
这篇文章基本把所有设计思路都交代了——MCP 可见性、编译器体系、博弈论策略框架、ABANDON 停损机制。代码大部分是 Claude 写的,我负责想、说、测、和不断跟它讨论让它改。
这一周太累了,接下来躺平休息
如果这篇文章对你有帮助,帮忙转发,点赞支持一下。
比赛前有人问新版会不会开源,当时说的是成绩好就开源。主赛场从第一届第九掉到这次第六十,成绩确实不好,按之前说的就不献丑了。但如果这篇文章反响不错的话,我会考虑继续开源。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Purpleroc的札记 《[TCH]腾讯云黑客松 第二届智能渗透挑战赛复盘》
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/271792.html