setuid 遇到理解困难

huangapple go评论70阅读模式
英文:

setuid trouble understanding

问题

I read about setuid and I didn't understand the term in 100%.
As I understand: setuid allow users to run an executable with the file system permissions of the executable's owner or group respectively and to change behavior in directories. (from Wikipedia).

But, I can't see a difference between:

-rwsr--r-- ::: you set to owner (rws is the owner) the setuid, so in other words you set to owner the owner permissions.
so there is no effect, right?

-rwxr--r-- ::: is equal to the previous example, because as I said, already talk about the owner, so it doesn't matter to add the owner the owner permissions.

THANKS FOR HELPS!

英文:

I read about setuid and I did'nt understand the term in 100%.
As I undetstand: setuid allow users to run an executable with the file system permissions of the executable's owner or group respectively and to change behaviour in directories. (from Wikipedia).

But, I can't see a difference between:

-rwsr--r-- ::: you set to owner (rws is the owner) the setuid, so in other words you set to owner the owner permissions.
so there is no effect, right?

-rwxr--r-- ::: is equal to the previous example, beacuse as I said, already talk about the owner so it's does'nt matter to add the owner the owner permissions.

THANKS FOR HELPS!

答案1

得分: 2

当您运行启用了 setuid 位的可执行文件时,它将以所有者的身份而不是运行可执行文件的用户的身份运行。因此,如果您有一个所有者是 root 并启用了 setuid 的可执行文件,该可执行文件将以 root 而不是运行可执行文件的用户的身份运行。

来自手册:

setuid() 设置调用进程的有效用户ID。如果调用进程具有特权(更确切地说:如果进程在其用户命名空间中具有 CAP_SETUID 能力),则还设置了实际UID和保存的设置用户ID。

在Linux下,setuid() 的实现方式与带有 _POSIX_SAVED_IDS 特性的POSIX版本相同。这允许一个设置用户ID(不是root)的程序以安全的方式放弃所有用户特权,执行一些非特权工作,然后重新以原始的有效用户ID重新运行。

如果用户是root或程序是设置用户ID-root,必须特别小心:setuid() 检查调用者的有效用户ID,如果它是超级用户,则将所有与进程相关的用户ID设置为uid。在发生这种情况后,程序无法重新获得root特权。

因此,希望临时放弃root特权,假装成非特权用户身份,然后重新获得root特权的设置用户ID-root程序不能使用setuid()。您可以使用seteuid(2)来实现这一点。

您可以使用以下代码进行验证:

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

int main(void){

    int val;
    printf("The real user ID is %d\n", getuid());
    printf("The effective user ID is %d\n", geteuid());

    return 0;

}

编译并设置setuid:

gcc uid.c -o uid
sudo chown root.root uid
ls -la uid
-rwxr-xr-x 1 root root 16712 Jul 10 11:59 uid
./uid                   
The real user ID is 1000
The effective user ID is 1000
sudo chmod 4755 uid     
ls -la uid         
-rwsr-xr-x 1 root root 16712 Jul 10 11:59 uid
./uid              
The real user ID is 1000
The effective user ID is 0

请注意,以上代码示例是为了演示setuid()的行为而提供的,不应在生产环境中滥用setuid()。

英文:

When you run a executable with setuid bit enabled, it is run with the identity of the owner instead the user that is running the executable. Thus, if you has a executable which the owner is root and the setuid is enabled, the executable will run as root instead the user that is running the executable.

From man:

   setuid() sets the effective user ID of the calling process.  If
   the calling process is privileged (more precisely: if the process
   has the CAP_SETUID capability in its user namespace), the real
   UID and saved set-user-ID are also set.

   Under Linux, setuid() is implemented like the POSIX version with
   the _POSIX_SAVED_IDS feature.  This allows a set-user-ID (other
   than root) program to drop all of its user privileges, do some
   un-privileged work, and then reengage the original effective user
   ID in a secure manner.

   If the user is root or the program is set-user-ID-root, special
   care must be taken: setuid() checks the effective user ID of the
   caller and if it is the superuser, all process-related user ID&#39;s
   are set to uid.  After this has occurred, it is impossible for
   the program to regain root privileges.

   Thus, a set-user-ID-root program wishing to temporarily drop root
   privileges, assume the identity of an unprivileged user, and then
   regain root privileges afterward cannot use setuid().  You can
   accomplish this with seteuid(2).

You can verify this with the following code:

#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;

int main(void){

    int val;
    printf(&quot;The real user ID is %d\n&quot;, getuid());
    printf(&quot;The effective user ID is %d\n&quot;, geteuid());

    return 0;

}

Compile and setuid:

gcc uid.c -o uid
sudo chown root.root uid
ls -la uid
-rwxr-xr-x 1 root root 16712 Jul 10 11:59 uid
./uid                   
The real user ID is 1000
The effective user ID is 1000
sudo chmod 4755 uid     
ls -la uid         
-rwsr-xr-x 1 root root 16712 Jul 10 11:59 uid
./uid              
The real user ID is 1000
The effective user ID is 0

答案2

得分: 1

你已经从 sinkmanu 得到了一个非常完整的答案。但也许举个例子来说明为什么我们需要 SetUID 会更清楚:

看看你的系统上的 passwd 命令。作为一个 普通用户,你可以使用这个命令来更改你的密码。但要实际执行此操作,它必须更改仅由 root 访问的系统文件。通常情况下,它会以你的用户身份运行,因此无法访问例如 /etc/shadow,更不用说写入它了。但多亏了 SetUID 位,该命令实际上会以其所有者 root 的身份执行。

$ ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 33K Feb  7  2022 /usr/bin/passwd*

注意:如果你有 root 权限,你可以创建自己的 SetUID 程序。但请注意,这可能会带来安全风险。安全扫描通常还会扫描系统上已启用 SetUID 的未知程序,并向管理员发出警报。

英文:

You already have a very complete answer from sinkmanu. But maybe an example to clarify why we need SetUID:

Check out the passwd command on your system. As a regular user you can change your password with this command. But to actually do this it has to change system files which are only accessible by root. Normally it would run as your user so it won't be able to access /etc/shadow for example, let alone write to it. But thanks to a SetUID bit the command will actually execute as it's owner which is root.

$ ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 33K Feb  7  2022 /usr/bin/passwd*

Note: If you have root access you can create your own SetUID programs. But be aware that this potentially poses a security risk. Security scans will often also scan a system for unknown programs with the SetUID turned on and alert the admins.

huangapple
  • 本文由 发表于 2023年7月10日 17:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76652521.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定