我经常在控制台上使用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


...
...

这使我想到,特制的二进制文件会在系统上造成混乱吗?!...现在,我确实意识到像这样鲁using使用cat并不是特别聪明,但我实际上想知道这里发生了什么。是什么字符导致突然将内容转储到标准输入上的结果...

注意:在执行此操作时,我在Mac OS X终端中,实际上我叫diff -a比较两个固件rom图像并打印出差异(我以为只有几个字节的差异,但是在屏幕上打印了将近8 MB的差异)后来,我有意地尝试整理其中一个文件,并得到了类似的效果我已粘贴到这里。

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

我昨天晚上在这里发布了此文件,今天早上我试图复制此行为我不能。不幸的是,我不确定某些转义字符是否会导致二进制文件中的乱码会自动在控制台上执行,还是在猫的末端我只剩下一堆字符(就像我粘贴了它们一样)。命令行,我可能不小心按了Enter键以得到一条清晰的线...

当我现在尝试查找有问题的文件时,它在完成时会显示出来(向右滚动):

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


是当前工作目录。
如您所见,它在二进制乱码中被伪装了,我可能反身按下Enter键或其他东西。这本身就是猫的错,因为显然我的提示可能甚至被“伪装”得更好。但这没有我最初想象的那么严重。尽管我仍然不能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

在那只猫上叫猫将导致终端退出。

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

类别:将导致1; 2c1; 2c1; 2; 2c1; 2c1; 2c1; 2c1; 2c1; 2c1; 2c1; 2c粘贴。 ...命令行上的字符

评论

啊,那些令人欣慰的回忆,源于ANSI炸弹轰动的时代,并广为人知...

#1 楼

是的,这是潜在的风险,请参阅CVE-2003-0063或CVE-2008-2383或CVE-2010-2713或CVE-2012-3515或OSVDB 3881或CVE-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 ”描述的标准xterm转义符可以做到这一点。此行为允许程序“在带内”查询/设置终端(或其他)属性,而不是通过ioctls或其他一些API。

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

这是一种使用此方法的巧妙方法,其中bash的read用于打印转义符(提示),然后立即阅读并将回复拆分为变量:

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


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

,因此,请结合使用对其他表现相似的序列进行转义:

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


对我来说,这导致11次尝试运行各种命令:12c8220710(我的rxvt版本字符串),0c53R(5和3是光标坐标),1120x0

可利用的吗?

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

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


这三个序列是:




\e]2;...\x07设置窗口标题;

\e[21;;t查询窗口标题,放置在输入缓冲区中;

\eGQ查询图形功能,将\n添加到输入缓冲区。

同样,根据终端,可以通过转义访问其他功能,例如字体大小,颜色,终端大小,字符集,备用屏幕缓冲区等。意外地修改这些内容至少会带来不便,即使不是绝对的安全问题。 xterm的当前版本通过“允许*”资源限制了可能有问题的功能。

CVE-2014-3121

在v9.20之前,urxvt也不保护读写访问X属性(主要由窗口管理器使用)。写入读取访问(或更准确地说,访问回显可能是任意字符串的序列的访问)现在需要-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元字符。
这可以通过多种方式加以利用,首先是处理不可信的二进制文件,然后是高清的更多想法摩尔的短文(2003)。


跟进

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

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


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

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


评论


好的链接!以下是一些特定的Apple苹果cvedetails.com/cve/CVE-2005-1341或cvedetails.com/cve/CVE-2009-1717,可能还有更多...

–伊万·科瓦切维奇(Ivan Kovacevic)
14年4月22日在22:45

我今天发现了这个问题(在搜索有趣的格式字符串时),直到与作者协调后才找到名称或详细信息。

–purpur先生
2014年4月24日在18:06

会做。由于相同的原因,我对段错误的推测性答案(没有OS X计算机可用)被保留。

–purpur先生
2014年4月24日在18:13

该死的,我现在都对这两个东西感到好奇。 i.imgur.com/eNoBclw.jpg可以吗? :)

–伊万·科瓦切维奇(Ivan Kovacevic)
2014年4月24日在18:24



我正在与作者联系,我将尽快用承诺的详细信息更新答案。

–purpur先生
2014年4月30日在0:15

#2 楼

绝对可以。
新添加的2020-01-25:
从我将大多数系统中的默认编码从LATIN-1切换为UTF-8以来,我发现了一些有趣的功能(现在一个字符串有两个长度)...
作为示例,我喜欢玩bash,我问为什么bash本地化不适用于多行字符串。此bash功能
存在一个错误,其中的解决方法是使用eval。如果这不是安全缺陷,那么它可能会变成或产生一个问题。
几乎所有事物(语言,库,工具,协议,应用程序,硬件,安装程序,控制台等)的每一种演变中都可能产生或产生一个缺陷。 ..)
具有一些新功能,其中包括潜在的新错误。
幸运的是,它们的数量与被迅速纠正的(从揭密到将近一天的时间)一样少,但是确实如此!
所以绝对可以,请当心!
正确使用cat命令。
由于您似乎正在使用现代的终端仿真器,因此可以使用一些转义序列来修改键盘缓冲区。
注入了正确的shell命令。
可以使用-e的参数cat进行安全操作,请参见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

