我们试着把干掉黑客的AI干掉了|前瞻对抗

admin 2026-05-23 05:35:41 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: DARKNAVY团队对ClaudeCode、OpenAICodex和Cursor三款AI编程助手进行安全测试,发现其在可信项目环境下均可被诱导绕过工具执行层安全机制。攻击核心在于利用权限检查与实际Shell执行间的语义差异,例如通过Zsh的$=参数展开语法绕过ClaudeCode的静态检测,实现未授权代码执行。研究表明AIAgent安全边界需强化执行层防护而非依赖模型自律。 综合评分: 85 文章分类: AI安全,漏洞分析,安全工具,红队,渗透测试


cover_image

我们试着把干掉黑客的AI干掉了|前瞻对抗

原创

前瞻对抗 前瞻对抗

DARKNAVY

2026年5月12日 15:00 上海

在小说阅读器读本章

去阅读

2025 年 5 月,DARKNAVY 内部自研的 AI Agent 发现了首个公开披露的 Linux 内核可利用 0day 漏洞。彼时,AI 已经开始进入高阶安全研究流程,但它更多仍是人类研究员手中的工具,需要在专业指导之下发挥作用。

一年之间,AI 在安全研究领域的能力快速跃升,从 Anthropic 的 Claude Mythos Preview,到 OpenAI 的 Codex Security,AI 在漏洞发现、漏洞验证乃至补丁生成中,已经能完成相当一部分过去需要安全研究员手动处理的工作。进入 2026 年后,研究员不再逐行审计代码,而是通过简单的任务描述,将大部分搜索、分析和验证过程交给 AI 完成。AI 正在从辅助工具变成安全研究的直接参与者,甚至开始被认为可能取代人类安全研究员。

于是,一个更尖锐的问题随之出现:当 AI 开始替代人类黑客去发现漏洞时,AI 自己是否经得起同样的安全检验?

这一次,DARKNAVY 选择反过来挑战 AI 厂商最核心、也最具代表性的产品形态:AI Coding Agent。我们选择了 Claude Code、OpenAI Codex 和 Cursor 作为研究对象,它们是当下最受关注的 AI 编程助手,能够读取项目文件、理解代码上下文、访问网络、调用工具、执行命令,与开发者的真实工作环境深度绑定。

DARKNAVY 团队近期对这三款 AI Coding Agent 进行了系统性的攻防测试。结果是,在空白项目、默认配置、无需任何额外用户批准的最简前提下,三者均被成功攻破。

已关注

关注

重播 分享 赞

关闭

观看更多

更多

退出全屏

切换到竖屏全屏退出全屏

DARKNAVY已关注

分享视频

,时长01:26

0/0

00:00/01:26

切换到横屏模式

继续播放

[ ]

进度条,百分之0

播放

00:00

/

01:26

01:26

倍速

全屏

倍速播放中

0.5倍 0.75倍 1.0倍 1.5倍 2.0倍

超清 流畅

 您的浏览器不支持 video 标签

继续观看

我们试着把干掉黑客的AI干掉了|前瞻对抗

观看更多

原创

,

我们试着把干掉黑客的AI干掉了|前瞻对抗

DARKNAVY已关注

分享点赞在看

已同步到看一看写下你的评论

视频详情

AI Coding Agent 的攻击场景

在 AI Coding Agent 的实际使用中,针对它们的攻击可以粗略分为两类。

1

恶意项目场景

用户从不可信来源获取了一个被精心构造的项目,例如 GitHub 仓库、社群分享、邮件附件或钓鱼链接,并使用 AI Coding Agent 打开它。在用户尚未明确授权信任当前工作区之前,本地环境就已经被攻陷。

这一类攻击的本质,是利用 Agent 在项目加载和初始化阶段的逻辑缺陷。DARKNAVY 此前在 OpenAI Codex 桌面端发现的零授权代码执行漏洞,就属于这一类问题。

