“cat-ing”文件会成为潜在的安全风险吗?

信息安全 linux 开发 苹果系统 终端
2021-08-19 01:45:29

我经常在控制台上使用cat来查看文件的内容,偶尔我会不小心 cat 一个二进制文件,它基本上会产生乱码和系统哔哔声。但是今天我遇到了 cat 实用程序的输出被重定向到控制台输入的情况,所以我得到了这样的东西:

-bash: 2c: command not found
-bash: 1: command not found
-bash: 1: command not found
-bash: 112: command not found
-bash: 112: command not found
-bash: 1: command not found
-bash: 0x1: command not found
-bash: 2c1: command not found
-bash: 2c: command not found
-bash: 1: command not found
-bash: 1: command not found
-bash: 112: command not found
-bash: 112: command not found
-bash: 1: command not found
-bash: 0x1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found
-bash: 2c1: command not found

……
_

这让我想到一个专门制作的二进制文件会在系统上造成相当混乱?!...现在我确实意识到像这样鲁莽地使用 cat 并不是特别聪明,但我实际上想知道这里发生了什么。什么字符会产生突然将内容转储到标准输入的效果...

注意:我在 Mac OS X 终端中执行此操作时,我实际上调用了diff -a来比较两个固件 rom 映像并将差异打印出来(我认为只有几个字节的差异,但那里几乎 8 MB打印到屏幕上的差异)后来我故意尝试对其中一个文件进行分类并获得与我粘贴在这里相同的效果。

- 更新 - - 更新 - - 更新 -

我昨天深夜在这里发布了这个,今天早上我试图复制这种行为,但我做不到。不幸的是,我无法确定是否某些转义字符导致二进制文件中的乱码自动在控制台上执行,或者是否在 cat 结束时我只剩下一堆字符(好像我已经粘贴了它们)命令行,我可能不小心按了 Enter 以获得清晰的线条......

当我现在尝试 cat 有问题的文件时,我会在它完成时得到它(向右滚动查看):

