阅读CVE-2009-4487 的详细信息(有关日志文件中转义序列的危险)我有点惊讶。
去引用CVE-2009-4487:
nginx 0.7.64 将数据写入日志文件而不清理不可打印字符,这可能允许远程攻击者通过包含终端仿真器转义序列的 HTTP 请求修改窗口标题,或者可能执行任意命令或覆盖文件。
显然,这实际上并不是 nginx 中的安全漏洞,而是终端模拟器中的安全漏洞。
当然,也许cat
将日志文件写入终端只是偶然发生的,但grep
日志文件却很常见。less
也许可以清理转义序列,但谁知道哪些 shell 命令不会改变转义序列......
我倾向于同意清漆反应:
一般来说,终端响应转义的明智性经常受到质疑,但仍然没有一个主要的终端仿真程序认为适合丢弃这些序列,这可能是为了与不再使用的 1970 年代技术兼容而进行的误导性尝试。 [..]从安全角度来看,让终端模拟程序停止做愚蠢的事情,从而一次解决这个问题和其他安全问题,而不是责怪任何和所有写入日志文件的程序,这会更有成效。并为所有人。
因此我的问题是:
如何保护我的 xterm,以便不再能够通过转义序列执行命令或覆盖文件?
哪些 X 终端模拟器可以抵御这种攻击?
答案1
VT100 终端(所有现代终端模拟器都在某种程度上模拟)支持许多有问题的命令,但现代模拟器或发行版禁用了问题较多且不太有用的命令。这是潜在风险的非详尽列表转义序列(不包括那些仅仅以某种方式使显示不可读的内容):
- rxvt 和 Eterm 中的任意日志文件命令HD摩尔报道。这些确实是重大错误,幸运的是早已修复。
- 应答命令,也称为返回终端状态,由
ENQ
(Ctrl+E
) 调用。这会将文本插入到终端中,就像用户已键入文本一样。但是,此文本不受攻击者控制:它是终端自己的名称,通常类似于xterm
或screen
。在我的系统(Debian squeeze)上,xterm 默认返回空字符串(这是由资源控制的answerbackString
)。 - 发送设备属性命令,
ESC [ c
等等。终端响应ESC [ … c
(其中…
只能包含数字和 ASCII 标点符号)。这是查询某些终端功能的一种方法,这些功能大多已过时,但可能被旧应用程序使用。同样,终端的响应与用户输入无法区分,但它不受攻击者的控制。控制序列可能看起来像功能键,但前提是用户具有不寻常的配置(我遇到的常用设置都没有有效的功能键转义序列,该序列是终端响应的前缀)。 - 各种设备控制功能(DCS 转义,以 开头
ESC P
)。- 我不知道
DECUDK
在典型的终端模拟器上通过(设置用户定义的键)会造成什么危害。 DECRQSS
(请求状态字符串) 是终端用转义序列响应的另一个命令,这次以\eP
;开头。这可能会出现问题,因为是\eP
有效的密钥 ( Alt++ )。ShiftP- Xterm 还有两个实验性功能:
ESC P + p …
和ESC P + q …
,用于获取和设置 termcap 字符串。从描述来看,这至少可以用来修改功能键的效果。
- 我不知道
- 几个状态报告命令:(
ESC [ … n
设备状态报告)。终端以转义序列响应。大多数转义序列与功能键转义序列不对应。一个看起来有问题:报告的ESC [ 6 n
形式是其中和是数字序列,这可能看起来像带有一些修饰符。ESC [ x ; y R
x
y
F3 - 窗口操作命令
ESC [ … t
。- 其中一些允许调整 xterm 窗口的大小、图标化等,这是破坏性的。
- 其中一些会导致终端使用转义序列进行响应。大多数转义序列看起来风险较低,但有两个危险命令:分别包含终端窗口图标标签和标题的答案
ESC [ 2 0 t
,ESC [ 2 1 t
攻击者可以选择这些命令。 - 至少在 Debian squeeze 下,xterm 默认忽略这些命令;它们可以通过设置
allowWindowOps
资源或有选择地通过disallowedWindowOps
资源来启用。 Ubuntu 10.04 下的 Gnome-terminal 甚至默认实现了标题应答。我没有检查其他终端或版本。
- 设置终端标题或图标名称的命令。在 xterm 和大多数其他 X 终端下,它们是.在屏幕下,转义序列为。我发现对这些命令的担忧被高估了。虽然它们确实允许一定程度的恶作剧,但任何网页都存在同样的问题。仅根据窗口标题而不是类来对窗口进行操作类似于打开由不受信任方提供的名称的文件,或者不在 shell 脚本中引用变量扩展,或者拍拍疯狗的鼻子——如果你被咬了,不要抱怨。
ESC ] digit ; title ESC \
ESC k title ESC \
我发现 Varnish 的回应不诚实。感觉就像它要么试图转移责任,要么处于安全纳粹模式(任何安全问题,无论真实与否,都证明了阻止某个功能的合理性)。
一般来说,终端响应转义的明智性经常受到质疑,但仍然没有一个主要的终端仿真程序认为适合丢弃这些序列,这可能是为了与不再使用的 1970 年代技术兼容而进行的误导性尝试。 (…)
从安全角度来看,让终端模拟程序停止做愚蠢的事情,从而一次解决这个问题和其他安全问题,而不是责怪任何和所有写入日志文件的程序,会更有成效。对全部。
许多答案都是有用的功能:应用程序确实需要知道光标位置和窗口大小等信息。设置窗口标题也非常有用。可以完全依赖ioctl
对这些的调用,但这需要额外的代码和实用程序来进行这些ioctl
调用并将它们转换为传递文件描述符的 unix 样式文本。现在更改这些接口将是一项繁重的工作,但收效甚微。
文本文件不应包含非打印字符,例如控制字符。日志文件通常应该是文本文件。日志文件不应包含控制字符。
如果您担心文件可能包含转义序列,请在编辑器中打开它,或者less
不使用-r
或-R
选项查看它,或者通过cat -v
.
答案2
事情并不那么简单;很多人都有代码将xterm
标题设置为提示的一部分等,并且有很好的理由(任何shutdown
从错误的终端窗口使用错误机器的人都可以告诉你!)。因此,正确修复它需要引入安全上下文,从而使 shell 和终端仿真器以及可能还有人们的点文件之间的交互变得严重复杂化。或者,您可以采用低租金解决方案,对终端中可能显示的任何内容进行消毒;这很大程度上减少了转义控制字符,无论如何都应该这样做,只是为了让它们脱颖而出(因为在日志文件中它们可以表明有人试图注入 shellcode)。
(作为旁白,庞尼代码是同类问题的一个更严重的例子——尽管如此,它已成为官方标准。有时,安全性归根结底是减少人们无法控制的不安全设计。)