Omn*_*ous 3 c linux security setuid
我有这个小程序:
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <sys/prctl.h>
extern char **environ;
int main()
{
char * const arglist[] = { "/bin/ls", "-l", "/proc/self/maps", NULL };
uid_t uid, euid, suid;
gid_t gid, egid, sgid;
getresuid(&uid, &euid, &suid);
printf("Before: uid: %u, euid: %u, suid: %u\n", uid, euid, suid);
uid = euid;
setresuid(uid, euid, suid);
getresuid(&uid, &euid, &suid);
printf(" After: uid: %u, euid: %u, suid: %u\n", uid, euid, suid);
getresgid(&gid, &egid, &sgid);
printf("Before: gid: %u, egid: %u, sgid: %u\n", gid, egid, sgid);
gid = egid;
setresuid(gid, egid, sgid);
getresuid(&gid, &egid, &sgid);
printf(" After: gid: %u, egid: %u, sgid: %u\n", gid, egid, sgid);
printf("Get result == %d\n", prctl(PR_GET_DUMPABLE, 0, 0, 0, 0));
printf("Set result == %d\n", prctl(PR_SET_DUMPABLE, 1, 0, 0, 0));
printf("Get result == %d\n", prctl(PR_GET_DUMPABLE, 0, 0, 0, 0));
if (fork())
{
return 0;
}
execve(arglist[0], arglist, environ);
}
Run Code Online (Sandbox Code Playgroud)
我将此程序编译为名为的可执行文件small-test,并将其所有权更改为测试用户:
[omnifarious@foohost ~]$ ls -l small-test
-rwxrwxr-x. 1 testing testing 8512 Oct 23 12:55 small-test
Run Code Online (Sandbox Code Playgroud)
然后我运行该程序:
[omnifarious@foohost ~]$ ./small-test
Before: uid: 1001, euid: 1001, suid: 1001
After: uid: 1001, euid: 1001, suid: 1001
Before: gid: 1001, egid: 1001, sgid: 1001
After: gid: 1001, egid: 1001, sgid: 1001
Get result == 1
Set result == 0
Get result == 1
-r--r--r--. 1 hopper hopper 0 Oct 23 14:50 /proc/self/maps
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。然后我这样做:
[omnifarious@foohost ~]$ sudo chmod ug+s ./small-test
[omnifarious@foohost ~]$ ls -l ./small-test
-rwsrwsr-x. 1 testing testing 8512 Oct 23 12:55 ./small-test
[omnifarious@foohost ~]$ ./small-test
Before: uid: 1001, euid: 1002, suid: 1002
After: uid: 1002, euid: 1002, suid: 1002
Before: gid: 1001, egid: 1002, sgid: 1002
After: gid: 1002, egid: 1002, sgid: 1002
Get result == 0
Set result == 0
Get result == 1
-r--r--r--. 1 root root 0 Oct 23 12:59 /proc/self/maps
Run Code Online (Sandbox Code Playgroud)
为什么/proc/self/maps最终被拥有root而不是被testingor拥有omnifarious?请注意,如果我删除fork.
这让我烦恼的原因是我需要创建一个程序,将自己作为执行它的用户之外的用户放入命名空间中。这样我就无法访问启动该程序的用户拥有的 cgroup 和其他内容。但我不被允许写入程序的uid_mapor gid_map,因此我无法正确设置名称空间。
注意:我编辑了这个问题,以包含对prctl设置(和读取)DUMPABLE标志的调用作为答案(和手册),表明重置此问题应该修复/proc/self/*文件的所有者。正如您在新程序中看到的那样,事实并非如此。
编辑:上面的程序有一个错误,它正在调用setresuid而不是setresgid. 即使将调用添加到prctl. prctl(PR_SET_DUMPABLE, 1);如果进程的真实有效组和用户 ID 不相同,则调用无效。
出于安全原因,任何 suid 进程都默认将其/proc/self目录归 root 所有(以防止用户引发核心转储并检查其内存以获取有价值的信息)。
suid您可以通过使用 prctl 手动使进程可转储来在 a 之后设置所有者PR_SET_DUMPABLE。
这里proc(5)包含对正在发生的事情以及如何影响它的描述:
/proc/[pid]\n There is a numerical subdirectory for each running\n process; the subdirectory is named by the process\n ID.\n\n Each /proc/[pid] subdirectory contains the pseudo-\n files and directories described below. These\n files are normally owned by the effective user and\n effective group ID of the process. However, as a\n security measure, the ownership is made root:root\n if the process\'s "dumpable" attribute is set to a\n value other than 1. This attribute may change for\n the following reasons:\n\n * The attribute was explicitly set via the\n prctl(2) PR_SET_DUMPABLE operation.\n\n * The attribute was reset to the value in the\n file /proc/sys/fs/suid_dumpable (described\n below), for the reasons described in prctl(2).\n\n Resetting the "dumpable" attribute to 1 reverts\n the ownership of the /proc/[pid]/* files to the\n process\'s real UID and real GID.\nRun Code Online (Sandbox Code Playgroud)\n\n下面,suid_dumpable说明为什么默认值是这样的:
1 ("debug")\n All processes dump core when possible.\n (Reasons why a process might nevertheless\n not dump core are described in core(5).)\n The core dump is owned by the filesystem\n user ID of the dumping process and no secu\xe2\x80\x90\n rity is applied. This is intended for sys\xe2\x80\x90\n tem debugging situations only: this mode is\n insecure because it allows unprivileged\n users to examine the memory contents of\n privileged processes.\nRun Code Online (Sandbox Code Playgroud)\n\n作为奖励,prctl(2)列出了影响可倾销性的非 Suid 情况:
PR_SET_DUMPABLE (since Linux 2.3.20)\n (...)\n Normally, this flag is set to 1. However, it is\n reset to the current value contained in the file\n /proc/sys/fs/suid_dumpable (which by default has\n the value 0), in the following circumstances:\n\n * The process\'s effective user or group ID is\n changed.\n\n * The process\'s filesystem user or group ID is\n changed (see credentials(7)).\n\n * The process executes (execve(2)) a set-user-ID\n or set-group-ID program, resulting in a change\n of either the effective user ID or the effec\xe2\x80\x90\n tive group ID.\n (...)\nRun Code Online (Sandbox Code Playgroud)\n