使用“回声”在终端上显示攻击者控制的数据是否危险?

信息安全 脆弱性 重击
2021-08-10 14:21:53

想象一下下面的代码:

ATTACKERDATA="$(cat attackerControlledFile.txt)"
echo "${ATTACKERDATA}"

攻击者可以通过任意过程将其内容修改为attackerControlledFile.txt他们想要的任何内容。内容可以是 ASCII、UTF-8、二进制等。什么都可以。该机器还假设它的速度无限快,因此即使是数 TB 的超大文件也可以立即读取和打印。

攻击者是否有可能通过修改 的内容以某种方式利用它,无论它多么不可能attackerControlledFile.txt“不知何故”指的是:

  • 此代码仅适用于 bash
  • 此代码要求将输出打印到特定的终端仿真器上
  • 等等。

其他一切都假设一个合理健全的系统。这意味着诸如“如果echo是攻击者控制的二进制文件实际上是恶意软件”之类的答案不计算在内,因为恶意软件的存在并不完全是“合理的”。需要特定软件或该软件版本存在的答案确实很重要只要该软件不是为了利用目的而制作的。


一个类似的问题问是否可以恶意使用 Linux “echo” 命令?,但公认的答案实际上是关于 Web 应用程序设计中的缺陷。此外,它要求攻击者能够进行重定向,据我所知,此构造无法做到。

4个回答

攻击者是否有可能通过修改attackerControlledFile.txt 的内容以某种方式利用它,无论它多么不可能?“不知何故”指的是:

此代码要求将输出打印到特定的终端仿真器上

事实上,是的。像 vt100 这样的旧终端能够使用 ANSI 转义序列来做一些特殊的事情,比如执行命令。下面的网站使用简单的回声记录了这种能力,就像你描述的那样。

https://www.proteansec.com/linux/blast-past-executing-code-terminal-emulators-via-escape-sequences/

这篇文章深入介绍了具体的利用说明,但可以从该站点的以下摘录中总结出总体思路:

危险的转义序列终端仿真器支持多种功能,如下所述 [8]:

  • 屏幕转储:屏幕转储转义序列将打开任意文件并将终端的当前内容写入文件。一些终端仿真器不会写入现有文件,而只会写入新文件,而其他终端仿真器只会用新内容覆盖文件。攻击者可能会使用此功能在 Web 服务器的 DocumentRoot 中创建一个新的后门 PHP 文件,该文件以后可用于执行任意命令。

  • 窗口标题:存在用于设置窗口标题的转义序列,这将改变窗口标题字符串。此功能可以与另一个转义序列一起使用,它读取当前窗口标题并将其打印到当前命令行。由于窗口标题中禁止回车字符,攻击者可以将命令存储在窗口标题中并将其打印到当前命令行,但仍需要用户按回车键才能执行它。有一些技术可以使命令不可见,例如将文本颜色设置为与背景相同的颜色,这会增加用户按下回车键的变化。

  • 命令执行:一些终端仿真器甚至可以允许通过使用转义序列直接执行命令。

正如评论中所指出的,这个特殊的漏洞是几十年前在现代终端模拟器上修复的。这只是一个简单的例子,30 秒的谷歌搜索显示,它很好地展示了这样一个概念,即仍有软件在工作,即使在显示文件这样简单的事情中也可以利用。

从理论上讲,现代终端仿真器可能存在其他可利用的问题(缓冲区溢出?)。

如果输出将发送到终端,则根据其他答案,您可能会遇到很多问题(无论您如何打印,除非您去除特殊字符)。

如果文件可能很大,攻击者可以bash利用大量 RAM。考虑head -c 100000而不是cat设置 100kB 的上限。或者head -c 10000 | cat -v (将非打印字符显示为^M或其他;可能会破坏 UTF-8 多字节字符)。

如果您希望数据可能很大,请考虑直接运行该命令(而不是在var=$()捕获中),并将输出cat直接连接到您的标准输出。


由于您在 shell 变量中拥有数据,而不是eval在双引号内进行编辑,因此您可以避免某些事情。

例如命令替换将不起作用。

peter@volta:/tmp$ foo='$(touch bar)'
peter@volta:/tmp$ echo "${foo}"
$(touch bar)

攻击者可以通过使用 string 稍微修改输出-n,这echo将解释为选项而不是文字数据。

$ echo "-n"     # notice that this doesn't print a newline.
$ echo ""       # unlike a normal echo "" or echo with no args

$

但是 bash 的内置echo函数并不"-n foo"作为一种选择。它按字面意思打印:

$ echo "-nabcd"
-nabcd

由于您在双引号内扩展了 shell 变量,因此它无法成为echo 的多个参数,例如echo "-n" "leave the cursor at the end of this string"

同样-e是不可能的,也不是危险,因为您的文件已经可以包含任意二进制数据。


/bin/echo来自 GNU Coreutils 的选项支持一个--version选项,因此如果您没有使用 shell 内置 echo,那么攻击者可以让您的程序打印软件版本信息。如果该输出最终以攻击者可见的形式出现,则它会披露有关目标系统的一些信息。


由于这些原因,便携式打印任意数据的建议是:

printf "%s\n" "${ATTACKERDATA}"

适用于所有 POSIX shell,不受echo.

但请注意,这对终端漏洞没有任何作用,它只是一种无需echo修改即可直接写入任何数据的安全方法。

在大多数 shell 中,二进制数据仍然将\0(零字节)视为终止符,因为 bash 内部使用 C 字符串。OSexecve接口也使用 C 字符串,但 shell 内置函数允许 shell 绕过echo/ printf,因此可以例如zshecho / printf 包含零字节的二进制数据。


顺便说一句,在 bash 中,您实际上并不需要cat读取文件。带有重定向的命令替换让 bash 自己进行读取。

ATTACKERDATA="$(< attackerControlledFile.txt)"

但是如果你想要任何处理,比如head -cand/or cat -v,你应该使用一个真正的命令。

一些终端可以像输入一样回显屏幕内容。

因此,您可以强制“键入”,从而使用正确的终端命令执行命令。我已经在物理 DEC 上做到了这一点VT62-t但还没有尝试用 X-term 的 VT-52 模式来做

这个漏洞是众所周知的,并且可能是从etcfinger -l username中删除所有控制字符(换行符和制表符除外)的原因~username/.plan

所以是的,这很危险。使其安全地通过 less 或 col 等管道。

不,上面示例中使用的 echo 很好

Echo 只是将字符串打印到管道标准输出(默认)

每:https ://superuser.com/a/699500/527937

管道不能溢出。管道只是生产者和消费者之间的缓冲区(一定数量的内存,在当前系统上很可能是 64KB)。如果生产者的生产速度快于消费者的消费速度,生产者将被阻塞(这意味着程序将休眠),直到消费者通过读取缓冲区再次腾出空间。

作为旁注,如果您在 1x 行中有大量数据......cat可能会挂起和/或消耗大量系统内存。