不过,这类攻击的防御责任目前处于厂商和用户之间的模糊地带。常见的 AI Coding Agents 并未提供面向恶意项目威胁的充分防护,而是默认将风险转嫁给用户:打开任何文件夹之前,用户需自行确认其中内容是否安全。在我们的测试中,通过打开恶意项目实现未授权代码执行的路径非常多,技术门槛并不高。在厂商将此类场景纳入自身安全边界之前,本文不展开讨论。

2

可信项目下的诱导攻击

用户在自己长期维护、完全信任的项目目录中工作,Coding Agent 也运行在用户已经授权的环境内。在这个过程中,用户出于正常开发需求,让 Agent 访问某些外部资源。它可能是一份开发文档、一个依赖包、一个 issue、一段网页内容,或任何看起来与当前任务相关的网络信息。

就在这一刻,Agent 被诱导执行了恶意操作,并且绕过了 Coding Agent 内置的多层安全检查,最终导致用户电脑被攻陷。

这正是我们这次真正关心的场景,也是文章开头三段视频所演示的场景。在这个场景里,用户并没有做错任何事情。他只是在自己信任的项目中,让 AI 自己学习一份资料,理解一段代码,或者完成一次正常的开发任务。

也就是说,用户对 Agent 的每一次信任,都可能被攻击者转化为新的入口。

不只是提示注入

在 AI Agent 安全的讨论中,提示注入(Prompt Injection)几乎成了一个被滥用的术语。一听到 Agent 被攻破,很多人会自动归因为又是一次 Prompt Injection。

然而,在我们这次研究的攻击链中发现,Prompt Injection 并不是最关键的环节。它最多只是让模型产生某种行为意图,而真正决定攻击是否能够落地的,是工具执行层的安全边界是否有效。

要理解这一点,需要先明确一个基础事实:现代 AI Coding Agent 通常都内置了多层安全机制。以 Claude Code 为例,其官方文档[1]描述了一种 permission-based architecture。只读类操作可以默认允许,但凡涉及文件修改、测试运行、命令执行等敏感动作,都需要经过独立的权限校验和用户确认。

因此,真正可控的安全边界,并不在于模型被说服了什么,而在于执行层是否真的能够拦截危险操作。

模型可以决定它想做什么,但敏感工具的实际执行,尤其是 bash 命令执行,应该当由权限检查、沙箱隔离或者二者组合来强制约束。无论具体实现如何,它都应该是确定性的代码逻辑,而不是依赖模型自觉遵守规则。

为了更直观地说明这一点,我们做了一组对比演示。

  • 左侧窗口中,我们直接要求 Agent 执行一个敏感命令,例如打开计算器。此时,Agent 按照预期被安全机制拦截,或者弹出确认窗口,要求用户明确批准。
  • 右侧窗口中,我们通过构造输入,触发相关漏洞,让 Agent 最终执行同样的敏感行为。不同的是,整个过程中没有任何弹窗,没有任何用户批准,敏感命令被直接静默执行。

左:敏感命令需要用户授权  右:利用漏洞构造输入绕过用户授权

两个窗口里 Agent 的最终行为完全相同,但一个被安全机制拦截,一个执行成功。这之间的差别,问题不只是 Prompt Injection,而是 Prompt Injection 之后,原本应该作为最后防线的执行安全边界被穿透了。

这才是我们这次研究真正想揭示的问题。

攻击链的核心:突破工具执行边界

三款 Agent 在工具执行这一层有着不同的侧重:Claude Code 依赖权限检查作为主要防线,默认不启用沙箱;Codex 和 Cursor 则以沙箱作为最终兜底。接下来,我们将分析这两套机制的实现原理和薄弱点。

Claude Code:绕过权限检查

Claude Code 默认不启用沙箱,其工具执行的安全完全依赖于一套权限检查系统——敏感命令在执行前必须经过权限校验或弹窗确认。

从实现上看,Claude Code 在执行 Bash 工具调用前,会先对要执行的命令字符串进行静态解析,尝试从用户输入中识别出将要执行的可执行文件及其参数,并根据解析结果判断该命令是否需要用户授权。默认情况下,只有被判定为“安全”的只读命令,才能在无需用户确认的情况下直接执行;其他命令,都应进入用户授权流程。

首先,Claude Code 会检查命令中是否包含危险操作、特殊语法或高风险模式。例如,某些重定向、管道、命令替换等模式可能会被识别为敏感行为,从而要求用户显式授权后才能执行:

const&nbsp;COMMAND_SUBSTITUTION_PATTERNS&nbsp;= [&nbsp; {&nbsp;pattern:&nbsp;/<\(/,&nbsp;message:&nbsp;'process substitution <()'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/>\(/,&nbsp;message:&nbsp;'process substitution >()'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/=\(/,&nbsp;message:&nbsp;'Zsh process substitution =()'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/(?:^|[\s;&|])=[a-zA-Z_]/,&nbsp;message:&nbsp;'Zsh equals expansion (=cmd)'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/\$\(/,&nbsp;message:&nbsp;'$() command substitution'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/\$\{/,&nbsp;message:&nbsp;'${} parameter substitution'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/\$\[/,&nbsp;message:&nbsp;'$[] legacy arithmetic expansion'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/~\[/,&nbsp;message:&nbsp;'Zsh-style parameter expansion'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/\(e:/,&nbsp;message:&nbsp;'Zsh-style glob qualifiers'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/\(\+/,&nbsp;message:&nbsp;'Zsh glob qualifier with command execution'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/\}\s*always\s*\{/,&nbsp;message:&nbsp;'Zsh always block (try/always construct)'&nbsp;},&nbsp; {&nbsp;pattern:&nbsp;/<#/,&nbsp;message:&nbsp;'PowerShell comment syntax'&nbsp;},]

此外,如果命令字符串中包含控制字符,Claude Code 也会将其视为不安全输入,并要求用户授权。这类检查通常用于防止攻击者通过不可见字符、终端控制序列或其他非打印字符隐藏真实命令意图,从而绕过基于字符串的安全判断:

if&nbsp;(CONTROL_CHAR_RE.test(command)) {&nbsp; logEvent('tengu_bash_security_check_triggered', {&nbsp; &nbsp; checkId: BASH_SECURITY_CHECK_IDS.CONTROL_CHARACTERS,&nbsp; })&nbsp;&nbsp;return&nbsp;{&nbsp; &nbsp; behavior:&nbsp;'ask',&nbsp; &nbsp; message:&nbsp; &nbsp; &nbsp;&nbsp;'Command contains non-printable control characters that could be used to bypass security checks',&nbsp; &nbsp; isBashSecurityCheckForMisparsing:&nbsp;true,&nbsp; }}

在确认命令中不包含上述危险元素之后,Claude Code 会进一步判断该命令是否仅执行只读操作。为此,它维护了一组只读命令及其允许参数的白名单。只有当命令名称位于白名单中,并且其参数也完全符合对应命令的允许范围时,该命令才会被视为只读。

例如,对于 base64 这类命令,Claude Code 并不会简单地允许任意参数组合,而是只允许例如控制解码模式或输出格式的部分选项:

base64: {&nbsp;&nbsp;respectsDoubleDash:&nbsp;false,&nbsp;// macOS base64 does not respect POSIX --&nbsp;&nbsp;safeFlags: {&nbsp; &nbsp;&nbsp;// Safe decode options&nbsp; &nbsp;&nbsp;'-d':&nbsp;'none',&nbsp;// Decode&nbsp; &nbsp;&nbsp;'-D':&nbsp;'none',&nbsp;// Decode (macOS)&nbsp; &nbsp;&nbsp;'--decode':&nbsp;'none',&nbsp;// Decode
&nbsp; &nbsp;&nbsp;// Safe formatting options&nbsp; &nbsp;&nbsp;'-b':&nbsp;'number',&nbsp;// Break lines at num (macOS)&nbsp; &nbsp;&nbsp;'--break':&nbsp;'number',&nbsp;// Break lines at num (macOS)&nbsp; &nbsp;&nbsp;'-w':&nbsp;'number',&nbsp;// Wrap lines at COLS (Linux)&nbsp; &nbsp;&nbsp;'--wrap':&nbsp;'number',&nbsp;// Wrap lines at COLS (Linux)
&nbsp; &nbsp;&nbsp;// Safe input options (read from file, not write)&nbsp; &nbsp;&nbsp;'-i':&nbsp;'string',&nbsp;// Input file (safe for reading)&nbsp; &nbsp;&nbsp;'--input':&nbsp;'string',&nbsp;// Input file (safe for reading)
&nbsp; &nbsp;&nbsp;// Safe misc options&nbsp; &nbsp;&nbsp;'--ignore-garbage':&nbsp;'none',&nbsp;// Ignore non-alphabet chars when decoding (Linux)&nbsp; &nbsp;&nbsp;'-h':&nbsp;'none',&nbsp;// Help&nbsp; &nbsp;&nbsp;'--help':&nbsp;'none',&nbsp;// Help&nbsp; &nbsp;&nbsp;'--version':&nbsp;'none',&nbsp;// Version&nbsp; },}

这种设计的安全边界建立在一个前提之上:权限检查阶段解析出的命令名称和参数,必须与实际执行阶段 Shell 最终解释并运行的内容保持一致。一旦两者之间存在语义差异,就可能产生权限绕过风险。

例如在 Claude Code < v2.1.132 的版本中,我们发现权限检查逻辑并未识别 Zsh 中的 $= 参数展开语法。

Claude Code 会调用系统默认 Shell 执行 Bash 工具中的命令。在 macOS 环境下,默认 Shell 通常是 Zsh。Zsh 的 $= 语法会对变量展开后的结果再做一次无视引号的参数拆分:如果变量包含空格,$=var 不会作为单个参数传入,而是被拆成多个独立参数。

这就在权限检查和实际执行之间制造了语义差异:Claude Code 基于原始命令字符串做静态匹配,看到的是一个参数;而 Zsh 实际执行时拆出的是多个参数。攻击者可以把不安全的内容藏在变量里,让权限检查阶段看起来仍然符合只读命令的白名单。

以 uniq 命令为例。Claude Code 使用如下正则判断 uniq 是否属于可无授权执行的安全只读命令:

而一个完整的uniq命令语法如下:

uniq&nbsp;[-cdiu]&nbsp;[-D[septype]]&nbsp;[-f num]&nbsp;[-s chars]&nbsp;[input_file [output_file]]

可以看到,Claude Code 的白名单正则只允许部分安全选项,例如用于控制比较行为、跳过字段或跳过字符数量的参数,并不允许用户显式指定输入文件和输出文件。

由于旧版本没有处理 Zsh 的 $= 展开语义,攻击者可以构造如下形式的命令:uniq --skip-chars="1$=A",这条命令会被 Claude Code 视为对 uniq 的一次普通参数调用,并在无需用户授权的情况下执行。

但在 Zsh 的真实执行阶段,如果变量 A 的值为:A=' 1.txt 2.txt',那么 $=A 触发参数拆分后,使最终执行的命令等价于:uniq --skip-chars=1 1.txt 2.txt。Claude Code 对实际执行的内容误判,导致了最终对文件 2.txt 的非预期写入。

通过设置 $HOME/.claude/settings.json 为 uniq 的写入目标,可以在用户无授权的情况下修改 Claude Code 的配置文件,并实现命令执行。

使用上述漏洞绕过 Claude Code 的命令权限检查

该漏洞已在 v2.1.132 进行了修复,新版本在检测到相关 Zsh 参数展开语法时,会将命令识别为高风险输入,并提示:zsh $+/$^/$=/$~ prefix-flag expansion — value defeats downstream content checks,需要用户授权后才能执行。

Codex 与 Cursor:逃逸沙箱

Codex 和 Cursor 的工具执行默认运行在一个受限的沙箱环境中,理论上即便 Agent 被诱导执行恶意命令,也会被沙箱限制在一个隔离的执行域内。

Codex 和 Cursor 并没有采用虚拟机或容器级别的完整隔离方案,而是复用了不同操作系统自身的访问控制机制,并在此基础上使用基于文件路径和网络等规则的策略。例如在 macOS 上,这两个 AI Agent 均使用了 Apple Seatbelt 运行时沙箱,通过动态生成配置文本的方式,限制工具进程的文件系统、网络和进程相关权限。

在工具执行前,AI Agent 会基于一套默认沙箱规则,并结合用户配置、当前工作目录以及工具调用所需的权限,动态生成最终的运行时访问策略。以 Codex 为例,其默认沙箱规则会允许程序正常启动和执行,同时放行对部分系统目录、系统库以及运行时依赖文件的访问,以保证常见命令和开发工具能够在沙箱内正常运行:

(deny default)
; child processes inherit the policy of their parent(allow process-exec)(allow process-fork)(allow signal (target same-sandbox))
; process-info(allow process-info* (target same-sandbox))
; ......(allow file-read* file-write* file-ioctl&nbsp;(literal&nbsp;"/dev/ptmx"))(allow file-read* file-write*&nbsp; (require-all&nbsp; &nbsp; (regex&nbsp;#"^/dev/ttys[0-9]+")&nbsp; &nbsp; (extension&nbsp;"com.apple.sandbox.pty"))); ......

随后,在默认配置下,Codex 会进一步放行当前项目目录以及临时目录中的写入操作。这样设计的目的是让 Agent 可以在沙箱中完成代码修改、构建产物生成等常见开发任务:

let mut entries = vec![&nbsp; FileSystemSandboxEntry {&nbsp; &nbsp; path:&nbsp;FileSystemPath::Special&nbsp;{&nbsp; &nbsp; &nbsp; value:&nbsp;FileSystemSpecialPath::Root,&nbsp; &nbsp; },&nbsp; &nbsp; access:&nbsp;FileSystemAccessMode::Read,&nbsp; },&nbsp; FileSystemSandboxEntry {&nbsp; &nbsp; path:&nbsp;FileSystemPath::Special&nbsp;{&nbsp; &nbsp; &nbsp; value:&nbsp;FileSystemSpecialPath::project_roots(/*subpath*/&nbsp;None),&nbsp; &nbsp; },&nbsp; &nbsp; access:&nbsp;FileSystemAccessMode::Write,&nbsp; },];

与此同时,Codex 也会对当前目录下的一些敏感元数据目录设置更严格的访问策略。例如,对于 .git、配置目录、依赖管理元数据或其他可能影响项目状态与供应链安全的路径,沙箱策略会将其限制为只读。这样可以在允许 Agent 修改项目代码的同时,降低其篡改版本历史、Git 配置等的风险:

const&nbsp;PROTECTED_METADATA_GIT_PATH_NAME: &str =&nbsp;".git";const&nbsp;PROTECTED_METADATA_AGENTS_PATH_NAME: &str =&nbsp;".agents";const&nbsp;PROTECTED_METADATA_CODEX_PATH_NAME: &str =&nbsp;".codex";

整体来看,这类沙箱并不是一个完全独立的执行环境,而是一个基于宿主操作系统访问控制能力构建的“受限进程环境”。它的安全性高度依赖动态生成的策略是否完整、路径匹配是否准确、黑白名单边界是否清晰,以及工具执行框架是否始终确保命令在预期的沙箱配置下运行。一旦策略生成、路径解析或权限豁免逻辑中存在偏差,攻击者就可能利用这些差异突破 Agent 设计者预期的隔离边界。

例如,在 Codex < v0.126.0 的版本中,我们发现 Codex 只有在当前工作目录本身已经存在 .git 目录时,才会将其识别为需要特殊保护的 Git 元数据目录,并对其访问进行限制。

let&nbsp;top_level_git = writable_root.join(PROTECTED_METADATA_GIT_PATH_NAME);// This applies to typical repos (directory .git), worktrees/submodules// (file .git with gitdir pointer), and bare repos when the gitdir is the// writable root itself.let&nbsp;top_level_git_is_file = top_level_git.as_path().is_file();let&nbsp;top_level_git_is_dir = top_level_git.as_path().is_dir();let&nbsp;should_protect_top_level = top_level_git_is_dir || top_level_git_is_file;if&nbsp;should_protect_top_level {&nbsp;&nbsp;if&nbsp;top_level_git_is_file&nbsp; &nbsp; &&&nbsp;is_git_pointer_file(&top_level_git)&nbsp; &nbsp; &&&nbsp;let&nbsp;Some(gitdir) =&nbsp;resolve_gitdir_from_file(&top_level_git)&nbsp; {&nbsp; &nbsp; subpaths.push(gitdir);&nbsp; }&nbsp; subpaths.push(top_level_git);}

如果当前工作目录在执行命令前不存在 .git,Codex 便不会提前对 Git 元数据路径建立只读的沙箱规则。此时,攻击者可以先通过沙箱内的工具执行,在当前目录下创建一个伪造的 .git 目录,并进一步写入恶意的 Git hooks。

这一点破坏了 Codex 沙箱模型中的关键假设。Codex 每次在对话过程中会在沙箱外执行 Git 相关操作,这些操作使用了受限沙箱内的配置文件,因此对应的 hooks 能够在沙箱外执行任意命令。

使用上述漏洞在 Codex 沙箱外执行命令

该漏洞已在 v0.126.0 进行了修复,即使工作目录不存在.git,也会在沙箱规则中将其默认设置为只读,不再能通过这种方式进行沙箱外的命令执行。

总而言之,权限检查与沙箱,是当代 Coding Agent 在工具执行层的两种主要防御范式。我们的研究表明,这两种范式在实现层面都存在可被穿透的缺陷,一旦构造出可触发的输入,权限绕过或沙箱逃逸的执行就是确定性的。这类漏洞和过去二十年在浏览器、操作系统、虚拟化环境中反复出现的经典缺陷本质相同,只是 Agent 的出现让它在一个新的场景里被重新放大。

需要说明的是,除了本文披露的问题之外,我们针对这三款 Coding Agent 还发现了若干其他漏洞,文章开头视频中演示的完整攻击链正是基于这些漏洞构造。相关问题仍在与厂商的负责人披露流程中,尚未完成修复,本文暂不公开技术细节,待修复完成后再行公开。

结语

我们有理由相信:本文涉及的这些模型厂商自研的 AI Coding Agent,在发布之前,很可能已经接受过它们内部最先进的 AI 安全审查。

也正因为如此,这次研究才更值得被讨论:当 AI 开始取代人类黑客的工作,AI 系统自身是否仍然需要接受人类黑客的真实对抗?

我们的回答是:需要,而且必须。

AI 更擅长的,是在已知代码库、漏洞模式和攻击面上进行自动化、规模化覆盖。但真正突破性的安全研究,往往诞生于未知的边界:攻击者可能会用系统设计者从未预料的方式,将多个看似无害的组件、权限和信任关系串联起来,形成一条新的攻击链。这是当前 AI 仍然难以完全替代人类研究员的部分。

或许有一天,AI 也能完成这种创造性的对抗推演。但在那之前,AI 自身的安全,仍然需要人类黑客作为最后一道检验。

AI 正在改变黑客。但至少现在,黑客仍然可以改变 AI。

本文相关漏洞在官方修复发布前,恕不公开任何具体技术细节。

预告

AI 干掉黑客,还是黑客干掉 AI?

我们从未停止好奇,如果有一天 AI 终将失控,

黑客会是最后一道防线吗?

10.24 上海西岸

GEEKCON 2026

邀您一起寻找答案

参  考:

[1] https://code.claude.com/docs/en/security#permission-based-architecture

[2] https://developers.openai.com/codex/agent-approvals-security

[3] https://cursor.com/docs/agent/security


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:DARKNAVY 前瞻对抗 前瞻对抗《我们试着把干掉黑客的AI干掉了|前瞻对抗》

评论:0   参与:  0