回答:
これはauditdにとって完璧な仕事のように思えます。最新のRedHatベースのシステムでデフォルトのサービスである実行を監査したら、実行することで必要な処理を正確に実行するルールを作成できます。
auditctl -a task,always -F uid=0
このコマンドルールを破り、マニュアルページを過度に使用すると、次のことがわかります。
-a list,action task Add a rule to the per task list. This rule list is used only at the time a task is created -- when fork() or clone() are called by the parent task. When using this list, you should only use fields that are known at task creation time, such as the uid, gid, etc. always Allocate an audit context, always fill it in at syscall entry time, and always write out a record at syscall exit time.
そのため、forkまたはcloneシステムコールが終了するたびに、このアクションのレコードを常に書き出してください。
最後のオプションはフィルター文字列と考えることができます。使用-F uid=0
する場合、プロセス所有者のuidが0の場合にのみ制限されます。
auditdが適切に構成されていることを確認し
-a task,always -F uid=0
、ディストリビューションの関連ファイルにルールを追加することにより、実行時にこのルールを実行できることに注意してください。/etc/audit/audit.rules
これはかなりうるさいので、ログのレビューをしている人は誰でもそれに備える必要があることに注意してください。
CONFIG_PROC_EVENTSおよび/またはCONFIG_KPROBESでカーネルを再コンパイルせずにこれを行うクリーンな方法はないと思います(それを行う方法があるかどうか知りたいので、あなたの質問を支持しました)。
/ proc内でディレクトリを作成するためにiwatch / inotifyを使用するというアイデアはありましたが、機能していないようで、auditctlも機能していませんでした。最良の選択のように見えますが、汚いですが、スクリプトからの変更についてpsを継続的に解析することです。次のPerlコードはそれを行いますが、いくつかを見逃して無視する傾向がありますps
(そうでなければそれ自体をトリガーします):
perl -e 'my %pids; while(1) { my @pids = `ps -U root -u root`; foreach (@pids) { next if /ps$/; ($pid) = /^\s*(\d+)\D/; if (!$pids{$pid}) { $pids{$pid}++; print "Process $pid created (" . `cat /proc/$pid/cmdline` . ")\n"; } } }
私が考えることができる最良の方法は、スヌーピーライブラリを構築することです。snoopyは非常に小さな共有ライブラリで/etc/ld.so.preload
あり、execve()
システムコールに接続されてラップされます。すべてexec()
の、またはルートからのログのみを記録するように構成できます。現在のインカネーションでは、スヌーピーは一致するイベント(へのシステムコールexecve()
)が発生するたびにsyslogにログを記録します。ただし、大規模なプログラム(せいぜい数百行のコード)ではなく、アクティビティをログに記録する代わりに(またはそれに加えて)スクリプトを実行するのにそれほど苦労することなく変更できます。スヌーピーはCで書かれています。
注意すべき点がいくつかあります。