如何避免终端中的转义序列攻击?

max*_*zig 30 security terminal-emulator xterm special-characters escape-characters

阅读CVE-2009-4487 的细节(这是关于日志文件中转义序列的危险)我有点惊讶。

引用CVE-2009-4487

nginx 0.7.64 将数据写入日志文件而不清理不可打印的字符,这可能允许远程攻击者通过包含终端模拟器转义序列的 HTTP 请求修改窗口的标题,或可能执行任意命令或覆盖文件。

显然,这实际上并不是 nginx 中的安全漏洞,而是终端模拟器中的安全漏洞。

当然,也许cat将日志文件写入终端只是偶然发生的,但是将日志文件写入grep是很常见的。less也许清理转义序列,但谁知道什么 shell 命令不会改变转义序列......

我倾向于同意Varnish 的回应

终端响应转义的智慧通常定期受到质疑,但仍然没有一个主要的终端仿真程序认为适合丢弃这些序列,这可能是在与不再使用的 1970 年代技术兼容的误导尝试中。[..] 从安全的角度来看,让终端仿真程序停止做愚蠢的事情,从而解决这个和其他安全问题,而不是责怪任何和所有写入日志文件的程序,这将更有效率和所有人。

因此我的问题:

我如何保护我的 xterm,以便不再可能通过转义序列执行命令或覆盖文件?

X 的哪些终端模拟器可以抵御这种攻击?

Gil*_*il' 31

VT100 终端(所有现代终端模拟器都在某种程度上模拟)支持许多有问题的命令,但现代模拟器或发行版禁用了更多问题和不太有用的命令。这是潜在风险转义序列的非详尽列表(不包括仅以某种方式使显示不可读的那些):

  • HD Moore 报告的rxvt 和 Eterm 中的任意日志文件命令。这些确实是主要错误,幸运的是长期修复。
  • 应答命令,也称为返回终端状态,由ENQ( Ctrl+E)调用。这会将文本插入终端,就像用户输入一样。但是,此文本不受攻击者的控制:它是终端自己的名称,通常类似于xtermscreen。在我的系统(Debian 挤压)上,xterm 默认返回空字符串(这是由answerbackString资源控制的)。
  • 发送设备属性命令ESC [ c和朋友。终端响应ESC [ … c(其中只能包含数字和 ASCII 标点符号)。这是一种查询某些终端功能的方法,这些功能大多已过时但可能被旧应用程序使用。同样,终端的响应与用户输入无法区分,但它不受攻击者的控制。控制序列可能看起来像一个功能键,但前提是用户有一个不寻常的配置(我遇到的所有常见设置都没有有效的功能键转义序列,即终端响应的前缀)。
  • 各种设备控制功能(DCS 转义,以 开头ESC P)。
    • 我不知道DECUDK在典型的终端模拟器上通过(设置用户定义的键)会造成什么危害。
    • DECRQSS(Request Status String) 是另一个终端以转义序列响应的命令,这次以\eP;开头。这可能是问题,因为\eP是一个有效的密钥(Alt+ Shift+ P)。
    • Xterm 还有两个实验性功能:ESC P + p …ESC P + q …,用于获取和设置 termcap 字符串。从描述来看,这至少可以用来修改功能键的效果。
  • 几个状态报告命令:(ESC [ … n设备状态报告)。终端以转义序列响应。大多数这些转义序列不对应于功能键转义序列。一个看起来有问题:报告ESC [ 6 n的形式是where和are 数字序列,这可能看起来像一些修饰符。ESC [ x ; y RxyF3
  • 窗口操作命令ESC [ … t
    • 其中一些允许调整 xterm 窗口的大小、图标化等,这是具有破坏性的。
    • 其中一些导致终端以转义序列响应。大部分这些转义序列的期待低风险的,但是有两个危险的命令:答案ESC [ 2 0 tESC [ 2 1 t分别包括终端窗口的图标标签和标题,并且攻击者可以选择这些。
    • 至少在 Debian 挤压下,默认情况下 xterm 会忽略这些命令;它们可以通过设置allowWindowOps资源或选择性地通过disallowedWindowOps资源来启用。Ubuntu 10.04 下的 Gnome-terminal 甚至默认实现标题回复。我没有检查其他终端或版本。
  • 设置终端标题或图标名称的命令。在 xterm 和大多数其他 X 终端下,它们是. 在 Screen 下,转义序列是。我发现对这些命令的关注被高估了。虽然它们确实允许一些恶作剧,但任何网页都有相同的问题。仅根据标题而不是类来操作窗口类似于打开一个文件,其名称是由不受信任的一方提供给您的,或者不引用 shell 脚本中的变量扩展,或者在鼻子上轻拍一只疯狗——如果你被咬了不要抱怨。ESC ] digit ; title ESC \ESC k title ESC \

我发现 Varnish 的回答不诚实。感觉它要么试图转移责任,要么在安全纳粹模式下(任何安全问题,无论是否真实,都可以证明对功能进行黑球)。

终端响应转义的智慧通常定期受到质疑,但仍然没有一个主要的终端仿真程序认为适合丢弃这些序列,这可能是在与不再使用的 1970 年代技术兼容的误导尝试中。(...)
与其责怪任何和所有写入日志文件的程序,从安全的角度来看,让终端仿真程序停止做愚蠢的事情会更有效率,从而一次性解决这个和其他安全问题对所有人。

许多答复都是有用的功能:应用程序确实需要知道诸如光标位置和窗口大小之类的信息。设置窗口标题也很有用。完全依赖ioctl于这些调用是可能的,但是这将需要额外的代码和实用程序来进行这些ioctl调用并将它们转换为传递文件描述符的 unix 样式文本。现在更改这些接口需要大量工作,但收益甚微。

文本文件不应包含非打印字符,例如控制字符。日志文件通常应该是文本文件。日志文件不应包含控制字符。

如果您担心文件可能包含转义序列,请在编辑器中打开它,或者less不带-r-R选项查看它,或者通过cat -v.

  • “完全依赖 ioctl 调用这些是可能的”但是如果应用程序和终端之间真的有串行电缆怎么办? (3认同)

gee*_*aur 5

事情没那么简单;很多人都有将xterm标题设置为提示等的一部分的代码,并且有很好的理由(因为任何shutdown从错误终端窗口使用错误机器的人都可以告诉你!)。因此,正确修复它涉及引入安全上下文,从而使 shell 和终端仿真器之间的交互以及可能人们的 dotfiles 之间的交互严重复杂化。或者,您可以采用低租金解决方案,对终端中可能显示的任何内容进行消毒;这在很大程度上减少了转义控制字符,无论如何应该这样做只是为了让它们脱颖而出(因为在日志文件中它们可以表明有人试图注入shellcode)。

顺便说一句,punycode是同类问题的一个更严重的例子 - 尽管如此,它已成为官方标准。有时安全性归结为减轻不受控制的不安全设计。)