或在bash下:
$ less < <(cat -e suspectfile.raw)
$ which less cat
/usr/bin/less
/bin/cat
$ rawless() { /usr/bin/less < <(/bin/cat -e "$@");}
当您阅读command not found时,这表示已有效注入了某些东西。
主要的注入功能没有删除的是序列uence可以识别自己,在许多VT-100封装中使用。
此序列为Escape Z,它将把字符串1;2c注入键盘缓冲区,这意味着VT-100(按照AVO约定)。
说到cat,您可以试试:
$ cat <<< $'3Z'

或另一个ANSI序列:CSI c(设备属性):
$ cat <<< $'3[c'

将打印一个空行,但是在下一行提示时,您将看到1;2c(或者也许以及另一个数字,具体取决于所使用的终端),就像您打了它们一样:
$ 65;1;9c█

...但是使用-e开关:
$ cat -e <<< $'3Z'
^[Z$
$ cat -e <<< $'3[c'
^[[c$

,其中-e => -vE-v3转换为^[-E在行尾添加一个$符号(并且下一行不会放置任何内容,您的键盘缓冲区不是
您可能会在《 VT100用户指南》中发现很多有趣的东西(例如:cat <<< $'3#8';)
(它们是现代的终端机!在过去的某个时代...)
尝试使用bash

有一个bash命令用于刷新键盘缓冲区并获取其内容:
$ cat <<<$'3[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 ""
    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!
$ █

A现在是吗?
不幸的是,那里没有标准。
每个虚拟终端实现都可以支持完整的ANSI和/或完整的DEC标准...
但是由于存在一些安全问题,许多......
使用一个终端可以观察到某些行为,而使用另一终端则无法观察...
xterm,linux控制台,gnome-terminal,konsole,fbterm,Terminal(Mac OS)...
终端仿真器的列表不是很短!
与DEC和ANSI标准相比,它们各自都有各自的错误和局限性。
在实践中,您可能会发现一些虚拟控制台可能比其他虚拟控制台功能更强大,并且键盘注入会破坏您的安全性。
原因之一是因为我更喜欢使用始终相同(旧)的xterm,而不是其他功能更强大的工具。

评论


哦?愿意分享细节吗?在一定程度上,这是终端仿真器中的关键安全漏洞。

– tylerl
2014年4月22日在5:49

这就是为什么某些ANSI转义序列通常在现代终端/仿真器中被禁用的原因。

–keshlam
2014年4月22日在7:38

猫-e,好的建议!我仍然很想知道您是否可以使用这些转义序列的示例来扩展答案,以修改键盘缓冲区,从而可能解释这一点。

–伊万·科瓦切维奇(Ivan Kovacevic)
2014年4月22日在12:39

当我键入man cat时,我看到的是-e“等同于-vE”,但是-vE上没有给出任何信息。

– Apnorton
2014年4月22日在18:35

约定是可以将单个字符标志组合在一起,因此-vE与-v -E相同。即,手册页告诉您查看-v和-E标志的文档,这些标志分别表示“使用^和M-符号显示非打印字符”和“将行结尾显示为$字符”。

–Cookyt
2014年4月22日在18:42

#3 楼

“真实”玻璃终端具有转义序列,可以将屏幕打印到打印机。他们通过运行命令并将当前屏幕内容通过管道传递给print命令的stdin来实现。

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

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

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

从理论上讲,现代的终端仿真器不再应该做这种事情。

Terminal.app似乎基于

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

好像有转义序列升高和降低终端:

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

此处有更多信息:

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

如果要将内容发送到程序的stdin,

program -para meters < /path/file.ext


评论


“当前屏幕内容为标准输入” —屏幕内容不是标准输入。

–俄罗斯
2014年4月22日11:35



@Ruslan:他的意思是将屏幕内容传递到的命令的标准输入。

– jwodder
2014年4月22日在16:40

那应该是不是

–俄罗斯
2014年4月22日在17:14

@JasperWallace:很酷的信息!示例:最小化Terminal.app:echo -e'\ x1B [2t'最小化-最大化echo -e'\ x1B [2t \ x1B [5t':)

–伊万·科瓦切维奇(Ivan Kovacevic)
2014年4月22日22:23在

#4 楼

通常没有漏洞,但是显然如果使用不当,则可以创建一个漏洞。

打印二进制文件的内容会发出哔哔声,因为字符7是使机器发出哔哔声的旧终端命令。 ,并且某些终端程序仍然遵循该命令。但是根据设计,没有什么可以伤害您的。在最坏的情况下,只需打开一个新的终端窗口来消除可能已经创建的任何混乱。

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

但是只要您不做任何事情,就可以了。

评论


在这种情况下,我只需键入:cat <文件名>。因此,我没有在控制台中粘贴一些伪造的命令,而是检查了对我刚才写的问题的更新。

–伊万·科瓦切维奇(Ivan Kovacevic)
2014年4月22日14:38在

#5 楼

您所看到的是xterm控制序列。

当在终端的输出中看到控制序列时,它们就会被激活;例如,当您使用不可打印的ASCII字节存储文件时。

在您的示例中,控制顺序是ESC Z(字节1B 5A),它返回终端ID-作为终端中的命令。

您可以自己尝试:

echo -e '\x1BZ'


(或者,您可以将ESC编写为\eZ编写为\x5A)。

还有其他一些有趣的东西:

echo -e '\eF' # move the prompt to the bottom of the terminal.
echo -e '\ec' # Reset the terminal


评论


实际上,在我的情况下,echo -e'\ x1BZ'仅打印出空行。但是,echo -e'\ x1B [\ x1BZ''在命令行上打印了“ 1; 2c”,这是在查找该固件二进制文件后反复得到的。那是和[,它称为转义序列,后跟Z。但是我不知道1; 2c的含义。那是终端ID吗?

–伊万·科瓦切维奇(Ivan Kovacevic)
2014年4月22日在22:18

@IvanKovacevic是的,请参阅我的附录。 (我的第一个回答太快了。抱歉;)

– F. Hauri
2014年4月22日23:34

@dr jimbob:我不对,echo -e'\ x1BZ'确实可以工作,但是在Mac OS X上它有一些奇怪的行为。如果我是首次发行它并删除输出的字符,请按Enter键以得到一个清除新的提示(因为回显还会在提示行的前面或后面留下一些胡言乱语,这取决于您如何看待它)。然后,如果我尝试使用向上键调出最后一个命令,然后再次调用它,它将不再起作用...仅显示换行符。这就是为什么我最初虽然无法运行的原因,因为我已经调用了它……在Linux上,每次都可以正常运行。

–伊万·科瓦切维奇(Ivan Kovacevic)
2014年4月23日在2:58



而且echo -e'\ x1B [\ x1BZ'也每次都起作用。我想CSI序列会重置它。

–伊万·科瓦切维奇(Ivan Kovacevic)
2014年4月23日在3:02

别名clear =“ echo -e'\ ec'”最后,在cygwin <3中清除

– Qix-蒙尼卡(MS)被盗
2014年4月24日在0:45

#6 楼

我将在此处添加此信息,而无实际意图回答我自己的问题。
在打印其他一些字符(最好称为转义序列)时可以在命令行中注入的字符在此站点上定义得非常好(感谢F. Hauri的提及):http://vt100.net/docs/vt100-ug/chapter3.html

下章:报告


光标位置报告

由ESC调用[6 n
响应是ESC [Pl; Pc R
Pl =行号; Pc =列号

状态报告

由ESC调用[5 n
响应为ESC [0 n(终端正常)
ESC [3 n (终端不正常)

您是什么人

ESC [c或ESC [0 c
”调用的响应是ESC [吗? 1个Ps c

Ps是“存在选项”参数,具有以下含义:

Ps含义
0基本VT100,无选项
1处理器选项(STP)
2高级视频选项(AVO)
3 AVO和STP
4图形处理器选项(GPO)
5 GPO和STP
6 GPO和AVO
7 GPO,STP和AVO

由ESC Z替代调用(不建议)。响应是相同的。


ESC是ASCII十进制27或八进制33或十六进制1B。

因此,例如可以打印出当前光标位置,或者更好表示已注入到现有命令行中,则可以调用:

echo -e '3[6n'


,输出将是这样的:

7;1R


可以按照以下转义顺序移动光标位置

echo -e '3[10;20H'


10-第10行
20-第20列

但是它不会移动列的位置(它确实会在行中移动),因为终端可能会将其重置为行的开头。无论如何,如果在此之后立即查询光标位置,它将在控制台上“粘贴”设置的列位置:

echo -e '3[10;20H3[6n'


输出:

0;20R


这就是您如何在控制台上注入(“粘贴”)不同的输出的方法,它远非任何真正的利用方法,因为这将仅给出可以输出的不同数字组合,但随后又可能与其他组合。谁知道。

在我照顾到固件映像的情况下,我得到了很多:1; 2c
现在我知道这是“ What Are You”报告,关于我的终端机,其中2表示:高级视频选项(AVO)。总而言之,最好避免盲目地放置任何文件...
如已经建议的那样(也由F. Hauri撰写),至少使用cat -e

#7 楼

将随机文件传递给任何类型的解释器都存在明显的风险,但是unix并不是为了保护用户免受自己的愚蠢而设置的。只需使用cat filename可能会弄乱您的显示,但不会损坏任何东西。

如果您使用cat查看文件并确定其类型,我建议您了解file(告诉您文件是什么是)和less,如果您正在查看二进制数据,它将发出警告,并且不会将100Mb安装程序存档转储到您的控制台。 zless将透明地打开gzip文件。

评论


当然,将随机文件发送到解释器(即bash)非常危险。但这不是我们在这里讨论的。仅显示猫的内容(历史记录显示)会造成损害。检查斯普雷蒂奇先生的答案。

–伊万·科瓦切维奇(Ivan Kovacevic)
2014年4月23日14:08在

要增加保罗的回答,已经说了很多次了,但是旧的习惯却很难改掉:不要为此使用cat,少使用文本编辑器。

–柴巴
2014年4月23日在16:58