Câu trả lời:
Điều này nghe có vẻ như một công việc hoàn hảo cho audd. Khi bạn đã chạy audd, một dịch vụ mặc định trên các hệ thống dựa trên RedHat hiện đại, bạn có thể tạo một quy tắc sẽ thực hiện chính xác những gì bạn muốn bằng cách thực thi
auditctl -a task,always -F uid=0
Phá vỡ quy tắc lệnh này, sử dụng quá nhiều trang man, chúng tôi thấy rằng:
-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.
Vì vậy, luôn luôn viết ra một bản ghi cho hành động này bất cứ khi nào một cuộc gọi ngã ba hoặc hệ thống nhân bản thoát.
Tùy chọn cuối cùng có thể được coi là một chuỗi bộ lọc, trong quá trình sử dụng của chúng tôi -F uid=0
chỉ đơn giản giới hạn chúng tôi trong trường hợp uid của chủ sở hữu quy trình là 0.
Lưu ý rằng quy tắc này có thể được thực thi trong thời gian chạy bằng cách đảm bảo rằng audd được cấu hình đúng và thêm quy tắc
-a task,always -F uid=0
vào tệp có liên quan để phân phối của bạn, rất có thể/etc/audit/audit.rules
Chỉ cần lưu ý rằng điều này sẽ khá nguy hiểm và bất cứ ai đang thực hiện đánh giá nhật ký của bạn sẽ cần phải chuẩn bị cho nó.
Tôi không nghĩ có một cách rõ ràng để làm điều này mà không cần biên dịch lại kernel của bạn với CONFIG_PROC_EVENT và / hoặc CONFIG_KPROBES (mặc dù tôi rất muốn biết liệu có cách nào để thực hiện không, vì vậy tôi đã nêu lên câu hỏi của bạn).
Tôi đã có ý tưởng sử dụng iwatch / inotify để tạo thư mục bên trong / Proc nhưng dường như nó không hoạt động, cũng không phải là audctl. Có vẻ như sự lựa chọn tốt nhất của bạn, mặc dù bẩn, là liên tục phân tích ps để thay đổi từ một kịch bản. Mã Perl sau đây sẽ làm điều đó, mặc dù sẽ dễ bị bỏ sót một số và bỏ qua ps
(vì nếu không nó sẽ tự kích hoạt):
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"; } } }
Cách tốt nhất tôi có thể nghĩ đến là xây dựng thư viện snoopy . snoopy là một thư viện chia sẻ rất nhỏ được nối vào /etc/ld.so.preload
và kết thúc execve()
các cuộc gọi hệ thống. Nó có thể được cấu hình để ghi nhật ký tất cả exec()
, hoặc chỉ những người từ gốc. Trong phiên bản hiện tại của nó, snoopy đăng nhập vào syslog mỗi khi một sự kiện phù hợp (một tòa nhà chọc trời execve()
) xảy ra. Tuy nhiên, đây không phải là một chương trình lớn (nhiều nhất là vài trăm dòng mã) và có thể được sửa đổi mà không gặp nhiều khó khăn để thực thi tập lệnh thay vì (hoặc thêm vào) ghi nhật ký hoạt động. Snoopy được viết bằng C.
Một số điều cần lưu ý: