Bashスクリプトから実際に実行しているものを確認する方法はありますか?
Bashスクリプトがいくつかのコマンド(例:tar
、mail
、scp
、mysqldump
)を呼び出していて、tar
は実際の実際のtar
であり、これはroot
ユーザーがファイルおよび親ディレクトリの所有者であり、書き込み権限を持つ唯一のユーザーであり、一部の/tmp/surprise/tar
ではありませんwww-data
またはApache2
がオーナーです。
確かにPATH
と環境について知っていますが、これが実行中のbashスクリプトから追加でチェックできるかどうか知りたいです。
例:(疑似コード)
tarfile=$(which tar)
isroot=$(ls -l "$tarfile") | grep "root root"
#and so on...
実行するバイナリを検証する代わりに、最初から適切なバイナリを実行できます。例えば。 /tmp/surprise/tar
を実行しないようにする場合は、スクリプトで/usr/bin/tar
を実行します。または、何かを実行する前に$PATH
を適切な値に設定します。
/usr/bin/
およびその他のシステムディレクトリ内のファイルを信頼しない場合、信頼を取り戻す方法はありません。あなたの例では、ls
で所有者を確認していますが、ls
を信頼できることをどのようにして確認しますか?同じ議論がmd5sum
やstrace
などの他のソリューションにも当てはまります。
システムの整合性に対する高い信頼性が必要な場合は、 [〜#〜] ima [〜#〜] などの特殊なソリューションが使用されます。しかし、これはスクリプトから使用できるものではありません。システム全体を、不変ファイルの概念を備えた特別な方法でセットアップする必要があります。
侵入者がシステムにアクセスし、$PATH
を変更できる場合(どのような状況でも/tmp
を含めることはできません)、実行可能ファイルの所有権について心配するのは遅すぎます。
代わりに、 侵入への対処方法 について読む必要があります。
侵入を完全に回避することに集中するほうがよい。
これらの種類のことが重要なシステムがある場合は、パブリックにする必要がある部分とプライベートにする必要がある部分を分離し、通信モードの監査を実行することをお勧めします。これらの間。
ファイルのmd5sum
を確認することで、ある程度は可能です。したがって、apt
パッケージ管理を使用するシステム-私の特定のケースでは、Ubuntu 16.04-中にファイル/var/lib/dpkg/info/tar.md5sums
があります。これは、tar
からのすべてのファイルのmd5合計を格納しますインストール。したがって、md5sum /bin/tar
の出力がそのファイルの内容と一致するかどうかを確認する簡単なifステートメントを作成できます。
もちろん、ファイル自体が改ざんされていないことを前提としています。もちろん、これは攻撃者がroot/Sudoアクセスを取得した場合にのみ発生する可能性があり、その時点ですべての賭けは無効になります。
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 -f
は、マルチスレッドの場合、thread_id = PIDのスレッドだけでなく、プロセスPIDのすべてのスレッドをアタッチすることに注意してください。
-e trace=file
:ファイル名を引数として取るすべてのシステムコールをトレースします。これは-e trace=open,stat,chmod,unlink,...
の省略形と考えることができます。これは、プロセスが参照しているファイルを確認するのに役立ちます。さらに、省略形を使用すると、リストにlstatのような呼び出しを誤って含めることを忘れないようになります。
はい、メソッドがあります:組み込みtype
。 PATHでのみ検索するwhich
コマンドとは対照的に、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
であることを通知します。
Linux osはファイルに基づいており、linuxで実行される多くのコマンドは、マシン上にあるファイルのいくつかの変更を解決する可能性があります。そのため たぶん が問題の最善の解決策です。コマンドが実行される前に、ファイルシステムの変更についてコマンドをテストできます。
コマンドを部分的に逆コンパイルする「strace」コマンドがあります...
深く掘り下げたい場合は、実行するスクリプトの逆コンパイラをチェックアウトします。つまり、そのコマンドのアセンブラ解釈を確認する必要があります。 bashの場合はobjdump -d
。 Linux binスクリプトは主にC
プログラミング言語で作成されるため、優れたC
デコンパイラーを使用してください。