Hotdry.

Article

即使执行 "cat readme.txt" 也不安全:iTerm2 Conductor 协议注入深度分析

深度解析 iTerm2 Conductor 协议注入漏洞:攻击者如何通过特制文件名让终端执行任意代码,突破传统安全认知。

2026-04-17security

当我们讨论命令注入漏洞时,注意力往往集中在用户直接传入 shell 命令的场景。然而,一个更加隐蔽的攻击面正在被安全研究者持续挖掘 —— 文件名本身就可以成为攻击向量。近期,安全公司 Calif.io 发布的研究揭示了一个令人不安的事实:即使你只是在终端中执行看似无害的 cat readme.txt,特制的文件名同样可能导致代码执行。这一发现并非孤例,它暴露了终端仿真器在处理文本输出时的深层安全盲区。

攻击的本质:终端不只是显示文本

传统认知中,cat 命令的功能仅仅是读取文件内容并输出到标准输出。安全意识较强的开发者会警告不要将用户输入直接拼接到 shell 命令中以防止命令注入,但却忽略了一个更为隐蔽的问题:终端应用程序本身在解析和渲染输出内容时,会执行一系列超出「显示文本」范畴的操作。

iTerm2 作为 macOS 上最流行的终端仿真器之一,内置了丰富的功能以提升用户体验。其中一项功能是 SSH 集成,它允许 iTerm2 与远程 SSH 会话建立更丰富的交互。为了实现这一功能,iTerm2 不会简单地「盲目输入命令」到远程 shell,而是通过一个名为 conductor 的小型辅助脚本来协调整个过程。这个 conductor 脚本通过终端 I/O 与 iTerm2 交换终端 escape sequence,完成诸如发现登录 shell、检查 Python 环境、切换目录、上传文件和运行命令等操作。

问题的关键在于:iTerm2 接受了来自终端输出的 SSH Conductor 协议,而这些输出实际上并非来自可信的、真实的 Conductor 会话。换句话说,攻击者可以通过在文件中植入恶意的终端 escape sequence,伪装成远程 conductor 与 iTerm2 通信。这就是漏洞的核心 —— 信任失败。

攻击链详解:如何从「cat 文件」到代码执行

攻击的具体实现利用了 iTerm2 的两项核心机制:DCS 2000p 用于钩住 SSH conductor,OSC 135 用于 pre-framer conductor 消息。当 iTerm2 收到 DCS 2000p 序列时,它会实例化一个 conductor 解析器,然后接受 OSC 135 消息,包括 begin <id>、命令输出行、end <id> <status> runhook

攻击者的 exploit 文件包含一个伪造的 conductor transcript。当受害者在 iTerm2 中运行 cat readme.txt 时,iTerm2 渲染文件内容,但这个文件不仅仅是文本 —— 它包含了伪造的 DCS 2000p 行和一个伪造的 conductor 会话。一旦 hook 被接受,iTerm2 会启动其正常的 conductor 工作流程。在上游源代码中,Conductor.start() 会立即发送 getshell(),成功后发送 pythonversion()。因此,攻击者不需要注入这些请求 ——iTerm2 自身会发出这些请求,而恶意输出只需要伪装成回复即可。

伪造的 OSC 135 消息非常精简但精确:它启动一个命令体用于 getshell,返回看起来像 shell 发现输出的行,结束该命令成功;然后启动命令体用于 pythonversion,以失败结束,最后 unhook。这足以让 iTerm2 进入其正常的回退路径。此时,iTerm2 相信它已完成足够的 SSH 集成工作流程,可以继续下一步:构建和发送 run(...) 命令。

接下来的部分更加精妙:伪造的 DCS 2000p hook 包含几个字段,其中包含攻击者控制的 sshargs 字段。这个值很重要,因为 iTerm2 稍后会用它作为构造 conductor 的 run... 请求的命令材料。攻击者选择 sshargs 使得当 iTerm2 对 run <padding><magic-bytes> 进行 base64 编码时,最后一个 128 字节块变成 ace/c+aliFIo。这个字符串并非任意选择 —— 它同时是 conductor 编码路径的有效输出和有效的相对路径名。

在合法的 SSH 集成会话中,iTerm2 将 base64 编码的 conductor 命令写入 PTY,SSH 将它们转发到远程 conductor。在 exploit 情况下,iTerm2 仍然将这些命令写入 PTY,但没有真实的 SSH conductor。本地 shell 将它们作为普通输入接收。攻击链的最后一步是:之前创建的 ace/c+aliFIo 文件实际上是一个可执行脚本,当 base64 解码的最后 chunk 解析为这个路径时,命令得以执行。

历史重演:类似漏洞的持续出现

终端仿真器的安全问题并非首次被发现。早在 2019 年,Mozilla 的安全审计就在 iTerm2 中发现了一个关键漏洞,该漏洞同样涉及 tmux 集成功能中的代码执行问题。类似的问题也出现在其他广泛使用的工具中:文本编辑器 Vim 和 Emacs 曾被发现允许通过文件内容执行任意命令;less 命令在处理特制输入时也存在类似风险。这些漏洞的共同特征在于:它们不是简单的输入验证失败,而是工具在处理「正常」文本时引入的额外功能导致的副产品。

值得注意的是,Calif.io 的研究人员展示了如何使用 AI 模型仅根据上游补丁 commit 就重建出完整的漏洞利用代码。这引发了关于漏洞披露时机的讨论 —— 从报告到补丁完成仅用了 18 天,远短于典型的漏洞披露期限。研究者认为,由于 AI 能够快速发现类似漏洞,攻击者很可能已经通过相同方法获得了这些信息,因此提前披露是合理的。

防御策略:多层防护体系

面对这类基于文件名的注入攻击,防御需要从多个层面同时着手。首先,在终端应用层面,用户应当确保始终运行最新版本的终端仿真器。截至本文撰写时,iTerm2 的该漏洞已在 commit 中修复,但尚未进入稳定版本。对于企业环境,应通过配置管理工具密切关注版本更新,并禁用那些存在已知风险的可选功能 —— 如果你不需要 SSH 集成功能,禁用它可以消除这一攻击面。

其次,在操作习惯层面,用户需要对来源不明的文件保持高度警惕。当需要查看未知来源的文本文件时,可以考虑使用更安全的替代方案:将输出重定向到文件后再使用十六进制工具查看原始内容,或者在隔离的虚拟机环境中操作。安全研究者还建议,可以将 cat 命令别名设置为 strings -a --unicode=hex,以避免终端自动解析 escape sequence—— 虽然这会牺牲部分功能,但在大规模处理不可信文件时是一个值得考虑的权衡。

第三,在更广泛的工程实践中,开发者应当重新审视工具链的安全性假设。传统的安全编码规范强调对用户输入进行严格验证,但文件名注入攻击提示我们:即使是从本地文件系统读取的数据,在某些上下文中也可能变成攻击向量。对于构建自动化流水线或 CI/CD 系统的团队,尤其需要对「信任本地文件」这一隐含假设保持警惕。在处理来自不可信来源的文件时,应考虑在受控的沙箱环境中进行。

重新审视「安全的基础设施」

cat readme.txt 被认为是不安全的 —— 这一结论挑战了开发者多年来的安全认知。终端仿真器作为开发者日常使用最频繁的工具之一,其安全性直接影响整个开发环境的安全水位。这个漏洞的精妙之处在于:它不依赖任何传统的代码注入技术,而是利用了终端应用自身的功能设计 —— 通过伪造协议响应来欺骗应用程序。当 AI 辅助漏洞发现逐渐普及,类似的隐藏攻击面正在被加速挖掘。可以预见,未来会有更多看似无害的操作被揭示存在风险。

面对这一趋势,防御策略也需要相应演进。单纯依赖「不运行未知代码」的朴素原则已不足够 —— 你需要理解工具链中每个环节的潜在攻击面,并在系统设计层面纳入纵深防御。对于安全团队而言,定期审计开发工具链的安全性、保持对新兴漏洞的关注、建立快速响应机制,将成为保护基础设施的关键能力。


资料来源:Calif.io 安全研究博客("MAD Bugs: Even 'cat readme.txt' is not safe")、Hacker News 讨论(https://news.ycombinator.com/item?id=47809190)、Mozilla 安全审计报告。

security