TL; DR
shellshockの脆弱性は、
- 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のパーサーは依然としてのコードに露出されているかどうか関連している唯一の試験である任意の環境変数)。
詳細。
バグが5で導入されたエクスポート/インポート機能の初期の実装にあった番目のブライアン・フォックスにより1989年8月の、そして最初のbashは、セキュリティの前に、そのような広く普及していなかった時に、後に約一ヶ月の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 varsの関数をエクスポートします
foo=() {
code
}
そして、インポート時に行う必要があるのは=
、それをスペースで置き換えて解釈することだけです...ただし、盲目的に解釈してはいけません。
また、bash
(Bourneシェルとは反対に)スカラー変数と関数の名前空間が異なるという点で壊れています。実際に持っている場合
foo() { echo bar; }; export -f foo
export foo=bar
bash
両方を環境に喜んで配置します(同じ変数名のエントリ)が、多くのツール(多くのシェルを含む)はそれらを伝播しません。
また、bashはBASH_
bashからbashにのみ関連するenv変数であるため、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はすべて次のパッチで修正されましたが、Red Hatは強化修正をプッシュしました。彼らのパッチでは、動作を変更して、BASH_FUNC_myfunc()
多かれ少なかれChetの設計決定を先取りする変数で関数がエクスポートされるようにしました。
Chetは後に、その修正を公式のアップストリームbashパッチとして公開しました。
その強化パッチ、またはその変形版は現在、ほとんどの主要なLinuxディストリビューションで利用でき、最終的にはApple OS / X向けになりました。
これにより、後にMichałZalewski(CVE-2014-6278がほぼ公開された)CVE-2014-6271と同じくらい悪い)ありがたいことに、ほとんどの人が強化パッチをインストールする時間があった
パーサーのバグも同様に修正されますが、パーサーが信頼できない入力にさらされにくくなったので、もはやそれほど大きな問題ではなくなりました。
セキュリティの脆弱性は修正されましたが、その領域でいくつかの変更が行われる可能性が高いことに注意してください。CVE-2014-6271のための最初の修正は、それはしてインポート機能を停止中にいることを、下位互換性壊れている.
か、:
または/
自分の名前にします。これらはまだbashによって宣言できますが、一貫性のない動作になります。持つ関数なので.
と:
自分の名前には、一般的に使用されている、それはパッチは、環境から少なくともそれらを受け入れて復元されます可能性があります。
なぜ以前に見つからなかったのですか?
それも私が疑問に思ったものです。いくつかの説明を提供できます。
まず、セキュリティ研究者(および私はプロのセキュリティ研究者ではない)が特にbashの脆弱性を探していた場合、彼らはそれを見つけた可能性が高いと思います。
たとえば、私がセキュリティ研究者である場合、私のアプローチは次のようになります。
- どこ
bash
から入力を取得し、それが何をするかを見てください。そして、環境は明らかです。
bash
インタープリターが呼び出される場所とデータを調べます。繰り返しますが、それは際立っています。
- エクスポートされた関数のインポート
bash
は、setuid / setgidの場合に無効にされる機能の 1つであり、これにより、さらに見やすい場所になります。
さて、私は誰もbash
(通訳者)を脅威とみなしたり、脅威がそのようになったとは考えていなかったと思います。
bash
インタープリターは、信頼できない入力を処理するためのものではありません。
シェルスクリプト(インタープリターではない)は、セキュリティの観点からよく見られます。シェル構文は非常に厄介であり、信頼できるスクリプトを書くことには非常に多くの警告があります(私や他の人がsplit + glob演算子について言及しているのか、なぜ変数を引用する必要があるのでしょうか?)信頼できないデータ。
そのため、CGIシェルスクリプトを記述するべきではない、またはほとんどのUnicesでsetuidスクリプトが無効になっているとよく耳にします。または、誰でも書き込み可能なディレクトリ内のファイルを処理する場合は、特に注意する必要があります(たとえば、CVE-2011-0441を参照)。
インタプリタではなく、シェルスクリプトに焦点が当てられています。
シェルインタープリターを信頼できないデータに公開する(解釈するシェルコードとして外部データを供給する)ことによりeval
、.
またはユーザーが提供したファイルで呼び出すか、またはそれbash
を悪用する脆弱性は必要ありません。シェルに非サニタイズデータを渡して解釈する場合、それが解釈されることは明らかです。
したがって、シェルは信頼されたコンテキストで呼び出されます。解釈するための固定スクリプトが与えられており、(信頼性の高いスクリプトを書くのは非常に難しいため)しばしば処理する固定データがあります。
たとえば、Webコンテキストでは、シェルは次のように呼び出されます。
popen("sendmail -oi -t", "w");
それで何がうまくいかないのでしょうか?何か問題が想定される場合、それはそのsendmailに送られるデータに関するものであり、そのシェルコマンドライン自体の解析方法や、そのシェルに送られる追加データに関するものではありません。そのシェルに渡される環境変数を検討する理由はありません。そして、そうすれば、名前が "HTTP_"で始まるすべてのenv変数であるSERVER_PROTOCOL
かQUERYSTRING
、シェルまたはsendmailと関係のないCGI env変数がよく知られているか、まったく関係ないことがわかります。
setuid / setgidを実行するときやsudoを使用するときのような権限昇格コンテキストでは、環境が一般的に考慮され、過去にも多くの脆弱性がありました。これもシェル自体ではなく、権限を昇格するものsudo
(たとえばCVEを参照)-2011-3628)。
たとえばbash
、setuidまたはsetuidコマンドによって呼び出されたときに環境を信頼しません(mount
たとえば、ヘルパーを呼び出すと考えてください)。特に、エクスポートされた関数は無視されます。
sudo
ないように設定されている場合、少なくともブラックリスト、(のようなシェルまたは他に影響を与えることが知られているいくつかのすべてのホワイトリストを除いて、デフォルトでは、と:環境をきれいんPS4
、BASH_ENV
、SHELLOPTS
...)を。また、コンテンツが始まる環境変数をブラックリストに登録します()
(これが、CVE-2014-6271がを介した権限昇格を許可しない理由sudo
です)。
しかし、これも環境が信頼できないコンテキストの場合です。任意の名前と値を持つ変数は、そのコンテキストの悪意のあるユーザーが設定できます。これは、Webサーバー/ ssh、または環境が制御されている(少なくとも環境変数の名前が制御されている...)CVE-2014-6271を悪用するすべてのベクトルには適用されません。
シェルスクリプトやコマンドラインからコマンドとして呼び出されることはないためecho="() { evil; }"
、などの変数をブロックすることは重要ですが、そうHTTP_FOO="() { evil; }"
でHTTP_FOO
はありません。そして、apache2はecho
or BASH_ENV
変数を決して設定しません。
これはかなり明らかだいくつかの環境変数が自分に基づいて、いくつかの場面でブラックリストする必要があります名前、誰も、彼らはに基づいて、ブラックリストされなければならないことを考えていないコンテンツ(を除きますsudo
)。または言い換えれば、任意のenv varsがコードインジェクションのベクトルになり得るとは誰も考えませんでした。
機能が追加されたときの広範なテストがそれをキャッチできたかどうかに関して、私はそれがありそうにないと思います。
機能をテストするとき、機能をテストします。機能は正常に動作します。あるbash
呼び出しで関数をエクスポートした場合、別の呼び出しでインポートされます。非常に徹底的なテストでは、同じ名前の変数と関数の両方がエクスポートされる場合、または関数がエクスポートされたロケールとは異なるロケールでインポートされる場合に問題を発見できました。
しかし、脆弱性を見つけることができるためには、あなたがしなければならなかった機能テストではありません。セキュリティの側面に主眼を置く必要があり、機能をテストするのではなく、メカニズムとその悪用方法をテストします。
開発者(特に1989年)が心の奥底にいることはよくありません。シェル開発者は、自分のソフトウェアがネットワークで悪用される可能性は低いと考えるのは許されるでしょう。