/etc/shadow 和南方的困境

/etc/shadow and suid dilemma

我偶然发现了有关使用 suid 可执行文件访问系统文件的问题。

我写了这个简短的 POC:

#include <unistd.h>
#include <stdio.h>

int main()
{
    if (access("/etc/shadow", W_OK) == 0)
        printf("shadow writable!\n");
    else
        printf("shadow not writable\n");

    return 0;
}

然后我用 chown root:rootchmod u+s 编译并给它 suid(运行 by root)

这是生成的可执行文件

-rwsrwxr-x  1 root root     4847 Apr 14 08:40 a.out

目标文件具有这些权限

-rw------- 1 root root 1836 Oct  8  2014 /etc/shadow

当我运行程序时,它给出了这个输出:

[d.berra@srvr ~]$ ./a.out
shadow not writable

为什么会这样?我的意思是...我正在以 rootroot CAN 的方式访问文件!

注意:selinux 已禁用

想法?

来自access

The check is done using the calling process's real UID and GID, rather than the effective IDs as is done when actually attempting an operation (e.g., open(2)) on the file. This allows set-user-ID programs to easily determine the invoking user's authority.

所以你可以成功打开这个文件进行写入,因为你的有效UID和文件系统UID现在是0,但是访问仍然会return错误。

如@nos 所述,您忘记将可执行文件所有者更改为 root:

$ sudo chown root:root ./a.out

但即使您这样做,由于 access 行为,您仍然会得到 "not writable":

$ ls -l ./a.out 
-rwsr-xr-x 1 root root 12651 Apr 14 09:53 ./a.out
$ ./a.out 
shadow not writable

您设置了 suid 位,这意味着可执行文件将 运行 作为拥有该可执行文件的用户。可执行文件将 运行 作为 d.berra,无法写入 /etc/shadow.

如果您希望可执行文件 运行 成为 root 而不管 运行 它的用户是谁,除了设置 suid 位之外,可执行文件还应归 root 所有。

试试这个:

#include <unistd.h>
#include <stdio.h>

int main()
{
    setuid(0);

    if (access("/etc/shadow", W_OK) == 0)
        printf("shadow writable!\n");
    else
        printf("shadow not writable\n");

    return 0;
}

它将用户ID设置为root以便能够访问该文件。 setuid(0) 仅在有效用户 ID 也为 0 的情况下有效。