web-dev-qa-db-ja.com

Set-uidスクリプトラッパー、 `system(3)` ShellshockおよびBash Function Import from Environment

与えられた非特権ユーザーに特権機能への制限付きアクセスを許可することは頻繁に必要である:Jobbing sysadminsは時々これをsetuidラッパー、次のように:

int main()
{
   setuid( 0 );
   system( "/path/to/script.sh" );

   return 0;
}

(このアサーションの証拠は、お好みの検索エンジンで setuidスクリプトが機能していない を検索するか、または スタックオーバーフロー で検索して見つけることができます。セキュリティのアドバイスが難しい、またはあいまいすぎて、システム管理者が従えない場合は、別のソリューションが必要です。

これは単に無知ではないかもしれないことに注意してください。これだけを含むスクリプトが危険だと誰が予想するでしょうか。

#!/bin/bash
kill -HUP $(< /var/run/demonname.pid)

明らかに、その目的は、デーモン名に彼の構成ファイルを再度読み取るよう依頼することです。組み込みのbash(パスを使用しないでください)だけを呼び出し、環境を一度は参照しません。私の意見では、経験豊富なシステム管理者でさえ、この場合はsuidwrapperで問題ないと思っていても許される

以前に発見されたように、Shellshock、および(それがなくても)bashのFunction Import from Environment(FIE)機能は、権限昇格の脆弱性を引き起こします。

仮定して:

  • そのようなものがインストールに存在し、それらが存在することを知らない、そして
  • 新しいものが作成されると確実に想定できます...

次のことをお勧めします:

  • bashをダンプして、他の何かを永遠にそしてアーメンを使用しますか?
  • パッチbashでFIEを完全に削除 (「nuke from orbit」オプション)
  • この機能の使用が許可されているスクリプトのフルパスをホワイトリストに登録するためにパッチbashを使用しますか?
  • rootとして実行している場合、デフォルトで環境をクリアするためのsystemおよびpopenをパッチしますか? (人々はこれらの機能を使用すべきではありません)。
  • 誰かがsystemをrootとして呼び出すたびに管理者にメールを送信しますか?またはrootとしてシェルスクリプトを起動しますか?
  • または何?

言い換えれば、FIEは、システムの悪用以外の目的で本番環境で使用されますか?もしそうなら、それらの使用をホワイトリストに登録し、他の場所では禁止することができますか?できない場合は機能を削除

3
Ben

このようなsetuidラッパーは、スクリプトインタープリターが固定bash、未固定bash、またはその他のシェルであるかどうかに関係なく、危険です。その理由は、スクリプトインタープリターが多くの環境変数の影響を受けるためです。よく引用される犯罪者はPATHとIFSです。これがSudoが環境全体を正常な値にリセットする理由です(シェルの作成者は常に創造的であるため、いくつかの「既知の危険な」環境変数のブラックリストだけではセキュリティを実現できません。全体を削除する必要がありますロット)。

使いすぎるメタファーを悪用するために、FIEは氷山の一角にすぎず、船の船体を引き裂く実際の氷のブロックではありません。環境変数は問題です。これは、呼び出しを介して伝播する隠れた間接チャネルであり、さまざまな方法で機能に影響を与える可能性があるためです(たとえば、環境を通じて「デバッグモード」をアクティブにすることで、メモリ割り当てルーチンの動作を変更できます)。 setuidバイナリの場合、カーネルは最悪の場合(LDPRELOAD)をクリアしますが、実際には、LC_ *変数を除いて、すべての環境変数をクリアする必要があります(ロケール依存の動作を設定するため、さらには非常に議論の余地があります)。 。

もちろん、setuidバイナリが呼び出されるたびにカーネルにパッチを適用して環境をクリアすると、問題が発生します... OpenBSDでさえ、「すべてのセキュリティは私たちのものである」というスタンスにも関わらず、実際にそのような大幅な変更を実装することから遠ざかりました。代わりに、彼らは documentation に依存しています:

環境を信用しないでください!これには、PATH(修飾されていない名前のシステムを使用せず、execvpを使用しない)などの単純なものだけでなく、ロケール、タイムゾーン、termcapなどのより微妙な項目も含まれます。推移性に注意してください。完全な予防策を講じていても、直接呼び出すプログラムは必ずしもそうとは限りません。特権プログラムでシステムを使用しないでください。コマンドラインと制御された環境を構築し、execveを直接呼び出してください。 perlsecのmanページは、そのような問題についての良いチュートリアルです。

5
Tom Leek

私のラッパーは次のようになります:

int main()
{
   setuid( 0 );
   execve("/path/to/script.sh", "/path/to/script.sh", NULL );

   return 0;
}

/ bin/shがbashであっても、Shellshockできません。

0
Joshua