Drag and Pwnd:利用ASCII字符攻破VS Code | PortSwigger研究
控制字符如SOH、STX、EOT和ETX本不应运行您的代码——但在现代终端模拟器的世界中,它们有时确实会这样。在本文中,我将深入探讨ASCII传输控制字符的被遗忘机制,它们如何塑造早期计算,以及现在如何被滥用于影响现代应用程序的真实漏洞中。
当终端使用控制代码交流时
在基于GUI的IDE和精美字体出现之前,计算机通过串行线路进行通信——逐个字符。为了保持这些对话的结构化,ASCII引入了一组通信控制字符:用于在系统之间分隔和管理消息流的不可见字节代码。
典型消息遵循严格结构:
|
|
[\x01] SOH
:头部开始[\x02] STX
:文本开始[\x03] ETX
:文本结束[\x04] EOT
:传输结束
从传输帧到交互式编辑
尽管它们的原始目的是通信控制,但如今这些字符中的许多仍然存在——被现代软件重新利用。
Readline库(被Bash和其他交互式shell使用)重新使用几个控制字符值进行行编辑:
[\x01] Ctrl + a
:移动到行首[\x02] Ctrl + b
:向后移动一个字符[\x03] Ctrl + c
:中断当前进程或命令[\x04] Ctrl + d
:删除光标处的字符
还有许多其他Readline快捷键(Ctrl + e、Ctrl + k、Ctrl + l等)——请参阅Readline手册页以获取更多信息。请记住,在MacOS上,您需要按Control键,而不是Command键。
当过去反噬:利用node-pty
快进到今天。像Visual Studio Code这样的应用程序使用node-pty在JavaScript环境中模拟伪终端。这将原始字节直接转发到shell,信任下游的所有内容都会"做正确的事情"。
当控制字符发挥作用时,这种信任就会破裂。
案例1:Visual Studio Code:配置文件
在Visual Studio Code中,您可以在运行→添加配置下定义自定义运行配置。这些配置通常包含一个args数组。在我之前的研究中,我发现了一个有趣的操作系统命令注入漏洞变体:将[\x01] SOH
字符插入参数会导致shell拆分和误解它们。让我们检查以下测试配置文件:
|
|
不是运行Python脚本,Visual Studio Code在MacOS上打开Calculator应用程序:
|
|
在Ubuntu上也可以工作;使用gnome-calculator
代替。
为什么这有效
查看197年数字设备公司的VT100用户指南,显示控制字符如何使用键盘快捷键编码:
正如您已经知道的,node-pty读取原始字节并将其直接发送到shell。每当Visual Studio Code看到字节[\x01] SOH
时,它就会将光标移动到行首(Ctrl + a)。
在给定示例中,此操作重复四次以反向构建有效负载并启动Calculator应用程序。
案例2:Visual Studio Code:文件拖放
虽然将恶意参数添加到运行配置是一个不寻常的用例,但问题可能出现在其他用户控制的输入中,例如文件名——任何node-pty盲目将数据传递到shell的地方。在文件拖放等情况下,这尤其令人担忧。默认情况下,如果将文件拖放到窗口中,终端应用程序会打印文件的完整路径。想象一下,一个文件名中隐藏了恶意有效负载:
|
|
Visual Studio Code终端看到的内容:
|
|
请注意,当文件被拖放时,回车字符[\x0d]
会自动执行命令。这阻止了用户在终端窗口中检查潜在的有害输入。
附带损害
此漏洞影响任何允许在文件名中使用控制字符的操作系统。我成功在macOS和Ubuntu上重现了此问题。在Windows上,风险通过两个因素得到缓解:文件系统不允许在文件名中使用控制字符,并且Visual Studio Code默认使用PowerShell,它不会将控制字符解释为光标移动或命令中断。有趣的是,默认的macOS终端在拖放带有特殊字符的文件时显示警告,而Ubuntu的内置终端在拖放期间自动转义控制字符。
这是一个看起来安全的转义函数——但此技术轻松绕过它:
|
|
虽然我已经在使用node-pty的Node.js应用程序中演示了此漏洞,但根本问题在于应用程序如何与终端通信。任何将原始字节盲目传递到终端而没有适当控制字符清理的Web应用程序都可能易受攻击——无论底层语言、框架或运行时环境如何。
披露
我将此漏洞提交给Microsoft安全响应中心;但是,他们不认为这是一个安全问题。根据他们的评估,现有的缓解措施——如工作区信任警告和需要大量用户交互——降低了严重性。
所以,下次将文件从不受信任的源拖放到终端应用程序时要小心。
最终想法
我们已经将这些技术中最有效的集成到Burp Suite的Active Scan++扩展中。要自己探索或测试它们,只需从Github直接安装或更新扩展。如果您对命令注入研究感兴趣,不要错过:
- Orange Tsai - WorstFit:揭示Windows ANSI中的隐藏转换器
- David Leadbeater - 终端转义:从命令行接口工程意外执行
小挑战
如果您想测试新知识,我为您准备了一个小型概念验证项目。您的任务:读取位于/app目录中的flag.txt文件的内容。
玩得开心!