Risposte:
Sembra un lavoro perfetto per auditd. Dopo aver eseguito auditd, un servizio predefinito sui moderni sistemi basati su RedHat, è possibile creare una regola che farà esattamente ciò che si desidera eseguendo
auditctl -a task,always -F uid=0
Abbattendo questa regola di comando, facendo un uso eccessivo della pagina man, troviamo che:
-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.
Quindi scrivi sempre un record per questa azione ogni volta che esce una chiamata di sistema fork o clone.
L'ultima opzione può essere pensata come una stringa di filtro, nel nostro uso -F uid=0
ci limita semplicemente ai casi in cui l'UID del proprietario del processo è 0.
Si noti che questa regola può essere eseguita in fase di esecuzione assicurandosi che auditd sia configurato correttamente e aggiungendo la regola
-a task,always -F uid=0
nel file pertinente per la distribuzione, molto probabilmente/etc/audit/audit.rules
Tieni presente che questo sarà abbastanza pericoloso e che chiunque stia facendo le tue recensioni di log dovrà essere preparato per questo.
Non credo che ci sia un modo chiaro per farlo senza ricompilare il kernel con CONFIG_PROC_EVENTS e / o CONFIG_KPROBES (anche se mi piacerebbe sapere se esiste un modo per farlo, quindi ho votato a favore della tua domanda).
Ho avuto l'idea di usare iwatch / inotify per la creazione di directory all'interno di / proc, ma non sembrava funzionare, né auditctl. Sembra che la tua scelta migliore, anche se sporca, sia quella di analizzare continuamente ps per un cambiamento da uno script. Il seguente codice Perl lo farebbe, anche se sarebbe incline a mancarne un po 'e ignorarlo ps
(altrimenti si innescerebbe):
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"; } } }
Il modo migliore che mi viene in mente sarebbe quello di costruire la libreria snoopy . snoopy è una libreria condivisa molto piccola che viene agganciata /etc/ld.so.preload
e avvolge le execve()
chiamate di sistema. È configurabile per registrare tutti exec()
o solo quelli da root. Nella sua attuale incarnazione, snoopy registra su syslog ogni volta che si verifica un evento corrispondente (una scala di grigi execve()
). Tuttavia, non è un programma di grandi dimensioni (almeno un paio di centinaia di righe di codice) e potrebbe essere modificato senza troppe difficoltà per eseguire uno script anziché (o in aggiunta a) registrare l'attività. Snoopy è scritto in C.
Alcune cose da notare: