不具合
CVE-2014-7169 は、bash のパーサーのバグです。Bash のパーサーは、変数eol_ungetc_lookahead
を使用して行をまたいで文字を取得します。その変数は、関数から適切にリセットされていませんでしたreset_parser
。たとえば、いくつかの構文エラーで呼び出されます。このバグを利用して、次の bash 入力行の先頭に文字を挿入することができます。
したがって、テスト コードは、 または のいずれ(a)=
かを使用して構文エラーを強制しfunction a a
、リダイレクト文字を次の行の先頭に>
追加し、行の継続を追加します\
。これにより、テスト コードのいずれかのバージョンが生成されます。
() { (a)=>\
() { function a a>\
bash が実行されると、環境から変数を処理し、変数X
がエクスポートされた関数であることを検出し、それを評価して関数をインポートします。しかし、評価は解析エラーで失敗し、変数に>
文字が残ります。eol_ungetc_lookahead
次に、コマンド引数 を解析するときに、echo date
先頭に>
文字を追加して、 という名前のファイルにリダイレクトして>echo date
実行します。date
echo
以前のバグとの関係
上記のバグは、元の shellshock バグとは明らかに大きく異なります。実際にはいくつかの問題があります。
- Bash は、エクスポートされた関数のように見える変数を完全に評価します (4 文字で始まります
() {
)。CVE-2014-6271。
- 状況によっては、文字を ungetc 変数に挿入して、次の入力行の先頭に追加することができます。CVE-2014-7169。
- Bash では、4 文字で始まる限り、すべての環境変数をエクスポートされた関数のように扱うことができます
() {
。CVE-2014-6271、CVE-2014-7169、bash のパーサーでバグがトリガーされる他のすべての CVE。
- ヒアドキュメント リダイレクトのスタックは制限されており、オーバーフローのチェックはありません。CVE-2014-7186 は、メモリの破損につながり、おそらく任意のコードの実行に利用される可能性があります。
select
ネストされた制御構造 ( / for
/ )のスタックには制限がありwhile
、オーバーフローのチェックが行われます。そのスタックはまだ破損しています。CVE-2014-7187。
修正
- 最初のパッチは、エクスポートされた関数のように見える各変数で単一の関数定義を評価するように bash を制限します。
- 2 番目のパッチは で正しくリセット
eol_ungetc_lookahead
されreset_parser
ます。
- 3 番目のパッチでは、関数のエクスポート方法が変更されました。現在は、 という名前の変数でエクスポートされます
BASH_FUNC_functionname%%
。
攻撃面
ここでの大きな問題は、すべての環境変数が攻撃のベクトルとして使用される可能性があることです。通常、攻撃者は任意の環境変数を制御することはできません。それ以外の場合は、他の既知の攻撃 ( LD_PRELOAD
、PATH
、IFS
、... など) が既に存在します。
sudo
Gilles が security.SE で述べているように、エクスポートされた bash 関数を環境から削除するため、影響を受けません。
ssh
影響を受けた。典型的な sshd インストールでは、環境変数の限定されたセットのみを、AcceptEnvで構成されているようにエクスポートできますsshd_config
(例:LANG
およびLC_*
. この積極的なホワイトリスト アプローチを使用しても、shellshock ではあらゆる変数が攻撃ベクトルになる可能性があります。
すべての環境変数が潜在的な攻撃ベクトルであるだけでなく、6000 行を超えるパーサーが公開されました。
再学習した教訓
system
、popen
、およびその他は潜在的に危険です。引数に注意するだけでなく、引数がコンパイル時に固定されている場合でも、環境は潜在的な攻撃ベクトルです。できればクリーンな環境で を使用fork()/execve()
してください (ただし、少なくとも環境をホワイトリストに登録された変数に制限し、できればそれらの値の健全性をチェックしてください)。高品質のシステムは本来の目的を果たしますが、安全なシステムは本来の目的を果たし、それ以上のことはしないということを忘れないでください。本格的なシェルを呼び出すと、何もしないことが少し難しくなります。
複雑さはセキュリティの敵です。最近では、よりシンプルなシェルを推奨する人を簡単に見つけることができます。ほとんどのシェルは、エクスポートされた関数をまったくサポートしていないため、シェルショックから解放されています。逆に、bash は何年にもわたって多くのセキュリティ機能を獲得してきました (起動時に特権を落とさないようにするには、で呼び出す必要があり、-p
IFS をサニタイズします...)、シェルの切り替えを推奨しているとは思わないでください。より一般的なアドバイスです。
環境変数に関するDavid Wheeler の古い「Linux および UNIX HOWTO のセキュア プログラミング」の章からの抜粋は、今でも読む価値があります。
§5.2.3 ¶1:
セキュリティで保護された setuid/setgid プログラムの場合、入力 (存在する場合) として必要な環境変数の短いリストを慎重に抽出する必要があります。次に、環境全体を消去してから、必要な環境変数の小さなセットを安全な値にリセットする必要があります。従属プログラムを呼び出す場合、これ以上の方法はありません。「すべての危険な値」を一覧表示する実用的な方法はありません。
§5.2.3 ¶6:
ユーザー指定の値が本当に必要な場合は、最初に値を確認します (値が正当な値のパターンに一致し、妥当な最大長の範囲内にあることを確認します)。