D?k(Fli9p?s?HT?78=!g??Ès3?&é??  =??7??K?̓Kü<ö????z(;???????j??>??ö?Ivans-MacBook-Pro:FI9826W-2.11.1.5-20140121 NA ivankovacevic$ 1;2c1;2c1;2;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c;1;1;112;112;1;0x1;2c1;2c;1;1;112;112;1;0x1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c

我的实际提示是:

Ivans-MacBook-Pro:FI9826W-2.11.1.5-20140121 NA ivankovacevic$

在哪里:

FI9826W-2.11.1.5-20140121 NA

是当前的工作目录。正如你所看到的,它被伪装在二进制乱码中,我可能已经反射性地按下了输入或其他东西。这本身就是 cat 有点错误,因为显然我的提示可能会更好地“伪装”。但它没有我最初想象的那么严重。虽然我仍然不能 100% 确定昨晚我尝试时它没有自动执行,因为在此之前,昨晚还发生了另一件奇特的事情。我在另一个非常相似的文件上调用了 cat ,导致终端应用程序退出:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00007fcb9a3ffffa

现在我在想这两个事件的组合可能导致控制台上自动执行乱码。但我无法再次复制这种行为。

有问题的文件是 Foscam IP 摄像机的固件,链接如下:

国际站点: http
://foscam.com/Private/ProductFiles/FI9826W-2.11.1.5-20140120.zip 然后里面的文件:FI9826W_app_ver1.11.0.40_OneToAll.bin

在那个上调用 cat 将导致终端退出。

美国站点: http
://foscam.us/downloads/FI9826W-2.11.1.5-20140121%20NA.zip 然后文件:FI9826W_app_ver1.11.0.40_OneToAll_A.bin

cat-ing 会导致在命令行上粘贴 1;2c1;2c1;2;2c1;2c1;2c1;2c1;2c1;2c1;2c1;2c.... 字符

4个回答

的,这是一个潜在风险,请参阅CVE-2003-0063CVE-2008-2383CVE-2010-2713CVE-2012-3515OSVDB 3881CVE-2003-0020或列出的任何类似风险这里......下面还有一些评论。

更新它不仅仅是一个潜在的风险,它是一个真正的风险rxvt-unicode(版本 2.7-9.19,在 9.20 中修补)允许对X 窗口属性进行读/写访问,这可以启用用户辅助执行任意命令,此问题已分配CVE-2014-3121,更多详细信息请参见https: //bugzilla.redhat.com/show_bug.cgi?id=1093287

最近(2019 年 10 月)发现直到 v3.3.5 的iTerm2版本存在同一类问题:恶意内容的显示可以启用集成的 tmux 并允许执行命令,请参阅CVE-2019-9535

这个主题在这里也有很好的报道:https ://unix.stackexchange.com/questions/73713/how-safe-is-it-to-cat-an-arbitrary-file 和Gilles对潜在问题的彻底分析在这里:https ://unix.stackexchange.com/questions/15101/how-to-avoid-escape-sequence-attacks-in-terminals 。


解释

您正在观察的是某些转义序列如何表现的副作用:其中一些将字符(通常也包含转义序列)直接填充到终端输入缓冲区中。当然,这一切都是为了向后兼容。使用术语“Report <something>”描述标准xterm转义就是这样做的。此行为允许程序“内”查询/设置终端(或其他)属性,而不是通过 ioctls 或其他一些 API。

好像这还不够糟糕,一些这样的序列可以包含一个换行符,这意味着从终端(您的 shell)读取的任何内容都将看到看似完整的用户命令。

这是使用它的一种巧妙方法,使用 bashread打印转义(作为提示),然后立即读取并将回复拆分为变量:

IFS=';' read -sdt -p $'\e[18t' csi8 rows cols
echo rows=$rows cols=$cols

这些序列可能因终端而异,但对于rxvt和派生,图形查询转义包括换行符(使用bash$''字符串的示例,请参见doc/rxvtRef.txt源代码)`:

$ echo $'\eGQ'
$ 0
bash: 0: command not found

此转义发送\033G0\n到终端输入缓冲区(或数字1,而不是0如果您有图形功能rxvt)。

因此,将此转义与行为类似的其他序列结合起来:

echo $'\x05' $'\e[>c' $'\e[6n' $'\e[x' $'\eGQ'

对我来说,这会导致 11 次尝试运行各种命令:1、、2c8220710我的rxvt版本字符串)、、0c53R5 和 3 是光标坐标)1120x0.

可利用?

使用rxvt最新的终端仿真器,您应该“仅”能够创建一组有限的主要数字序列。在旧的终端模拟器中(上面列出的一些 CVE)可以访问剪贴板、窗口图标和标题栏文本来构造更多恶意字符串以进行调用(当前的一个小例外是如果您设置了answerbackStringX 资源字符串,但这不能直接使用此方法设置)。然后,该缺陷允许任意读写访问传递状态或存储在将数据填充到输入缓冲区中的转义序列中的内容。

rxvt需要编译时更改才能激活,但urxvt有一个-insecure命令行选项可以帮助您启用一些更令人兴奋的功能:

$ echo $'\e]2;;uptime;\x07' $'\e[21;;t' $'\eGQ' 
bash: l: command not found
17:59:41 up 1448 days,  4:13, 16 users,  load average: 0.49, 0.52, 0.48
bash: 0: command not found

这三个序列是:

  1. \e]2;...\x07 设置窗口标题;
  2. \e[21;;t 查询窗口标题,放入输入缓冲区;
  3. \eGQ查询图形功能,添加\n到输入缓冲区。

同样,根据终端,字体大小、颜色、终端大小、字符集、备用屏幕缓冲区等其他功能可以通过转义访问。对这些进行意外修改至少会带来不便,如果不是彻底的安全问题的话。当前版本xterm通过“允许*”资源限制可能存在问题的功能。

CVE-2014-3121

在 v9.20 之前,也没有保护对X 属性urxvt的读写访问主要由窗口管理器使用)。读访问(或更准确地说,访问可能回显任意字符串的序列)现在需要该选项。-insecure

$ echo $'\e]3;xyzzy=uptime;date +%s;\x07'
$ xprop -id $WINDOWID xyzzy
xyzzy(UTF8_STRING) = 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x3b, 0x64, 0x61, 0x74, \
0x65, 0x20, 0x2b, 0x25, 0x73, 0x3b

这可以简单地用于将任意字符串填充到终端输入缓冲区中。当调用查询属性的转义序列时(以及\eGQ添加换行符的帮助):

 $ echo $'\e]3;?xyzzy\x07' $'\eGQ'
 $ 3;uptime;date +%s;0
 bash: 3: command not found
 17:23:56 up 1474 days,  6:47, 14 users,  load average: 1.02, 1.20, 1.17
 1400603036
 bash: 0: command not found

多个命令,保留空格和 shell 元字符。这可以通过多种方式加以利用,当然,首先是对不受信任的二进制文件进行处理,HD Moore 的短文(2003 年)中提供了进一步的想法。


跟进

对于您询问的转义序列:1;112;112;1;0x1;2 这是:请求终端参数(DECREQTPARM)和发送设备属性

$ echo $'\e[x' $'\e[0c'
;1;1;112;112;1;0x1;2c

第二个 ( \e[0c) 与^E(using rxvt) 相同。那里也有一些转义序列。为每个编写的完整序列分别是:

\e[1;1;1;112;112;1;0x
\e[?1;2c

肯定是的。

新增2020-01-25:

从我在大多数系统中从LATIN-1编码切换到UTF-8默认编码开始,我发现了一些有趣的特性现在一个字符串有两个长度)......

作为示例,我喜欢,我问过为什么 bash 本地化不适用于多行字符串此 bash 功能存在一个错误,解决方法包括使用eval. 如果这不是一个安全漏洞,这可能会成为或产生一个......

在几乎任何事物(语言、库、工具、协议、应用程序、硬件、安装程序、控制台等)的每一次演变中,都会出现新功能,也可能会出现新错误……

幸运的是,它们的数量很少,因为它们会很快得到纠正(距揭晓近一天),但它们确实如此!

所以肯定是的,保持关心!

正确使用cat命令。

由于您似乎使用的是现代终端仿真器,因此可以使用一些转义序列来修改键盘缓冲区

可能会注入适当的 shell 命令。

您可以使用参数-eofcat进行安全操作,请参阅man cat.

  -e     equivalent to -vE

  -E, --show-ends
         display $ at end of each line

  -v, --show-nonprinting
         use ^ and M- notation, except for LFD and TAB

然后

$ cat -e suspectfile.raw
$ cat -e suspectfile.raw | less

或以下

$ less < <(cat -e suspectfile.raw)

甚至

$ which less cat
/usr/bin/less
/bin/cat
$ rawless() { /usr/bin/less < <(/bin/cat -e "$@");}

评论

当您阅读时command not found,这意味着某些东西被有效地注入了。

删除的主要注入功能是序列标识自己,用于许多 VT-100 封装。

这个序列Escape Z会将字符串注入1;2c您的键盘缓冲区,这意味着VT-100(在 AVO 约定中)。

说到cat,您可以尝试:

$ cat <<< $'\033Z'

或另一个 ANSI 序列:(CSI c设备属性):

$ cat <<< $'\033[c'

将打印一个空行,但在下一行提示时,您会看到1;2c(或者可能带有其他数字,取决于使用的终端),就像点击它们一样:

$ 65;1;9c█

...但有-e开关:

$ cat -e <<< $'\033Z'
^[Z$
$ cat -e <<< $'\033[c'
^[[c$

where -e => -vE, -v转换\033^[并在行尾-E放一个$符号(下一行不会放任何东西,你的键盘缓冲区不受影响)。

您可能会在VT100 用户指南中找到很多有趣的东西(例如:cat <<< $'\033#8';)

(他们是现代终端!在过去……)

尝试使用

有一个小 bash 命令用于刷新键盘缓冲区并获取他的内容:

$ cat <<<$'\033[c';buf='';while read -t .1 -n 1 chr;do
        buf+="$chr"
  done;printf "\n>|%q|<\n" $buf

^[[?65;1;9c
>|$'\E[?65;1;9c'|<

还有一个测试任何链的小功能:

$ trySeq() {
    printf -v out "$1"
    echo -n "$out"
    buf=""
    while read -t.1 -n1 char
      do buf+="$char"
    done
    [ "$buf" ] && printf "\r|%q|->|%q|<\e[K\n" "$out" "$buf"
}

所以我可以尝试:

$ for seq in $'\e['{c,{1..26}{n,t,x}};do
      trySeq "$seq";done
|$'\E[c'|->|$'\E[?65;1;9c'|<
|$'\E[1x'|->|$'\E[3;1;1;120;120;1;0x'|<
|$'\E[5n'|->|$'\E[0n'|<
...

(也许会对您的控制台产生一些无害的影响;)

实用小样

想象一下,有些人可以在你的环境中放置这样的东西:

$ source <(printf '%dc() {
     printf "You\\047ve been hitted\\041\\n"
   };\n' {0..100};printf 'alias %s=1c\n' {0..100};)

那么,如果你

$ cat <<<$'\e[c'

$ 65;1;9c█

光标将停留在命令提示行的末尾。

从那里开始,如果你用机器敲击Return而不是Ctrl+c,你会读到如下内容:

$ 65;1;9c
You've been hitted!
You've been hitted!
You've been hitted!
$ █

现在?

不幸的是,从那里开始没有标准

每个虚拟终端实现都可以支持完整的 ANSI 和/或完整的 DEC 标准......

但由于存在一些安全问题,许多人不...

您可以使用一个终端观察到一些您不会使用另一个终端观察到的行为......

xterm, linux console, gnome-terminal, konsole, fbterm, Terminal (Mac OS)...终端模拟器 的列表不是那么短!

与 DEC 和 ANSI 标准相比,它们中的每一个都有自己的错误和限制。

实际上,您可能会发现一些虚拟控制台可能比其他控制台更具特色,并且键盘注入可能会破坏您的安全性。

这是原因之一,因为我更喜欢使用始终相同(旧)xterm而不是其他更具特色的工具。

“真正的”玻璃终端有一个转义序列,可以将屏幕打印到打印机上。他们通过运行命令并将当前屏幕内容通过管道传输到打印命令的标准输入来做到这一点。

该命令可以由另一个转义序列配置。

利用这一点的经典方法是创建具有嵌入转义序列的名称的文件,以设置打印机命令并将其更改为您选择的某些脚本,然后在其中包含打印转义序列的第二个文件。

当有人随后ls在该目录中运行时,他们最终会运行您的代码。如果他们是用户,那就太好了root

理论上,现代终端仿真器不应该再做那种事情了。

Terminal.app 似乎是基于 NextStep nsterm 的,所以它里面可能有各种奇怪的东西。

也许尝试缩小产生command not found消息的确切字节的范围?

看起来有转义序列可以升高和降低终端:

http://the.taoofmac.com/space/apps/Terminal

这里有更多信息:

http://invisible-island.net/ncurses/terminfo.src.html#toc-_Apple__Terminal_app

如果您想将内容发送到程序的标准输入,

program -para meters < /path/file.ext

通常没有漏洞,但显然如果您使用错误,那么您可以创建一个。

打印二进制文件的内容会产生哔声,因为字符7是使机器发出哔声的旧终端命令,并且某些终端程序仍然支持该命令。但是按照设计,那里没有任何东西可以伤害您。在最坏的情况下,只需打开一个新的终端窗口即可撤消可能已创建的任何混乱。

现在,如果您以某种方式将文件的内容重定向到命令 shell,那就是另一回事了。您可以通过将某些内容的输出传送到/bin/bash(从安全角度来看通常不赞成)来做到这一点,或者您可能无意中将其复制并粘贴到您的终端中。也通常是不明智的。

但只要你不运行这个东西,你就没事。