是否可以在每个进程创建时挂钩脚本执行?
本质上相当于 inotifywait 来监视磁盘活动,但应用于进程表。
它将允许在进程生成时执行操作,例如记录它、cgset 等等。我可以看到它将递归地应用于新流程的挑战。但是,有没有更好的方法,而不是尽快轮询进程表以捕获容易受到竞争条件影响的更改。
谢谢
答案1
首先,进程创建很少是需要记录的有用事件,并且与安全性无关(资源限制除外)。我认为你的意思是挂钩程序的执行,这是由execve
, 不是fork
。
其次,您引用的用例通常最好使用为此目的而设计的现有机制,而不是自行推出。
- 对于日志记录,BSD 进程会计提供少量信息,并且适用于大多数 Unix 变体;在 Linux 上,安装GNU 会计实用程序(从您的发行版安装软件包)。对于 Linux 上更复杂的日志记录,您可以使用审计子系统(这
auditctl
手册页有示例;正如我上面所解释的,您想要记录的系统调用是execve
)。 - 如果您想对某些程序应用安全限制,请使用安全框架,例如SELinux或者应用装甲。
- 如果要在容器中运行特定程序或使用某些设置,请移动可执行文件并将包装器脚本放在其位置,以设置所需的设置并调用原始可执行文件。
如果要修改一个特定程序调用其他程序的方式,而不影响其他程序的行为方式,则有两种情况:该程序可能具有潜在的敌意。
- 如果该程序可能存在恶意,请在专用虚拟机中运行它。
- 如果程序是协作的,最明显的攻击角度就是使用不同的
PATH
.如果程序使用了不易配置的绝对路径,在非古董Linux系统上,可以在单独的目录中运行它挂载命名空间(也可以看看内核:命名空间支持)。如果您确实需要精细控制,您可以加载一个库,通过使用 调用程序来覆盖某些库调用LD_PRELOAD=my_override_library.so theprogram
。看执行前重定向文件描述符举个例子。请注意,除了 之外execve
,您还需要重写execve
内部调用的所有 C 库函数,因为LD_PRELOAD
不会影响内部 C 库调用。您可以通过运行以下程序获得更精确的控制ptrace
;这允许您覆盖系统调用,即使它是由 C 库函数进行的,但它更难设置(我不知道有什么简单的方法可以做到这一点)。
答案2
//fakeExec.c
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
int execve(const char *path, char *const argv[], char *const envp[]) {
printf("Execing \"%s\"\n", path);
return syscall(SYS_execve, path, argv, envp);
}
在终端中:
$ gcc -fPIC -shared fakeExec.c -o fakeExec.so
$ export LD_PRELOAD=$PWD/fakeExec.so
现在您应该将每个新执行的文件记录到stdout
.
叉子包装显然需要更多的工作才能完成。
( 简单的fork
包装器(与上面类似,但 forfork
而不是execve
)可以工作,但会setgpid
在用它生成的进程中导致一些错误。
显然 libcfork
函数有一些额外的东西,我不太明白。 )