3

(注: Linux を念頭に置いていますが、問題は他のプラットフォームにも当てはまる可能性があります。)

問題: Linux は #! で suid を実行しません。スクリプトの「Linux 機能」を有効にすることもありません。

なぜ私たちはこの問題を抱えているのでしょうか? スクリプトを実行するためのカーネル インタープリターのセットアップ中に、攻撃者がそのファイルを置き換えた可能性があるためです。どのように?以前信頼されていた suid/capability-enabled スクリプト ファイルは、管理者が制御できるディレクトリにある可能性があります (たとえば、所有されていない信頼されたファイルを削除したり、ファイルが実際に所有しているシンボリック リンクである場合)。

適切な解決策: 次の場合に、カーネルで suid/cap スクリプトを許可するようにします。a) 呼び出し元がスクリプト ファイルに対して権限を持っていないことが明らかな場合、または他のいくつかのオペレーティング システムが行うように、b) スクリプトを /dev/fd/ として渡します。 x、最初にカーネルで開かれた信頼できるファイルを参照します。

私が探している答え:これを実行できないカーネル (すべての Linux) については、安全な「今」のソリューションが必要です。

私は何を考えていますか?カーネルが実行しないことを安全な方法で実行するバイナリ ラッパー。

私はしたいと思います

  1. Linux の機能を渡す (Python) スクリプトの確立されたラッパーから聞いて、スクリプト ファイルからインタープリターに suid してそれらを有効にする可能性があります。
  2. 以下で提案された私のラッパーにコメントを得る

sudo に関する問題: sudo は適切なラッパーではありません。これは、先ほど説明した「スクリプトが置き換えられた」というトラップにカーネルが陥らないようにするのに役立たないためです (警告の下の「man sudo」はそう言っています)。


提案されたラッパー

  • 実際には、ラッパーを生成する小さなプログラムが必要です
    • コマンドライン、例: sudo suid_capability_wrapper ./script.py
    • script.py には既に suid ビットと機能が設定されています (機能はなく、情報のみ)
  • ジェネレータ suid_capability_wrapper が行う
    • C(?) ソースを生成してコンパイルする
    • 出力を次のようにコンパイルします: default: basename script.py .py、または引数 -o
    • ラッパーの所有者、グループ、suid を script.py のように設定します
    • script.py のような許可された機能を設定し、継承可能な有効なキャップを無視します
    • インタープリター (例: /usr/bin/python) の継承可能なセットに対応するキャップがない場合に警告します (これはシステムの制限です: それ以外の場合、suid-root なしでケーパビリティーを渡す方法はありません)。
  • 生成されたコードは次のことを行います。
    • ファイル記述子 0、1、および 2 が開いているかどうかを確認し、そうでない場合は中止します (あまりにもクレイジーな環境条件のチェックを追加する可能性があります)。
    • コンパイルされたターゲット スクリプトが相対パスでコンパイルされている場合、/proc/self/exe を介して自分自身の場所を特定します
    • 自分のパスとスクリプトへの相対パスを組み合わせて見つけます
    • ターゲット スクリプトの所有者、グループ、パーミッション、caps、suid がオリジナル (コンパイル済み) のままかどうかを確認します [これは、含めたい唯一の不要な安全チェックです: それ以外の場合は、そのスクリプトを信頼します]
    • 許可された機能のセットと等しい継承された機能のセットを設定します
    • execve() インタープリターはカーネルと同様ですが、既知のスクリプトパスと取得した環境を使用します (スクリプトは環境を処理する必要があります)。

suid_capability_wrapper によって一連のメモと警告が出力され、ユーザーに次の情報が表示される場合があります。

  • 誰もスクリプトを操作できないようにする (例: 誰でも書き込み可能)
  • suid/capabilities はラッパーから取得されることに注意してください。スクリプト ファイルの suid/xattr マウントについては何も気にしません。
  • インタープリター (python) が execve() され、ここからダーティな環境が取得されます
  • また、それを通過する標準プロセス環境の残りの部分も取得します。これは ... ... ... (最初に exec のマンページを読んでください)
  • #!/usr/bin/python -E を使用して、環境変数から Python インタープリターを免疫化します
  • スクリプトで自分で環境をきれいにするか、これらの変数のいくつかを気にする副作用として実行するコードがたくさんあることに注意してください
4

1 に答える 1

0

どのファイルでも、シバンをまったく使用したくありません。Pythonインタープリターを呼び出すバイナリを使用し、要求したスクリプトファイルを開始するように指示します。

それは3つのことをする必要があります:

  • Pythonインタープリターを起動します(信頼できるパスから、chroot jailを壊すなど)。libpythonを静的にリンクし、これにCPython APIを使用することをお勧めしますが、それはあなた次第です。
  • スクリプトファイルFDを開き、それがsuidであり、rootによって所有されていることをアトミックに確認します。チェックと実行の間にファイルが変更されないようにしてください。注意してください。
  • 以前に開いたFDからスクリプトを実行するようにCPythonに指示します。

これにより、Pythonでのみrootとsuidが所有するすべてのスクリプトを実行するバイナリが提供されます。このようなプログラムは、スクリプトごとに1つではなく、1つだけ必要です。それはあなたの「suidpythonrunner」です。

ご想像のとおり、Pythonを実行する前に環境をクリアする必要があります。LD_LIBRARY_PATHカーネルによって処理されますが、PYTHONPATH致命的となる可能性があります。

于 2012-02-11T19:02:43.553 に答える