Odpowiedzi:
To brzmi jak idealna praca dla audytora. Po przeprowadzeniu audytu, domyślnej usługi w nowoczesnych systemach opartych na RedHat, możesz stworzyć regułę, która wykona dokładnie to, co chcesz, wykonując
auditctl -a task,always -F uid=0
Po rozbiciu tej reguły polecenia, nadmiernym korzystaniu ze strony podręcznika, okazuje się, ż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.
Dlatego zawsze zapisuj zapis tego działania za każdym razem, gdy kończy się wywołanie systemowe rozwidlenia lub klonowania.
Ostatnią opcję można traktować jako ciąg filtru, w naszym zastosowaniu -F uid=0
po prostu ogranicza nas do przypadków, w których identyfikator użytkownika procesu wynosi 0.
Pamiętaj, że tę regułę można wykonać w czasie wykonywania, upewniając się, że auditd jest poprawnie skonfigurowany, i dodając regułę
-a task,always -F uid=0
do odpowiedniego pliku dla Twojej dystrybucji, najprawdopodobniej/etc/audit/audit.rules
Pamiętaj tylko, że będzie to dość głośno i każdy, kto robi twoje recenzje dziennika, będzie musiał być na to przygotowany.
Nie sądzę, że istnieje czysty sposób na zrobienie tego bez ponownej kompilacji jądra za pomocą CONFIG_PROC_EVENTS i / lub CONFIG_KPROBES (chociaż chciałbym wiedzieć, czy istnieje sposób, aby to zrobić, więc wziąłem pod uwagę twoje pytanie).
Wpadłem na pomysł użycia iwatch / inotify do tworzenia katalogów w / proc, ale nie działało, podobnie jak audctl. Wygląda na to, że najlepszym wyborem, choć nieprzyzwoitym, jest ciągłe analizowanie ps pod kątem zmiany ze skryptu. Poniższy kod Perla zrobiłby to, chociaż miałby skłonność do pominięcia niektórych i ignorowania ps
(ponieważ w innym przypadku sam się uruchomiłby):
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"; } } }
Najlepszym sposobem, jaki mogę wymyślić, jest zbudowanie biblioteki snoopy . snoopy to bardzo mała biblioteka współdzielona, która zaczepia się /etc/ld.so.preload
i otacza execve()
wywołania systemowe. Jest konfigurowalny do rejestrowania wszystkich exec()
, lub tylko tych z roota. W obecnym wcieleniu snoopy loguje się do syslog za każdym razem, gdy execve()
zdarzy się pasujące zdarzenie (wywołanie syscall ). Nie jest to jednak duży program (najwyżej kilkaset wierszy kodu) i można go modyfikować bez większych trudności w celu wykonania skryptu zamiast (lub oprócz) rejestrowania działania. Snoopy jest napisane w C.
Kilka rzeczy do zapamiętania: