sudo 的内部是如何工作的?

sudo 的内部是如何工作的?

内部如何sudo运作?与root不同,它怎么可能在没有root密码的情况下成为root su?该过程涉及哪些系统调用等?这难道不是 Linux 中的一个巨大的安全漏洞吗(例如,为什么我不能编译一个经过大量修补的版本sudo,它只执行常规操作sudo,但不要求非特权用户的密码)?

我读过了登录和 su 内部结构。我也读过sudo 是如何使用的?但尽管有标题,它们主要处理su和之间的差异sudo

答案1

如果你看一下可执行文件sudo

$ which sudo
/usr/bin/sudo
$ ls -la /usr/bin/sudo
---s--x--x 2 root root 208808 Jun  3  2011 /usr/bin/sudo

您会注意到它带有权限位---s--x--x。这些可以细分如下:

-|--s|--x|--x
-      - first dash denotes if a directory or a file ("d" = dir, "-" = file)  
--s    - only the setuid bit is enabled for user who owns file
--x    - only the group execute bit is enabled
--x    - only the other execute bit is enabled

因此,当一个程序启用了 setuid 位(也称为 SUID)时,这意味着当有人运行该程序时,它将使用拥有该文件的用户的凭据运行,即。在这种情况下扎根。

例子

如果我以用户 saml 身份运行以下命令:

$ whoami
saml

$ sudo su -
[sudo] password for saml: 

您会注意到,sudo实际上是以 root 身份运行的:

$ ps -eaf|grep sudo
root     20399  2353  0 05:07 pts/13   00:00:00 sudo su -

setuid机制

如果您好奇 SUID 的工作原理,请查看man setuid.这是手册页的摘录,它比我能更好地解释它:

setuid() 设置调用进程的有效用户 ID。如果调用者的有效UID是root,则真实UID和保存的set-user-ID也被设置。在 Linux 下,setuid() 的实现方式与具有 _POSIX_SAVED_IDS 功能的 POSIX 版本类似。这允许设置用户 ID(root 除外)程序放弃其所有用户权限,执行一些非特权工作,然后以安全的方式重新使用原始有效用户 ID。

如果用户是root或者程序是set-user-ID-root,则必须特别小心。 setuid() 函数检查调用者的有效用户 ID,如果它是超级用户,则所有与进程相关的用户 ID 都设置为 uid。发生这种情况后,程序就不可能重新获得root权限。

这里的关键概念是程序有一个真实的用户 ID (UID) 和一个有效的用户 ID (EUID)。当该位使能时,Setuid 正在设置有效用户 ID (EUID)。

因此,从内核的角度来看,在我们的示例中,saml仍然是原始所有者 (UID),但 EUID 已设置为可执行文件的所有者。

设置gid

我还应该提到,当我们分解 sudo 命令的权限时,第二组位用于组权限。组位也有类似于 setuid 的东西,称为设置组 id(又名 setgid、SGID)。这与 SUID 执行相同的操作,只不过它使用组凭据而不是所有者凭据运行进程。

参考

答案2

真正的sudo二进制是setuid 根,并且您不能只是将这样设置的文件存在。

setuid 和 setgid(分别是“执行时设置用户 ID”和“执行时设置组 ID”的缩写)[1] 是 Unix 访问权限标志,允许用户分别以可执行文件所有者或组的权限运行可执行文件,更改目录中的行为。

答案3

为了回答似乎没有人接触过的有关系统调用的部分,重要的系统调用之一是 setresuid() 或 setresgid()。我确信还有其他的,但这两个似乎非常特定于 setuid/sudo。

相关内容