Мониторинг того, какая программа вызывает исполняемый файл

Я хочу знать, какая программа вызывает конкретный исполняемый файл, в том числе, когда этот исполняемый файл используется в качестве интерпретатора через строку shebang.

Это не совсем такая же проблема, как знать, какая программа обращается к определенному файлу . Например, auditctl -w /usr/bin/myprogram сообщает мне, что программа выполняется самим … сама, поскольку событие аудита создается после успешного вызова execve .

Один из вариантов – заменить исполняемый файл программой-оболочкой, например …

 #!/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 дает полезный результат, но я хочу, чтобы решение работало для обоих случаев.) Оно также не работает для программ setuid, если /bin/sh является bash с момента bash капель привилегий.

Как я могу контролировать выполнение конкретного исполняемого файла, включая использование исполняемого файла в качестве интерпретатора shebang, и, в частности, использовать полезную информацию о вызывающем процессе (а не только PPID, но, по крайней мере, имя процесса или родительский исполняемый путь, в идеале также вызывающий пользователя и аргументов)? Предпочтительно, не заменяя файл оберткой. Решение, специфичное для Linux, в порядке.

2 Solutions collect form web for “Мониторинг того, какая программа вызывает исполняемый файл”

Это было бы взломанным, но если это динамически связанный исполняемый файл, вы можете настроить глобальную предварительную загрузку в /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(/*...*/); } } 

Очевидным недостатком этого подхода является то, что он немного задерживает выполнение каждого динамически связанного исполняемого файла в вашей системе, но мои измерения показывают, что задержка довольно мала (<1 мс, где fork + exec стоит около 2 мс).

Что касается проблемы с разрешенным разрешением, у вас может быть небольшой двоичный файл setuid-root, который будет безошибочно читать и эхо его файлы дедушки и бабушки (скорее всего, файл status ), возможно, если и только если его родителем является исполняемый файл, родители которого вы хотите журнал. Затем вы можете создать этот исполняемый файл setuid внутри вашего логгера, чтобы получить информацию о родительском файле исполняемых файлов (grandparent помощника setuid).

Вы можете использовать API-интерфейс fanotify для прослушивания всех открытий, сделанных в файлах в данной файловой системе. Информация предоставляется как поток структур событий, которые включают файловый дескриптор, который предоставляет открываемое имя файла, и идентификатор процесса запрашивающего.

Ваша программа может разрешить или отклонить открытие, что означает, что он может искать pid in /proc чтобы найти команду и пользователя, выполняющие открытые действия, прежде чем разрешить им продолжить, без возможности условия гонки.

Страница man fanotify (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 
  • Может ли один каталог принадлежать двум группам?
  • Какие символы действительны для использования в именах файлов?
  • На каких системах // foo / bar отличается от / foo / bar?
  • Поведение памяти mmap'd на давление памяти
  • Добавление метки времени в имя файла / dir
  • имя файла и путь к файлу
  • Linux: поиск текстового файла со строкового ввода
  • Не удалось удалить каталоги, скопированные из других источников. Centos 6
  • Как пользователь может редактировать файл, даже когда бит записи отключен в файле
  • Присоединение файлов на диске
  • Дерево с именем каталога и именами файлов
  • Linux и Unix - лучшая ОС в мире.