Shellshockのバグについてbashシェルを確認するために使用したコマンドは次のとおりです。
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
誰でもコマンドを詳細に説明できますか?
この回答は Fedora Magazineのオリジナル記事 Matthew Millerによる派生物であり、 Creative Commons Attribution-Share Alike 4. ライセンスの下でライセンスされています。
説明させてください:
env x='() { :;}; echo OOPS' bash -c :
これは、脆弱なシステム上で「OOPS」を出力しますが、bashにパッチが適用されている場合はサイレントに終了します。
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
これは、脆弱なシステムでは「OOPS」を出力しますが、bashにパッチが適用されている場合は“this is a test”
を出力します。
そして、おそらく環境変数と関係があると聞いたことがあるでしょう。しかし、なぜ環境変数のコードが実行されるのですか?まあ、それは想定されていません-しかし、私は自分自身の利益のために少し賢すぎると呼びたがっている機能のために、いくつかの欠陥の余地があります。 Bashはターミナルプロンプトとして表示されますが、スクリプト言語でもあり、関数を定義する機能があります。あなたはこのようにします:
$ Ubuntu() { echo "Ubuntu is awesome."; }
そして、新しいコマンドがあります。ここのecho
は実際にはまだ実行されていないことに注意してください。新しいコマンドを実行すると何が起こるかとして保存されています。これはすぐに重要になります!
$ Ubuntu
Ubuntu is awesome.
有用!しかし、何らかの理由で、サブプロセスとしてbashの新しいインスタンスを実行し、その下で素晴らしい新しいコマンドを実行する必要があるとしましょう。ステートメントbash -c somecommand
はまさにこれを行います:新しいシェルで与えられたコマンドを実行します:
$ bash -c Ubuntu
bash: Ubuntu: command not found
ああ悲しい。子は関数定義を継承しませんでした。しかし、それは環境に固有のものです-シェルからエクスポートされたキーと値のペアのコレクション。 (これは完全な「より重要な概念です。これに慣れていない場合は、今のところ私を信頼してください。」そして、bashは関数をエクスポートすることもできます。そう:
$ export -f Ubuntu
$ bash -c Ubuntu
Ubuntu is awesome.
これはすべてうまくいきます。ただし、これを実現するメカニズムはsorta dodgyです。基本的に、環境変数で関数を実行するためのLinux/Unixマジックはないため、エクスポート関数は実際には関数定義を含む通常の環境変数を作成するだけです。次に、2番目のシェルが「着信」環境を読み取り、関数のように見えるコンテンツを持つ変数に遭遇すると、それを評価します。
理論的には、これは完全に安全です。なぜなら、関数を定義しても実際には実行されないからです。ただし、これが私たちがここにいる理由です。コードにバグがあり、関数定義の最後に達しても評価が停止しませんでした。ただ動き続けた。
環境変数に格納された関数がexport -f
で正当に作成された場合、それは決して起こりません。しかし、なぜ合法ですか?攻撃者は古い環境変数を作成することができ、関数のように見える場合、新しいbashシェルはそれを考えます!
したがって、最初の例では:
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
env
コマンドは、指定された変数セットでコマンドを実行します。この場合、x
を関数のように見えるものに設定しています。この関数は、単一の:
であり、実際には何もしないと定義されている単純なコマンドです。しかし、その後、semi-colon
の後に関数定義の終了を知らせるecho
コマンドがあります。そこにあることは想定されていませんが、それを妨げるものは何もありません。
次に、この新しい環境で実行するために指定されたコマンドは新しいbashシェルであり、「echo this is a test
」または「do nothing :
」コマンドを使用します。その後、完全に無害に終了します。
しかし—おっと!その新しいシェルが起動して環境を読み取ると、x
変数に到達し、関数のように見えるため、それを評価します。関数定義は無害にロードされます-そして、悪意のあるペイロードもトリガーされます。したがって、脆弱なシステムで上記を実行すると、“OOPS”
が表示されます。または、攻撃者は単に物事を印刷するよりもはるかに悪いことをする可能性があります。
bash
のパッチ未適用バージョンでは、エクスポートされた関数定義を環境変数として保存します。
関数x
を次のように保存します。
$ x() { bar; }
$ export -f x
そして、その定義を確認してください、
$ env | grep -A1 x
x=() { bar
}
したがって、独自の環境変数を定義してこれを利用し、関数定義として解釈することができます。たとえば、env x='() { :;}'
は次のように扱われます
x() { :;
}
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
man env
から、
env
-変更された環境でプログラムを実行します。
:
は何もせずに終了ステータス0
で終了します。 more を参照してください
パッチが適用されていないbashの新しいインスタンスがbash -c "echo this is a test"
として起動されると、細工された環境変数は関数として扱われ、ロードされます。したがって、出力が得られます
脆弱性 これはテストです
注:関数定義外のエコーは、bashの起動中に予期せず実行されました。関数定義は、評価と悪用を行うための単なるステップであり、関数定義自体と使用される環境変数は任意です。シェルは環境変数を調べ、xを見て、関数定義がどのようなものかを知っている制約を満たしているように見え、行を評価します。 。 this も参照してください