【翻译】利用 “cat” 隐藏文本
/usr/bin/cat 指令可以从一个地方读取数据并在另一个地方展示;大部分情况下,它被用来从文本文件中读取数据在标准输出中展示。cat 默认支持控制字符,类似于 \n
,\f
,\r
等。
这里有一小段 python 代码,我们来看看 \r
是如何隐藏部分指令的:
cmd_h = "echo 'You forgot to check `cat -A`!' > oops" # hidden
cmd_v = "echo 'Hello world!'" # visible
with open("test.sh", "w") as f:
output = "#!/bin/sh\n"
output += cmd_h + ";" + cmd_v + " #\r" + cmd_v + " " * (len(cmd_h) + 3) + "\n"
f.write(output)
打开一个文本文件,然后写入两个指令,再写入 #\r
,再写入一个指令,并且在后面加了一些空格。
$ cat test.sh
#!/bin/sh
echo 'Hello world!'
可以看到,cat 的结果中缺失了很多,这是因为 cat 在接收到 \r
字符过后,自动回到了行首,然后用 echo 'Hello world!'
等内容替换前面的内容。
再之后,尝试手动执行下这个 test.sh
。
$ ls
test.sh
$ sh -x test.sh
+ echo 'You forgot to check `cat -A`!'
+ echo 'Hello world!'
Hello world!
$ ls
oops test.sh
$ cat oops
You forgot to check `cat -A`!
可以看到,虽然 cat 没看到内容,但是实际执行却会出现。
最后,有以下的方案判断 cat 是否隐藏了文本:
- 文件大小和展示的内容不匹配
- 通过编辑器,例如
vi
、vim
或者nano
去读取,而不是 cat - 或者使用
cat -A test.sh
(macOS下cat -e test.sh
)替代 cat,指定该选项不再渲染控制字符
$ cat -e test.sh
#!/bin/sh$
echo 'You forgot to check `cat -A`!' > oops;echo 'Hello world!' #^Mecho 'Hello world!' $
不幸的是,很多人从网上下载脚本,从来不去检查脚本做了那些事。有一小部分的人会使用 cat 去检查,而利用控制字符可以制造攻击。
从现在开始,为了安全着想,可以利用 less
去预览脚本内容。