Řešení 1:
To zní jako perfektní práce pro auditované. Jakmile budete mít auditovaný běh, výchozí službu na moderních systémech založených na RedHat, můžete vytvořit pravidlo, které vykoná přesně to, co chcete, spuštěním
auditctl -a task,always -F uid=0
Porušením tohoto příkazového pravidla a nadměrným používáním manuálové stránky zjistíme, že:
-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.
Proto vždy zapište záznam o této akci, kdykoli se ukončí systémové volání rozvětvení nebo klonování.
Poslední možnost si lze představit jako řetězec filtru, v našem případě -F uid=0
jednoduše nás omezuje na případy, kdy uid vlastníka procesu je 0.
Všimněte si, že toto pravidlo lze spustit za běhu, když se ujistíte, že je auditd správně nakonfigurováno, a přidáte pravidlo
-a task,always -F uid=0
do příslušného souboru pro vaši distribuci, pravděpodobně /etc/audit/audit.rules
Jen mějte na paměti, že to bude pěkně hlučné a kdokoli, kdo bude provádět kontroly vašich protokolů, na to bude muset být připraven.
Řešení 2:
Nemyslím si, že existuje čistý způsob, jak toho dosáhnout bez rekompilace jádra pomocí CONFIG_PROC_EVENTS a/nebo CONFIG_KPROBES (ačkoli bych rád věděl, zda existuje způsob, jak to udělat, takže jsem hlasoval pro vaši otázku).
Měl jsem nápad použít iwatch/inotify pro vytváření adresářů v /proc, ale nezdálo se, že by to fungovalo, ani auditctl. Vypadá to, že nejlepší volbou, i když je to špinavé, je neustále analyzovat ps pro změnu ze skriptu. Následující kód v Perlu by to udělal, i když by byl náchylný k vynechání některých a ignoruje ps
(jak by se jinak spustilo samo):
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"; } } }