バグに関するコンテキスト:CVE-2014-6271
Bashは、シェル変数だけでなく、シェル関数を他のbashインスタンスに、プロセス環境を介して
の環境変数設定
(間接)子プロセスにエクスポートすることもサポートしています。現在のbashバージョンでは、関数名で指定された環境変数と、変数値の「(){」で始まる関数定義
を使用して、
関数定義を環境全体に伝播します。この脆弱性は、
関数定義の処理後にbashが停止しないために発生します。
は、関数の定義に従って
シェルコマンドの解析と実行を続行します。たとえば、VAR=() { ignored; }; /bin/id
環境がbash
プロセスにインポートされるときに/bin/idを実行します。
出典:http://seclists.org/oss-sec/2014/q3/650
バグが発生したのはいつですか。それを完全に修正するパッチは何ですか? (CVE-2014-7169を参照)
CVEに記載されている以上の脆弱なバージョンは何ですか(最初は)(3.{0..2}および4.{0..3})?
バグのあるソースコードは他のプロジェクトで再利用されていますか?
追加情報が望ましいです。
関連:env x ='(){:;};コマンドのbashは実行し、なぜ安全ではないのですか?
承認された回答:
TL; DR
シェルショックの脆弱性はで完全に修正されています
- bash-2.05bブランチの場合:2.05b.10以降(パッチ10を含む)
- bash-3.0ブランチの場合:3.0.19以降(パッチ19を含む)
- bash-3.1ブランチの場合:3.1.20以降(パッチ20を含む)
- bash-3.2ブランチの場合:3.2.54以降(パッチ54を含む)
- bash-4.0ブランチの場合:4.0.41以降(パッチ41を含む)
- bash-4.1ブランチの場合:4.1.14以降(パッチ14を含む)
- bash-4.2ブランチの場合:4.2.50以降(パッチ50を含む)
- bash-4.3ブランチの場合:4.3.27以降(パッチ27を含む)
bashに古いバージョンが表示されている場合でも、OSベンダーが独自にパッチを適用している可能性があるため、確認することをお勧めします。
場合:
env xx='() { echo vulnerable; }' bash -c xx
「脆弱」を示していますが、まだ脆弱です。これが関連する唯一のテストです(bashパーサーがいずれかののコードにまださらされているかどうか 環境変数)。
詳細。
このバグは、1989年8月5日にBrian Foxによって導入された関数のエクスポート/インポートの最初の実装にあり、セキュリティが確立される前の、bashがそれほど普及していなかった約1か月後にbash-1.03で最初にリリースされました。それだけの懸念があり、HTTPとWebまたはLinuxも存在していました。
1.05のChangeLogから:
Fri Sep 1 18:52:08 1989 Brian Fox (bfox at aurel) * readline.c: rl_insert (). Optimized for large amounts of typeahead. Insert all insertable characters at once. * I update this too irregularly. Released 1.03. [...] Sat Aug 5 08:32:05 1989 Brian Fox (bfox at aurel) * variables.c: make_var_array (), initialize_shell_variables () Added exporting of functions.
その頃のgnu.bash.bugとcomp.unix.questionsのいくつかの議論でも、この機能について言及しています。
どうやってそこにたどり着いたのかを理解するのは簡単です。
bashは、次のようなenv変数の関数をエクスポートします
foo=() {
code
}
そしてインポート時に、それがしなければならないのは =
でそれを解釈することだけです スペースに置き換えられました…それが盲目的にそれを解釈してはならないことを除いて。
bash
でも壊れています (Bourneシェルとは異なり)、スカラー変数と関数の名前空間は異なります。実際に持っている場合
foo() { echo bar; }; export -f foo
export foo=bar
bash
両方を環境にうまく配置しますが(同じ変数名のエントリはあります)、多くのツール(多くのシェルを含む)はそれらを伝播しません。
また、bashは BASH_
を使用する必要があると主張する人もいます。 その環境変数はbashからbashにのみ関連するため、その名前空間プレフィックス。 rc
fn_
を使用します 同様の機能のプレフィックス。
それを実装するためのより良い方法は、エクスポートされたすべての変数の定義を次のような変数に入れることでした:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
それでもサニタイズする必要がありますが、少なくとも $ BASH_ENV
よりも悪用されることはありません。 または$SHELLOPTS
…
bash
を防ぐパッチがあります そこにある関数定義(https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html)以外のものを解釈することから、それはすべてのセキュリティに適用されているものですさまざまなLinuxディストリビューションからのアップデート。
ただし、bashはまだそこにあるコードを解釈し、インタープリターのバグが悪用される可能性があります。そのようなバグの1つはすでに発見されていますが(CVE-2014-7169)、その影響ははるかに小さいです。そのため、まもなく別のパッチが提供されます。
bashが任意の変数のコードを解釈できないようにする強化修正まで( BASH_FUNCDEFS
の使用など) 上記のアプローチ)、bashパーサーのバグに対して脆弱でないかどうかはわかりません。そして、遅かれ早かれそのような強化修正がリリースされると私は信じています。
編集2014-09-28
パーサーに2つの追加のバグが見つかりました(CVE-2014-718 {6,7})(ほとんどのシェルは、コーナーケースのパーサーにバグがあることに注意してください。そのパーサーがなかった場合、それは問題になりませんでした。信頼できないデータにさらされていません。
次のパッチでは、3つのバグ7169、7186、および7187がすべて修正されていますが、RedHatは強化の修正を要求しました。彼らのパッチでは、関数が BASH_FUNC_myfunc()
と呼ばれる変数にエクスポートされるように動作を変更しました。 チェットの設計上の決定を多かれ少なかれ先取りします。
Chetは後に、その修正を公式のアップストリームbashパッチとして公開しました。
その強化パッチまたはそのバリアントは、現在ほとんどの主要なLinuxディストリビューションで利用可能であり、最終的にはApple OS/Xになりました。
これにより、後でMichałZalewskiによって開示されたパーサー(CVE-2014-627 {7,8})の他の2つの脆弱性(CVE-2014-6278はほぼCVE-2014-6271と同じくらい悪い)ありがたいことに、ほとんどの人が強化パッチをインストールする時間があった後
パーサーのバグも修正されますが、パーサーが信頼できない入力に簡単にさらされることがなくなったため、それほど問題にはなりません。
セキュリティの脆弱性は修正されていますが、その領域でいくつかの変更が行われる可能性があることに注意してください。 CVE-2014-6271の初期修正により、を使用した関数のインポートが停止するという下位互換性が失われました。
または:
または/
彼らの名前で。それらはまだbashによって宣言できますが、これは一貫性のない動作になります。 。
で機能するため および:
それらの名前で一般的に使用されているので、パッチは少なくとも環境からのものを受け入れて復元する可能性があります。
なぜ以前に見つからなかったのですか?
それも私が疑問に思ったことです。いくつか説明させていただきます。
まず、セキュリティ研究者(そして私はプロのセキュリティ研究者ではありません)がbashの脆弱性を特に探していたとしたら、彼らはそれを見つけた可能性が高いと思います。
たとえば、私がセキュリティ研究者だった場合、私のアプローチは次のようになります。
-
bash
の場所を見てください から入力を取得し、それをどのように処理するか。そして、環境は明らかです。 -
bash
の場所を確認してください インタプリタが呼び出され、どのデータに対して。繰り返しますが、それは際立っています。 - エクスポートされた関数のインポート
bash
のときに無効になる機能の1つです setuid / setgidであるため、さらにわかりやすく表示されます。
さて、 bash
を検討する人は誰もいないと思います (通訳)脅威として、または脅威がそのように来た可能性があること。
bash
インタプリタは、信頼できない入力を処理するためのものではありません。
シェルスクリプト (通訳ではなく)セキュリティの観点からよく見られます。シェルの構文は非常に扱いにくく、信頼できるスクリプトを作成する際の注意点が非常に多いため(split + glob演算子について言及している私や他の人、または変数を引用する必要がある理由など)、処理するスクリプトでセキュリティの脆弱性を見つけることは非常に一般的です。信頼できないデータ。
そのため、CGIシェルスクリプトを記述すべきではない、またはほとんどのUnicesでsetuidスクリプトが無効になっているとよく耳にします。または、誰でも書き込み可能なディレクトリ内のファイルを処理する場合は、特に注意する必要があります(たとえば、CVE-2011-0441を参照)。
焦点は、インタープリターではなく、シェルスクリプトにあります。
eval
を介して、シェルインタープリターを信頼できないデータに公開できます(外部データをシェルコードとしてフィードして解釈します)。 または。
またはユーザー提供のファイルで呼び出すが、 bash
に脆弱性は必要ありません それを悪用する。シェルが解釈するためにサニタイズされていないデータを渡す場合、それが解釈されることは非常に明白です。
したがって、シェルは信頼できるコンテキストで呼び出されます。解釈するための固定スクリプトが与えられ、多くの場合(信頼できるスクリプトを書くのが非常に難しいため)処理するための固定データが与えられます。
たとえば、Webコンテキストでは、シェルは次のようなもので呼び出される可能性があります。
popen("sendmail -oi -t", "w");
何がうまくいかない可能性がありますか?何か問題が想定される場合、それはそのsendmailに供給されるデータに関するものであり、そのシェルコマンドライン自体の解析方法やそのシェルに供給される追加のデータに関するものではありません。そのシェルに渡される環境変数を検討する理由はありません。そうすると、名前が「HTTP_」で始まるすべてのenv変数であるか、 SERVER_PROTOCOL
のようなよく知られているCGIenv変数であることがわかります。 またはQUERYSTRING
シェルやsendmailはどれも関係ありません。
setuid / setgidを実行する場合やsudoを介する場合などの特権昇格のコンテキストでは、環境が一般的に考慮され、過去にも多くの脆弱性がありました。これもシェル自体に対してではなく、sudo<などの特権を昇格させるものに対してです。 / code> (たとえば、CVE-2011-3628を参照してください)。
たとえば、 bash
setuidまたはsetuidコマンドによって呼び出されたときに環境を信頼しません( mount
を考えてください) たとえば、ヘルパーを呼び出します)。特に、エクスポートされた関数は無視されます。
sudo
環境をクリーンアップします:ホワイトリストを除いてすべてデフォルトで、設定されていない場合は、少なくともシェルまたは別のシェルに影響を与えることがわかっているいくつかのブラックリスト( PS4
など) 、 BASH_ENV
、 SHELLOPTS
…)。また、コンテンツの環境変数をブラックリストに登録します。 ()
で始まります (これが、CVE-2014-6271が sudo
による特権の昇格を許可しない理由です。 。
ただし、これは環境を信頼できないコンテキストの場合です。名前と値が任意の変数は、そのコンテキスト内の悪意のあるユーザーによって設定される可能性があります。これは、環境が制御されている(少なくとも環境変数の名前が制御されている)CVE-2014-6271を悪用するWebサーバー/SSHまたはすべてのベクターには適用されません
echo ="(){evil;}"
のような変数をブロックすることが重要です 、ただし HTTP_FOO ="(){evil;}"
ではありません 、 HTTP_FOO
シェルスクリプトやコマンドラインからコマンドとして呼び出されることはありません。そして、apache2が echo
を設定することは決してありません またはBASH_ENV
変数。
非常に明白ないくつか 一部のコンテキストでは、環境変数を名前に基づいてブラックリストに登録する必要があります。 、しかし、コンテンツに基づいてブラックリストに載せるべきだとは誰も考えていませんでした。 ( sudo
を除く )。言い換えれば、任意のenv変数がコードインジェクションのベクトルになるとは誰も考えていませんでした。
機能が追加されたときの大規模なテストでそれを捕らえることができたかどうかについては、ありそうもないと思います。
機能をテストするとき 、機能をテストします。機能は正常に動作します。関数を1つのbash
でエクスポートする場合 呼び出し、それは別のものに問題なくインポートされます。非常に徹底的なテストにより、同じ名前の変数と関数の両方がエクスポートされた場合、または関数がエクスポートされたロケールとは異なるロケールにインポートされた場合に、問題が発見される可能性があります。
しかし、脆弱性を見つけることができるようにするために、それはあなたがしなければならなかったであろう機能テストではありません。セキュリティの側面を主な焦点にする必要があり、機能をテストするのではなく、メカニズムとその悪用方法をテストする必要がありました。
これは、開発者(特に1989年)がしばしば頭に浮かぶものではなく、シェル開発者は、自分のソフトウェアがネットワークで悪用される可能性は低いと考えることを許される可能性があります。