18

bashは、共通のライブラリを持つユーティリティのコレクションを書いています。私が作成する各スクリプトには、実行可能ファイルに対するライブラリの相対パスを決定するコード ブロックが必要です。実際のコードではありませんが、例:

#!/bin/bash

DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. $DIR/../lib/utilities/functions

ライブラリを検索しようとするプリアンブルの代わりに、環境変数を使用してライブラリの場所を示すという優れたアイデアを思いつきました。

#!/bin/bash

. $TOOLS_LIBRARY_PATH

ラッパー プログラムを使用してその環境変数を設定することも、独自のパスに設定することもできます。bashツールセットを整理するより良い方法があるかもしれませんが、問題は次のとおりです。

自分の環境変数を信頼できますか?

これは、私が本当に考えたことのない種類の質問の 1 つです。他の言語でプログラミングする場合、ライブラリを見つけるためにパスが使用されます (例: LD_LIBRARY_PATHPYTHONPATHPERLLIBRUBYLIB) 。CLASSPATHNODE_PATH

実際、LD_LIBRARY_PATHhas Whyの使用をLD_LIBRARY_PATH思いとどまらせるのはよくありません。Ruby および Perl のライブラリ パス環境変数は、それぞれのセキュリティ メカニズムが呼び出されている場合、$SAFEおよび-T(テイント モード)の場合は無視されます。

ここまでの思い…

  • ユーザーはTOOLS_PATH_LIBRARY選択したライブラリに設定できますが、ユーティリティはユーザーの uid で実行されます。悪意のあるライブラリを直接実行するだけで済みますbash
  • 私のツールsudoいくつかのもの。TOOLS_PATH_LIBRARY誰かがこれを利用するものに設定できます。ただし、ツールは を介し​​て実行されるのではなく、あちこちでsudo起動するだけです。sudoいずれにせよ、ユーザーは である必要があり、直接sudoer呼び出すことができますsudo
  • 信用できないならTOOLS_PATH_LIBRARY、信用できないPATH。すべてのプログラム呼び出しは、絶対パスを使用する必要があります。
  • シェルプログラムが絶対的なプログラムのエイリアスを使用するのを見たことがあります。そのため、を呼び出す代わりにls、のような変数を使用しますLS=/bin/ls。私が読んだことによると、これはユーザーがプログラムのデフォルトをエイリアスとして再定義するのを防ぐためです。参照: PATH、関数、およびセキュリティ。Bash スクリプトのベスト プラクティス。 .
  • Perl の汚染モードは、すべての環境変数を「汚染された」ものとして扱います。これは予感です。そのため、私は環境のリスクについて推論しようとしています。
  • ユーザーが root でない限り、あるユーザーが別のユーザーの環境を変更することはできません。したがって、ユーザーが自分の環境を変更して特権をエスカレートすることだけに関心があります。参照:別のプロセスの環境変数を変更する方法はありますか?

私はこれをある種の回答にゴムダックしましたが、それは完全な回答ではないので、まだ投稿します.

更新: 環境変数を使用してライブラリと実行可能ファイルへのパスを指定する際のセキュリティ上の問題は何ですか?

4

3 に答える 3

4

環境変数の変更を防ぐメカニズムはさまざまなプログラムに存在しますが、結論として、環境変数を信頼することはできません。セキュリティ上の懸念は非常に基本的なものです。

ユーザーが実行されると予想される内容を変更できる場合はいつでも、脆弱性が悪用される可能性が生じます。

適切な例として、CVE-2010-3847 をご覧ください。これにより、setuid または setgid バイナリを含むファイル システムへの書き込みアクセス権を持つ権限のない攻撃者が、この欠陥を利用して権限を昇格させる可能性があります。これには、ユーザーによって変更される環境変数が含まれます。

CVE-2011-1095は別の例であり、SUID バイナリは含まれていません。「glibc cve environment」をグーグル検索して、環境変数の変更で人々ができることの種類を確認してください。かなり狡猾。

あなたの懸念は、次のようなあなたの声明に要約されます。

ユーザーは TOOLS_PATH_LIBRARY を選択したライブラリに設定できますが、ユーティリティはユーザーの uid で実行されます。悪意のあるライブラリを bash で直接実行するだけです。

ここでのキー フレーズは、悪意のあるライブラリを実行することです。これは、ライブラリも UID によって所有されていることを前提としています。

ここで、セキュリティ フレームワークが大いに役立ちます。この問題にのみ焦点を当てて私が書いたものは、ここにあります。

