env x='() { ::};どういう意味ですか? bashコマンドは何をし、なぜ安全ではないのですか?

env x='() { ::};どういう意味ですか? bashコマンドは何をし、なぜ安全ではないのですか?

Bashには明らかに脆弱性(CVE-2014-6271)があります。Bash特別に作成された環境変数コード注入攻撃

私は何が起こっているのかを理解しようとしていますが、私がそれを理解しているかどうかは完全にはわかりません。echo一重引用符でどのように処理しますか?

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test

編集1:パッチされたシステムは次のとおりです。

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
this is a test

編集2:関連する脆弱性/パッチがあります。CVE-2014-7169わずかに異なるテストを使用してください。

$ env 'x=() { :;}; echo vulnerable' 'BASH_FUNC_x()=() { :;}; echo vulnerable' bash -c "echo test"

パッチされていない出力:

vulnerable
bash: BASH_FUNC_x(): line 0: syntax error near unexpected token `)'
bash: BASH_FUNC_x(): line 0: `BASH_FUNC_x() () { :;}; echo vulnerable'
bash: error importing function definition for `BASH_FUNC_x'
test

部分(旧バージョン)パッチ出力:

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
bash: error importing function definition for `BASH_FUNC_x()'
test

パッチ出力CVE-2014-7169まで:

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `BASH_FUNC_x'
test

編集3:物語は続きます:

ベストアンサー1

bashは、エクスポートされた関数定義を環境変数として保存します。エクスポートされた関数は次のとおりです。

$ foo() { bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() {  bar
}

つまり、環境変数にはfooリテラルコンテンツがあります。

() {  bar
}

Bashの新しいインスタンスが起動したら、特別に作成された環境変数を見つけて関数定義として解釈します。自分で書いて、まだ機能していることを確認することもできます。

$ export foo='() { echo "Inside function"; }'
$ bash -c 'foo'
Inside function

残念ながら、文字列(環境変数)から関数定義を解析すると、予想よりも広範な影響を与える可能性があります。パッチが適用されていないバージョンでは、関数定義が終了した後に発生する任意のコマンドも解釈されます。これは、環境で許容される関数型文字列を決定するのに制約がないためです。たとえば、

$ export foo='() { echo "Inside function" ; }; echo "Executed echo"'
$ bash -c 'foo'
Executed echo
Inside function

bashの起動中に関数定義の外側のエコーが予期せず実行されることに注意してください。関数定義は評価と利用の一段階に過ぎません。関数定義自体と使用される環境変数は任意です。シェルは、foo自分が知っている関数定義の制約を満たすと思われる環境変数seesを調べて行を評価し、誤ってecho(悪意があるかどうかにかかわらず任意のコマンドである可能性があります)を実行します。

変数自体は通常許可されていないか、またはその中に含まれる任意のコードを直接呼び出すことは期待されていないため、これは安全ではないと見なされます。たぶん、プログラムは信頼できないユーザー入力に基づいて環境変数を設定できます。驚くべきことに、これらの環境変数は、コードに記載されている理由で、環境変数を使用して明示的な意図なしにユーザーが任意のコマンドを実行できるように操作できます。

これは可能な攻撃の例です。あなたが実行しているWebサーバーは、ライフサイクルの一部としてどこかで脆弱なシェルを実行します。 Web サーバーは環境変数を bash スクリプトに渡します。たとえば、CGI を使用する場合、HTTP 要求に関する情報は通常、Web サーバーの環境変数として含まれます。たとえば、HTTP_USER_AGENTユーザーエージェントに設定できる項目です。これは、ユーザーエージェントを'(){::}; echo foo 'のようななりすましは、シェルスクリプトがecho foo実行されることを意味します。繰り返しますが、echo foo悪意があるかどうかは何でもあります。

おすすめ記事