将文本从网站安全粘贴到终端的简单方法

信息安全 网页浏览器 终端
2021-09-04 13:52:31

众所周知,将文本从网站复制粘贴到终端非常危险的,因为它可能包含额外的文本、控制代码和换行符,这些在复制时不可见,但保存在粘贴缓冲区,如果粘贴到终端会导致恶意代码执行。

上述链接的网站包含以下 HTML 和 CSS:

<p class="codeblock">
  <!-- Oh noes, you found it! -->
  git clone
  <span style="position: absolute; left: -100px; top: -100px">/dev/null; clear; echo -n "Hello ";whoami|tr -d '\n';echo -e '!\nThat was a bad idea. Don'"'"'t copy code from websites you don'"'"'t trust!<br>Here'"'"'s the first line of your /etc/passwd: ';head -n1 /etc/passwd<br>git clone </span>
  git://git.kernel.org/pub/scm/utils/kup/kup.git
</p>

这呈现为git clone git://git.kernel.org/pub/scm/utils/kup/kup.git,但是当您突出显示并复制它时,它将多行粘贴到终端中,导致它们被执行:

git clone /dev/null; clear; echo -n "Hello ";whoami|tr -d '\n';echo -e '!\nThat was a bad idea. Don'"'"'t copy code from websites you don'"'"'t trust!
Here'"'"'s the first line of your /etc/passwd: ';head -n1 /etc/passwd
git clone git://git.kernel.org/pub/scm/utils/kup/kup.git

对于单行字符串,是否有任何简单、快速的方法来解决这个问题?例如,复制文本,将其粘贴到浏览器的搜索栏中,然后从那里复制似乎会删除所有换行符:

git clone /dev/null; clear; echo -n "Hello ";whoami|tr -d '\n';echo -e '!\nThat was a bad idea. Don'"'"'t copy code from websites you don'"'"'t trust!Here'"'"'s the first line of your /etc/passwd: ';head -n1 /etc/passwdgit clone git://git.kernel.org/pub/scm/utils/kup/kup.git

现在,您必须显式按 Enter 才能使代码执行,而将其粘贴到终端中的行为是不够的。这是防止这种攻击的所有变体的安全方法吗?

2个回答

您是否有可用的(GUI*)十六进制编辑器应用程序?其中大部分分为两个窗格:

  • 一个将原始字节显示为十六进制数字组,例如 48656C6C 6F20776F 726C642E
  • 一个显示在某些固定宽度字符编码(如 ASCII 或 ISO Latin-1)下的字节解释 Hello world.

将相关内容粘贴到十六进制编辑器的右侧(文本)。就像文本编辑器一样,它为您提供了所有字符的基本预览,这是一个很好的开始。但除了文本编辑器之外,它还有其他好处:

一个好的十六进制编辑器在左侧的字节和右侧的文本解释之间保持 1:1 的关系。因此,如果粘贴了不可打印的字符,您将能够看到间隙。对于可能用于在普通文本编辑器中隐藏内容的各种 Unicode 技巧也是如此。

因此,假设网站文本也不能利用您的特定十六进制编辑器(或编辑器使用的框架)中的错误,您可以获得更可靠的数据视图,以及解码任何可能已经存在的恶意包括!

*粘贴到基于终端的十六进制编辑器中也可能是安全的,但这似乎是一个单独的问答,深入探讨了应用程序如何将数据放到剪贴板、终端仿真器本身以及在终端内运行的进程面对例如控制代码和诸如此类的东西,所有这些都可以协同工作……。

我要写一个答案,因为评论会太长,即使我不确定这是你正在寻找的答案。

听起来您想要一种将代码粘贴到终端的快速方法,但我不明白为什么您在做显然非常危险的事情时要快速,这也是我认为(并希望)您的事情不会经常做。我的意思是,如果您信任源代码,您可以直接复制和粘贴代码,但既然您显然在谈论您不信任的源代码(并且可能使用“技巧”将代码隐藏在文本字符串中),为什么要这样做你甚至想快点您实际上应该想放慢速度。

在评论中,我建议使用文本编辑器检查字符串,但经过重新考虑和一些测试,我相信你甚至不能相信一般的文本编辑器。可以做什么取决于您使用的终端(模拟器)和您的文本编辑器。我的终端显然从命令行中删除了 ANSI 代码所需的转义字符,因此我不能使用“不可见文本”或在命令中移动光标(但当然可以在输出中执行此操作)。例如,无法粘贴以下命令,因为删除了 ANSI 代码:

# ESC is 0x1B, the first code sets invisible text, the last resets it
echo foobar; ESC[8m echo hacked!; ESC[0m

如果 ANSI 代码有效,则可以在命令末尾添加不可见代码,然后将光标移回以避免提示前的可疑空间。所有终端都这样吗?我不知道,但我认为我们不应该相信他们所有人。

我的终端还删除了 Unicode 字符 U+202E(从右到左覆盖)和 U+202D(从左到右覆盖)。这意味着结果可能与您看到和期望的不同。例如:

 # The following string will appear as "echo rm;"
 # when seen in an environment that interprets those chars
 echo\u202E;\u202D rm

 # However when you copy it and paste it to an environment
 # that strips those chars off (like my terminal), you will get:
 echo; rm

可能很难找到执行任意代码的技巧,并且您可以实现的目标可能有限,但这仍然表明事情可能会出错,并且换行符可能不是我们需要担心的唯一字符。

事实上,我们肯定需要担心的其他字符是非 ASCII 字符,它们在涉及 URL 时允许同形异义词攻击。今天所有的现代浏览器都会显示真实地址,但在终端中,恐怕在你按下回车之前无法知道你实际上要做什么:

# Here the first "e" is a Cyrillic letter
curl 'https://www.еxample.com'
Could not resolve host: www.xn--xample-2of.com

文本编辑器可能会或可能不会在所有情况下都有帮助(这取决于它可以显示什么以及它是如何设置的)。十六进制编辑器总是有帮助的,这可能是我的建议:将不受信任的代码保存在文件中,然后使用十六进制编辑器对其进行检查。另一个快速的解决方案可能是一个自定义脚本,它确保所有输入字符都是可打印的 ASCII 字符,如果不是,它会警告你。您可以xclip用于从剪贴板获取输入、grep检查输入(如果发现任何超出可打印 ASCII 范围的内容,则打印警告,否则打印输入正常的确认信息)notify-sendzenity显示桌面通知。配置一些键盘快捷键以轻松运行它。