https://github.com/cormander/tpe-lkm

このモジュールは、書き込み可能なファイル、または信頼できるユーザー (root) が所有していないファイルに対する execve/mmap/mprotect 呼び出しを停止します。信頼できるユーザーが所有するファイル/ディレクトリに悪意のあるコードを挿入できない限り、この方法でシステムを悪用することはできません。

これらの変数を含む SUID バイナリまたは sudo を使用している場合は、"paranoid" および "strict" オプションを有効にして、root でさえ root 以外が所有するバイナリを信頼するのを停止することを検討することをお勧めします。

この Trusted Path Execution メソッドは、バイナリと共有ライブラリによる直接実行を保護します。インタープリター言語はバイトコードを解析し、直接実行しないため、インタープリター言語に対しては (もしあれば) ほとんど影響しません。したがって、、、、などにはある程度の注意が必要でありPYTHONPATH、言及した言語の安全メカニズムを使用してください。PERLLIBCLASSPATH

于 2012-04-10T14:50:02.943 に答える
2

簡潔な答え:

とにかく、ユーザーが自分で選んだプログラムやコードを実行できると仮定すると、環境を含め、ユーザーが提供するものをすべて信頼する必要はありません。アカウントがなんらかの方法で制限されている場合 (シェル アクセス権なし、実行を許可するファイル システムへの書き込みアクセス権なし)、状況が変わる可能性があります。干渉?


より長い答え:

セキュリティの問題に関しては、少なくとも 2 つの個別の問題を考慮する必要があります。

  • 何を、誰から守る必要がありますか?
    • (密接に関連する質問: 私たちのプログラムは実際に何ができて、何が壊れる可能性がありますか?)
  • どうやってそれを行うのですか?

プログラムを開始し、すべての入力を提供するユーザー (つまり、攻撃を開始できる唯一のユーザー) のユーザー ID でプログラムが実行されている限り、セキュリティを強化することが理にかなっている状況はほとんどありません。攻撃に対するプログラム。アンチ コピー プロテクションとハイスコアの共有が頭に浮かびますが、これらのグループは入力だけでなく、おそらくユーザーがコードやメモリを読み取れないようにすることにも関係しています。ある種の suid/sgid トリックを使わずにシェル スクリプトのコードを非表示にする方法は、私にはわかりません。私が考えることができる最善の方法は、コードを覆い隠すことです。

この状況では、ユーザーがプログラムをだまして実行させることができることはすべて、ツールの助けがなくても実行できるため、このユーザーによる攻撃から「保護」しようとすることは意味がありません。あなたの説明は、攻撃に対する保護が実際に必要であるかのようには読めません。


保護が必要であると仮定すると、環境変数に頼ることはできません。また、 や などのリセットに失敗した場合LD_LIBRARY_PATH、またはLD_PRELOADのような絶対パスでツールを呼び出しても、そのツールがたまたま静的にコンパイルされていない限り、信頼できる答えは得られません。これが、がデフォルトで有効になっている理由であり、実行中の suid プログラムが特定の環境変数を無視しなければならない理由です。これは、同じように信頼できるというあなたのポイントがあなたの状況では真実かもしれないが、他の状況の境界ケースでは必ずしも真実ではないことを意味することに注意してください.sysadminは使用のためにリセットするかもしれませんが、非標準の環境変数を通過させます./bin/id/bin/lssudoenv_resetTOOLS_PATH_LIBRARYPATHPATHsudo

上で指摘したように、argv[0](またはそれに相当する bash ${BASH_SOURCE[0]}) は、環境変数よりも信頼性が高くありません。ユーザーは、元のファイルのコピーまたはシンボリック リンクを簡単に作成できるだけではありません。execveまたはbashexec -a foo barは何でも入れることができますargv[0]

于 2012-04-10T17:12:04.400 に答える
0

他人の環境を信用することはできません。

この重要なコードをすべて含む新しいユーザーを単純に作成してみませんか。次に、情報を直接取得するか/etc/passwd、構文を使用し~fooてユーザーのホーム ディレクトリを見つけることができます。

# One way to get home directory of util_user
DIR=$(/usr/bin/awk -F: '$1 == "util_user" {print $6}' /etc/passwd)

# Another way which works in BASH and Kornshell
[ -d ~util_dir ] && DIR=~util_dir


# Make sure DIR is set!
if  [ -z "$DIR" ]
then
   echo "Something's wrong!"
   exit
fi
于 2012-04-10T18:55:34.447 に答える