どのプログラムが実行可能ファイルを呼び出すかを監視する

どのプログラムが実行可能ファイルを呼び出すかを監視する

実行可能ファイルがshebang行を介してインタプリタとして使用される場合を含む、どのプログラムが特定の実行可能ファイルを呼び出すかを知りたいです。

これは質問とまったく同じではありません。どのプログラムが特定のファイルにアクセスするかを確認する。たとえば、呼び出しが成功した後にauditctl -w /usr/bin/myprogram監査イベントが発生し、プログラムが自動的に実行されていることを知らせます。execve

1つのオプションは、次のように実行可能ファイルをラッパーに置き換えることです。

#!/bin/sh
logger "$0: executed by uid=$(id -u) ruid=$(id -ur) cmd=$(ps -o args= -p $PPID)"
exec "$0.real" "$@"

ただし、これを行うには実際のファイルを移動する必要があり、これは破壊的です(ファイルは読み取り専用にすることはできず、パッケージマネージャが変更したものと競合するなど)。プログラムがスクリプトのインタプリタとして使用されると、shebangがネストされないため、機能しません。 (この場合はauditctl -w /usr/bin/interpreter有用な結果が得られますが、両方の場合に動作する解決策が必要です。)bashの場合、bashは/bin/sh権限を削除するため、setuidプログラムでは機能しません。

特定の実行可能ファイルの実行を監視するには、その実行可能ファイルをshebangソルバーとして使用し、特に呼び出しプロセスに関する有用な情報(PPIDだけでなく、少なくともプロセス名または親実行可能ファイルパスなど)を記録するにはどうすればよいですか。呼び出しプロセス)ユーザーとパラメータ)?ファイルをラッパーに置き換えないことをお勧めします。 Linux関連のソリューションが可能です。

答え1

/etc/ld.so.preloadこれは面倒ですが、動的にリンクされた実行可能ファイルの場合は、正しい実行可能ファイルがあることを検出した場合にのみ、ロギングフックを実行するグ​​ローバルプリロードを設定できます。

それは次のとおりです。

#define _XOPEN_SOURCE
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define TARGET "/some_executable"

__attribute__((constructor)) 
static void 
logger(int argc, char** argv){ 
    /*catch own argv right here and parent's later from /proc */

    static char buf[sizeof(TARGET)];

    readlink("/proc/self/exe", buf, sizeof(buf)-1);

    if ( 0==strcmp(TARGET, buf)){
        /* ... */
        syslog(/*...*/);
    }
}

このアプローチの明らかな欠点は、システム内の動的にリンクされたすべての実行可能ファイルの実行がわずかに遅れることです。しかし、測定結果によれば、遅延が非常に小さいことがわかりました(<1ms、ここでフォーク+実行コストは約2ms)。

権限の削除に関する問題については、おそらく親procファイル(ほとんどのファイル)を無条件に読み込んでエコーする小さなsetuid-rootバイナリがあります。statusおそらく、その親ファイルが目的のファイルである場合にのみ可能です。親実行可能ファイルを記録します。その後、ロギングフックからsetuid実行可能ファイルを生成して、実行可能ファイルの親(setuidヘルパーの祖父母)に関する情報を取得できます。

答え2

あなたはそれを使用することができますファン通知特定のファイルシステム上のファイルに関するすべての開いているジョブを受け取るためのAPI。この情報は、開いているファイルの名前と、要求者のプロセスIDを提供するファイル記述子を含むイベント構造のストリームとして提供されます。

あなたのプログラムは、オープンを許可または拒否することを選択できます。つまり、/proc競合状態なしで続行できるようにする前に、オープンを実行したコマンドとユーザーを見つけるためにpidを見つけることができます。

マニュアルページファン通知(7)イベントを取得し、公開要求を調停するための完全なCプログラムが提供されるので/proc。マウントされたファイルシステム。

このfatraceコマンドは、簡単なテストでこの情報の一部を取得する方法を示しています。たとえば、小さなスクリプトをコピー/bin/bashして作成します。/tmp/bash~/test2

#!/tmp/bash
pwd

fatrace現在のディレクトリファイルシステムを受け取り、開くを受け取る/tmpオプションを使用してファイルシステムでのみ実行します(別々のtmpfsマウントと仮定)。-c-f O

cd /tmp
sudo fatrace -c -f O

今走ると

sh -c 'echo $$; ~/test2'
expect -c 'spawn /home/meuh/test2'
~/test2

記録された内容を表示する必要があります。

sh(7360): RO /tmp/bash
expect(7414): RO /tmp/bash
bash(7590): RO /tmp/bash

関連情報