実行前のコマンドバイナリの検証


13

bashスクリプトから実際に実行していることを確認する方法はありますか?

(例えば:あなたのbashスクリプトは、いくつかのコマンドを呼び出していると言うtarmailscpmysqldump)、あなたはそのことを確認して喜んでいるtar本当の、実際にあるtarことによって決定された、rootファイルおよび親ディレクトリの所有者と書き込み権限を持つ唯一の一つであるユーザー所有者/tmp/surprise/tarであるwww-dataapache2所有者ではない人もいます。

確かに私PATHは環境について知っていますが、これを実行中のbashスクリプトからさらにチェックできるかどうか、そしてそうであれば、どのくらい正確に知りたいですか?

例:(擬似コード)

tarfile=$(which tar)
isroot=$(ls -l "$tarfile") | grep "root root"
#and so on...

2
あなたがとても妄想的であるなら、あなた自身のバイナリを使用してください!
IPOR Sircer

8
xhienneが答えたように、which何をtarするかを正しく言わないことに加えて、lsハッキングされてファイルに関する偽の情報があればそれを返す可能性があります。またgrep、ハッキングされて誤った情報を返す可能性があります。代わりにシェルマッチングを使用することで回避できますが、シェルがハッキングされる可能性があります。typeそもそも、シェルはハッキングされて間違った結果をもたらす可能性があります。または、シェルの交換可能性は50年前のOSと比較してUnixの重要な革新であったため、完全に置き換えられました。ケントンプソンの1984年のチューリングアドレスを参照してください。それはずっとカメです。
-dave_thompson_085

2
Linuxではこれに答えられません-信頼できる実行(TE)と呼ばれるコンポーネントを持つAIXのみ- 署名付きのデータベース(つまり、MD5チェックサムよりも広範囲です。TEがアクティブで、ファイルがデータベースにある場合は選択可能)プログラムが実行されるかどうか、またはデータベースと一致しないことを警告するだけですさらに、2つの設定があります:(TEP信頼された実行PATH)とTLP(信頼されたLIBrary PATH)。TEPのプログラムのみが実行され、ライブラリはディレクトリは、TLPに含まれているでLinuxの私はあなたを助けるかもしれない「AppArmorの」と呼ばれるものがある。。
マイケルはフェルト

1
この種の安全性は確保できますが、スクリプトからはできません。制御されていない環境でスクリプトを実行するまでには手遅れです。あなたが見ることができるすべてを知っているすべてのために、攻撃者によって設定されたchrootです。
チャールズダフィー

2
...完全に信頼できるシステムを構築したい場合は、ChromeOSのアプローチを採用する必要があります。ハードウェアに埋め込まれたキーでファームウェアに署名してください。ファームウェアによって検証されたブートローダー/カーネル。検証にブロックレベルの署名を使用して、ルートOSパーティションを読み取り専用にします。@MichaelFeltが議論しているものと同様のアプローチもあります-Integrity Measurement Architectureを参照してください-ただし、パフォーマンスへの影響はより大きく、整合性のレベルは低下します(バイナリ署名のチェックは非実行可能ファイルを介した攻撃には役立たないため)コンテンツ)。
チャールズダフィー

回答:


24

実行するバイナリを検証する代わりに、最初から正しいバイナリを実行できます。たとえば、実行しないようにしたい場合は、スクリプトで/tmp/surprise/tar実行/usr/bin/tarするだけです。または、$PATH何かを実行する前に、適切な値に設定します。

あなたがファイル/usr/bin/や他のシステムディレクトリを信頼しない場合、自信を取り戻す方法はありません。あなたの例では、で所有者を確認してlsいますが、どのように信頼できることを知っていますかls?同じ議論は、md5sumやなどの他のソリューションにも適用されstraceます。

システムの完全性に対する高い信頼性が必要な場合、IMAなどの特殊なソリューションが使用されます。しかし、これはスクリプトから使用できるものではありません。システム全体を特別な方法でセットアップし、不変ファイルの概念を適切に設定する必要があります。


