Kennt jemand eine einfache Möglichkeit, Root-Prozess-Spawn zu überwachen?

13

Ich möchte ein Skript ausführen, wenn ein neuer Root-Prozess gestartet wird. (unter Linux) Wie kann ich das einfach machen?

Vielen Dank

Cerisier
quelle
Dies ist eine interessante Frage, aber gibt es dafür eine praktische Anwendung? Ich habe mir den Kopf zerbrochen und ziehe eine Lücke ...
Steven Montag,

Antworten:

9

Das klingt nach einem perfekten Job für auditd. Sobald Sie auditd, einen Standarddienst auf modernen RedHat-basierten Systemen, ausgeführt haben, können Sie eine Regel erstellen, die genau das tut, was Sie möchten, indem Sie sie ausführen

auditctl -a task,always -F uid=0

Wenn Sie diese Befehlsregel auflösen und die Manpage übermäßig nutzen, stellen Sie fest, dass:

   -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.

Schreiben Sie daher immer einen Datensatz für diese Aktion, wenn ein Fork- oder Clone-Systemaufruf beendet wird.

Die letzte Option kann als eine Filterzeichenfolge betrachtet werden. Bei unserer Verwendung -F uid=0werden wir einfach auf Fälle beschränkt, in denen die UID des Prozesseigners 0 ist.

Beachten Sie, dass diese Regel zur Laufzeit ausgeführt werden kann, indem Sie sicherstellen, dass auditd ordnungsgemäß konfiguriert ist, und die Regel
-a task,always -F uid=0
höchstwahrscheinlich in die für Ihre Distribution relevante Datei einfügen/etc/audit/audit.rules

Denken Sie daran, dass dies ziemlich laut sein wird, und wer auch immer Ihre Protokollprüfungen durchführt, muss darauf vorbereitet sein.

Scott Pack
quelle
Eigentlich merke ich jetzt, wo ich das geschrieben habe, plötzlich, dass ich die Frage im Titel und nicht die Frage in der Frage beantwortet habe. Ich hoffe es ist immer noch nützlich.
Scott Pack
Warum verwenden Sie manchmal pid = 0 und manchmal uid = 0
Dakusan
@dakusan Meistens weil ich einen Editor brauche. Jetzt behoben.
Scott Pack
2

Ich glaube nicht, dass es eine saubere Möglichkeit gibt, dies zu tun, ohne Ihren Kernel mit CONFIG_PROC_EVENTS und / oder CONFIG_KPROBES neu zu kompilieren (obwohl ich gerne wissen würde, ob es eine Möglichkeit gibt, dies zu tun, also habe ich Ihre Frage hochgestuft).

Ich hatte die Idee, iwatch / inotify für die Verzeichniserstellung in / proc zu verwenden, aber es schien nicht zu funktionieren, und auditctl auch nicht. Es sieht so aus, als ob Sie die beste Wahl treffen, obwohl Sie dreckig sind, wenn Sie ps kontinuierlich analysieren, um eine Änderung an einem Skript vorzunehmen. Der folgende Perl-Code würde es tun, obwohl er dazu neigen würde, etwas zu verpassen und zu ignorieren ps(da er sich sonst selbst auslösen würde):

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"; } } }
James L
quelle
Am Ende Ihres Codes fehlt ein einfaches Anführungszeichen. Kann nicht bearbeitet werden, da SO mindestens 6 Zeichen zum Ändern benötigt. Verwenden Sie für alle Benutzer außerdem "-ax" anstelle von "-U root -u root"
Dakusan,
1

Der beste Weg, den ich mir vorstellen kann, wäre, die Snoopy- Bibliothek aufzubauen . snoopy ist eine sehr kleine gemeinsam genutzte Bibliothek, die sich in Systemaufrufe einhakt /etc/ld.so.preloadund diese umschließt execve(). Es kann so konfiguriert werden, dass alle exec()oder nur die von root protokolliert werden . In seiner aktuellen Inkarnation protokolliert sich snoopy jedes Mal in syslog, wenn ein passendes Ereignis (ein Systemaufruf an execve()) eintritt. Es ist jedoch kein großes Programm (höchstens ein paar Hundert Codezeilen) und kann ohne große Schwierigkeiten geändert werden, um ein Skript auszuführen, anstatt (oder zusätzlich zu) die Aktivität zu protokollieren. Snoopy ist in C geschrieben.

Ein paar Dinge zu beachten:

  • Wenn Sie ein Skript jedes Mal ausführen, wenn ein Root-Prozess erzeugt wird, ist Ihr Skript ein Root-Prozess, der das Skript erneut erzeugen muss, ein weiterer Root-Prozess usw. Achten Sie darauf, dass Sie nicht in eine Schleife geraten Dort.
  • Auf einer typischen Linux-Box gibt es viele Prozesse, die als Root ausgeführt und regelmäßig erzeugt werden. Zum Beispiel kann cron System-Cronjobs jede Minute oder einige Minuten als root erzeugen. Wenn Sie nur danach Ausschau halten, dass dies geschieht, wenn sich ein Benutzer als root anmeldet, ist dies arbeitsintensiver.
Christopher Cashell
quelle