各プロセスの作成時にスクリプトの実行をフックすることは可能ですか?
基本的にはディスクアクティビティを監視する inotifywait と同等ですが、プロセス テーブルに適用されます。
これは、プロセスの生成時に、ログに記録したり、cgset を実行したり、その他のアクションを実行できるようにすることです。新しいプロセスに再帰的に適用されるという課題があることは理解できます。ただし、競合状態に脆弱な変更をキャッチするために、プロセス テーブルをできるだけ早くポーリングする代わりに、もっと良い方法があるでしょうか。
ありがとう
答え1
まず、プロセスの作成はログに記録する価値のあるイベントとはめったにならず、セキュリティとは無関係です(リソース制限を除く)。プログラムの実行をフックすることを意味していると思いますが、これは次のように行われます。execve
、 ないfork
。
第二に、あなたが挙げたユースケースは、通常、独自のメカニズムを作成するよりも、その目的のために作成された既存のメカニズムを使用する方が最適に機能します。
- ログ記録については、BSDプロセスアカウンティング少量の情報を提供し、ほとんどのUnix系で利用可能です。Linuxでは、GNU 会計ユーティリティ(ディストリビューションからパッケージをインストールしてください)。Linuxでより洗練されたログ記録を行うには、監査サブシステム(の
auditctl
man ページには例があります。上で説明したように、ログに記録するシステム コールは ですexecve
。 - 特定のプログラムにセキュリティ制限を適用したい場合は、次のようなセキュリティフレームワークを使用します。カーネルまたはアプリアーマー。
- 特定のプログラムをコンテナ内で実行したり、特定の設定で実行したりする場合は、実行可能ファイルを移動し、その代わりに必要な設定を指定して元の実行可能ファイルを呼び出すラッパー スクリプトを配置します。
他のプログラムの動作に影響を与えずに、特定のプログラムが他のプログラムを呼び出す方法を変更したい場合、そのプログラムが潜在的に敵対的であるかそうでないかの 2 つのケースがあります。
- プログラムが潜在的に悪意のあるものである場合は、専用の仮想マシンで実行します。
- プログラムが協調的である場合、最も明白な攻撃の角度は、別の で実行することです
PATH
。プログラムが絶対パスを使用していて、設定が容易でない場合は、古いLinuxシステムでは、別の で実行できます。マウント名前空間(参照カーネル: 名前空間のサポート)。本当に細かい制御が必要な場合は、 でプログラムを起動して、一部のライブラリ呼び出しをオーバーライドするライブラリをロードすることができますLD_PRELOAD=my_override_library.so theprogram
。実行前にファイル記述子をリダイレクトする例えば、 を参照してください。 は内部の C ライブラリ呼び出しには影響しないため、に加えてexecve
、 を呼び出すすべての C ライブラリ関数をオーバーライドする必要があることに注意してください。 でプログラムを実行すると、より正確な制御が可能になります。これにより、C ライブラリ関数によって行われたシステム呼び出しもオーバーライドできますが、設定が難しくなります (簡単な方法は知りません)。execve
LD_PRELOAD
ptrace
答え2
//fakeExec.c
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
int execve(const char *path, char *const argv[], char *const envp[]) {
printf("Execing \"%s\"\n", path);
return syscall(SYS_execve, path, argv, envp);
}
ターミナルで:
$ gcc -fPIC -shared fakeExec.c -o fakeExec.so
$ export LD_PRELOAD=$PWD/fakeExec.so
そして、新しく実行されたすべてのファイルが に記録されるはずですstdout
。
フォーク ラッパーを正しく実行するには、どうやらもう少し作業が必要になるようです。
(ではなく を対象fork
とする上記のような単純なラッパーは、ある程度は機能しますが、これによって生成されたプロセスでいくつかのエラーが発生します。fork
execve
setgpid
どうやら libcfork
関数には少しだけ追加の機能があるようですが、よくわかりません。)