異なるディストリビューションがの/bin代わりにバイナリを置くことを選択した場合、これは壊れます/usr/bin
ダミアンジェリック

IMAは、これに対する2つの実稼働対応のアプローチの1つです。もう1つは、rootfsのブロックレベルの検証を行うためにChromeOSが採用したdm-verityアプローチです。
チャールズダフィー

@DamianYerrick Fairの発言。$PATH複数の配布サポートが必要な場合は、これらの両方のパスに設定してください。
ドミトリーグリゴリエフ

AIX TE(RBACの有無にかかわらず)は、これを実現する3番目の「実稼働対応」カーネル組み込み機能です。TEは、パッシブ以上の機能を有効にすると、ファイルのオープンやプログラムの実行を防止します。さらに、アプリケーションとライブラリの使用は、TEP(信頼された実行パス)またはTLP(信頼されたライブラリパス)のみに設定できます。基本情報についてはibm.com/support/knowledgecenter/en/ssw_aix_61/…を参照してください
Michael Felt

6

侵入者がシステムにアクセスし、自分を変更できる場合$PATH/tmpどのような状況でもこれを含めるべきではありません)、実行可能ファイルの所有権を心配するのは遅すぎます。

代わりに、侵入への対処方法について読む必要があります

侵入を完全に回避することに集中することをお勧めします。

これらの種類の事柄が重要なシステムがある場合、パブリックにする必要がある部分をプライベートにする必要がある部分から分離し、通信モードの監査を実行することをお勧めしますこれらの間。


4

md5sumファイルの検証によってある程度可能です。したがって、aptパッケージ管理を使用するシステム(私の場合はUbuntu 16.04)には、インストール中に/var/lib/dpkg/info/tar.md5sums取得されたすべてのファイルのmd5合計を保存するfile がありtarます。したがって、の出力がmd5sum /bin/tarそのファイルにあるものと一致するかどうかをチェックする単純なifステートメントを書くことができます。

もちろん、ファイル自体が改ざんされていないことを前提としています。もちろん、これは攻撃者がroot / sudoアクセスを取得したときにのみ発生し、その時点ですべてのベットはオフになります。


8
しかし、どのように検証し/usr/bin/md5sumますか?
ドミトリーグリゴリエフ

攻撃者は、交換することが可能である場合/bin/tar/usr/bin/tar、それは非常に可能性が、彼らは単に置き換えることができますmd5sum/var/lib/dpkg/info/tar.md5sums。または$SHELL
ジョナスシェーファー

1
前の段落で既に述べたように、そのようなことが起こるには、攻撃者はシステムへのルートアクセスを取得する必要があり、その時点で何でも可能です。ケースでは、攻撃者がルートアクセス権を持っていませんが、ユーザーのPATH変数を変更したり、tar異なるbinaryを指すエイリアスを作成したりすることができます。システムは、ルートレベルで危険にさらされたとき、あなたは、1つのオプションを持っている-軌道からそれをハァハァ
Sergiy Kolodyazhnyy

3

はい、組み込みメソッドがありtypeます。whichPATHでのみ検索するコマンドとは異なりtype、コマンド名が実際に予約キーワード、組み込み、エイリアス、関数、またはディスクファイルであるかどうかがわかります。

$ type -t foobar || echo "Not found"
Not found

$ type -t echo
builtin

$ enable -n echo; type -t echo; type -p echo
file
/usr/bin/echo

$ echo() { printf "(echoing) %s\n" "$*"; }; type -t echo
function

$ alias echo="/bin/echo 'I say: ' "; type -t echo
alias

さらにtype -a、コマンドのすべての候補(最初の選択から最後の選択まで)を提供します。

$ type -a echo
echo is aliased to `/bin/echo 'I say: ' '
echo is a function
echo () 
{ 
    printf "(echoing) %s\n" "$*"
}
echo is a shell builtin
echo is /usr/local/bin/echo
echo is /bin/echo

最後に、ディスク上のバイナリのみに関心がある場合type -Paは、PATH内のすべてのバイナリを取得するために使用できます(上記と同じ順序)。

$ type -Pa tar
/home/me/bin/tar                <= oh oh, is this normal?
/bin/tar

typeはいえ、それだけでは、最終的にどのコマンドが呼び出されるかを正確に伝えることはできません。たとえば、あなたtarがバイナリ(たとえばalias tar="/tmp/tar")を呼び出すエイリアスである場合、typeこれはであることがわかりますalias


type -aすべてのフォームを含む(エイリアスと外部プログラムの両方など)
-dave_thompson_085

@daveに感謝します。本当に面白いです。答えを更新しました
-xhienne

1
typebashが知っている限りあなたに伝えますが、悪意のある攻撃者から制御されている場合、bashがそれを知っていると考えるものが実際の真実を反映していると信じる理由はありません。あなたが知っているすべてのために、あなたが行うLD_PRELOADすべての単一のCライブラリ呼び出しをインターセプトするモジュールがあります。
チャールズダフィー

1
@CharlesDuffyあなたはもちろん正しいです。セキュリティアングルに向かって答えたくありませんでした。私はちょうど上部に質問への答えを提案しています:との代替を提案した「あなたが実際にbashスクリプトから実行しているかどうか確認するために任意の方法があります」which
xhienne

私はenable前に見たことがありません。これらの回答からのアドバイスを使用して実行type enableし、組み込みのシェルであることを確認してhelp enableから、その機能を確認しました。
ジョー

3

を使用して、スクリプトによって正確に実行されているコマンドを確認できますstrace。例えば:

strace -f -e execve ./script.sh

次のスクリプトを使用します。

#!/bin/bash
touch testfile.txt
echo "Hello" >> testfile.txt
cat testfile.txt
rm testfile.txt

strace-e execveパラメータとともに使用したときに実行されるコマンドへの正確なパスを示します。

execve("./script.sh", ["./script.sh"], [/* 69 vars */]) = 0 
Process 8524 attached
[pid  8524] execve("/usr/bin/touch", ["touch", "testfile.txt"], [/* 68 vars */]) = 0 
[pid  8524] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8524, si_status=0, si_utime=0, si_stime=0} --- 
Process 8525 attached [pid > 8525] execve("/bin/cat", ["cat", "testfile.txt"], [/* 68 vars */]) = 0
Hello [pid  8525] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8525, si_status=0, si_utime=0, si_stime=0} --- 
Process 8526 attached [pid > 8526] execve("/bin/rm", ["rm", "testfile.txt"], [/* 68 vars */]) = 0
[pid  8526] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8526, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

パラメーター(strace manから):

-f:子プロセスは、fork(2)、vfork(2)、clone(2)システムコールの結果として現在トレースされているプロセスによって作成されたとおりにトレースします。-p PID -fthread_id = PIDのスレッドだけでなく、マルチスレッドの場合、プロセスPIDのすべてのスレッドをアタッチすることに注意してください。

-e trace=file:引数としてファイル名を取るすべてのシステムコールをトレースします。-e trace=open,stat,chmod,unlink,...これは、プロセスが参照しているファイルを確認するのに役立つ略語と考えることができます。さらに、略語を使用すると、リストにlstatのような呼び出しを含めることを誤って忘れないようにすることができます。


3
これは、スクリプトで自動テストを実行するために使用できる手段でstraceは決してなく、それ自体が破壊されていないと信じる特別な理由はありません。
チャールズダフィー

0

Linux OSはファイルに基づいており、Linuxで実行される多くのコマンドは、おそらくマシン上のファイルの一部の変更を解決します。そのため、おそらくあなたの問題の最善の解決策です。コマンドを実行する前に、ファイルシステムの変更をコマンドでテストできます。

ここに画像の説明を入力してください

コマンドを部分的に逆コンパイルする「strace」コマンドがあります...

ここに画像の説明を入力してください

深く掘り下げたい場合は、実行されるスクリプトの逆コンパイラをチェックアウトする必要があります。つまり、そのコマンドのアセンブラーの解釈を確認する必要があります。bashがありobjdump -dます。Linux binスクリプトは主にCプログラミング言語で作成されるため、適切なC逆コンパイラーを使用してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.