root 用户与其他用户的区别到底是什么?

root 用户与其他用户的区别到底是什么?

某些任意帐户和 之间的根本区别是什么root?难道只是UID零以外的存在吗?

那么,到底是做什么的二进制它如何将用户提升为root?我知道用户必须首先sudo通过我们在 中找到的内容成为该组的一部分/etc/sudoers

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

查看su我们发现的可执行文件的权限-rwsr-xr-x, 或者4755(即已setuid设置)。

是不是读取此配置文件并检查请求 root 权限的用户是否属于任一组的二进制文件须藤或者行政?如果是这样,二进制文件是否会生成另一个 shell 作为 root(考虑到设定值位)假设用户是预期组的一部分并且知道尝试替换的适当用户的密码(例如, 尤其)?


太长了;博士 特权提升行为是否依赖setuid二进制文件,还是有其他机制来更改当前进程的 UID?对于前者,似乎只有 EUID 会改变,留下 UID != EUID。这有问题吗?

有关的 这一切是如何在 Android 环境中模拟的?据我所知,对 root 的访问已被完全剥夺——尽管进程仍然在此特权级别上运行。

如果我们删除sudosu这是否足以防止特权提升,或者 Android 是否采取了进一步的措施?

答案1

root 是用户 0

关键是用户 ID 0。内核中有很多地方会检查调用进程的用户 ID,只有当用户 ID 为 0 时才授予执行某些操作的权限。

用户名无关紧要;内核甚至不知道用户名。

Android的权限机制在内核层面是相同的,但在应用程序层面却完全不同。 Android 有一个 root 用户(UID 0),就像任何其他基于 Linux 内核的系统一样。 Android 没有用户帐户,并且在大多数设置中不允许用户(如操作和拥有设备的人)以根用户身份执行操作。 “root”Android 是一种允许设备所有者/用户以 root 身份执行操作的设置。

setuid 的工作原理

A设定值可执行文件以拥有该可执行文件的用户身份运行。例如,su它是 setuid 并由 root 拥有,因此当任何用户运行它时,正在运行的进程su都会以 root 用户身份运行。的工作su是验证调用它的用户是否可以使用 root 帐户,如果验证成功则运行指定的命令(如果未指定命令则运行 shell),如果验证失败则退出。例如,su可能会要求用户证明他们知道 root 密码。

更详细地说,一个进程有三个用户 ID: 这有效的UID,用于安全检查;这真实的UID,用于一些权限检查,但主要用作原始用户 ID 的备份,以及保存的用户 ID,它允许进程暂时将其有效 UID 切换到真实用户 ID,然后再返回到之前的用户 ID有效的 UID(例如,当 setuid 程序需要以原始用户身份访问文件时,这很有用)。运行 setuid 可执行文件将有效 UID 设置为可执行文件的所有者并保留真实 UID。

运行 setuid 可执行文件(以及类似的机制,例如 setgid)是提升进程权限的唯一方法。几乎所有其他事情都只会降低进程的特权。

超越传统 Unix

到目前为止,我描述了传统的 Unix 系统。所有这些在现代 Linux 系统上都是如此,但 Linux 带来了一些额外的复杂性。

Linux 有一个能力系统。还记得我说过内核有很多检查,其中只允许以用户 ID 0 运行的进程吗?事实上,每个检查都有自己的功能(嗯,不完全是,有些检查使用相同的功能)。例如,有访问原始网络套接字的功能,以及重新启动系统的功能。每个进程都有一组与其用户和组相关的功能。如果进程以用户 0 身份运行或者具有与检查相对应的功能,则该进程通过检查。需要特定权限的进程可以作为非 root 用户运行,但具有必要的功能;如果进程存在安全漏洞,这会限制影响。可执行文件可以设置为一项或多项功能:这与 setuid 类似,但适用于进程的功能集而不是进程的用户 ID。例如,ping只需要原始网络套接字,因此可以使用setcapCAP_NET_RAW而不是setuid root。

Linux 有几个安全模块,最有名的是SELinux。安全模块引入了额外的安全检查,甚至可以应用于以 root 身份运行的进程。例如,可以(不容易!)设置 SELinux 以便以用户 ID 0 运行一个进程,但有太多限制,实际上它无法执行任何操作

Linux 有用户命名空间。在内核内部,用户实际上不仅仅是一个用户ID,而是由用户ID和命名空间组成的一对。命名空间形成层次结构:子命名空间在其父命名空间中细化权限。全权用户是根命名空间中的用户 0。命名空间中的用户 0 仅在该命名空间内拥有权力。例如,用户命名空间中的用户 0 可以模拟该命名空间的任何用户;但从外部来看,该命名空间中的所有进程都以同一用户身份运行。

答案2

Linux 中有 4 个 UID:鲁伊德(真实的),欧盟用户识别码(有效的),苏伊德(已保存),FSUID(文件系统)。

这些只不过是数字,是进程的属性,它们存储在内核进程表的控制块中。

UID'0'有一个特殊的特征,因为它表示用户root,通常具有不受限制的访问权限。

susudo是更改用户有效访问权限的程序,方法是启动一个新的子进程,并通过 的 SetUID 位将 EUID 设置为新的 UID su。然后,此 su 进程在新的子进程中再次生成一个新的 shell,并将 4 个 UID 设置为新的 UID 值。

下面的例子应该证明这一点。假设用户rda通过 ssh 终端登录。ps fax将显示涉及以下过程:

472 ?        Ss     0:00 /usr/sbin/sshd -D
9151 ?        Ss     0:00  \_ sshd: rda [priv]
9153 ?        S      0:00  |   \_ sshd: rda@pts/1
9154 pts/1    Ss+    0:00  |       \_ -bash

4个进程,ssh守护进程,两个进程用于ssh会话(和终端?),最后一个进程是登录shell(-前面用a表示bash

ps faw -eo euser,ruser,suser,fuser,f,comm将显示进程的 UID:

EUSER    RUSER    SUSER    FUSER    F COMMAND
...
root     root     root     root     4 sshd
root     root     root     root     4  \_ sshd
rda      rda      rda      rda      5  |   \_ sshd
rda      rda      rda      rda      0  |       \_ bash

成功验证后调用su将导致以下结果:

EUSER    RUSER    SUSER    FUSER    F COMMAND
...
root     root     root     root     4 sshd
root     root     root     root     4  \_ sshd
rda      rda      rda      rda      5  |   \_ sshd
rda      rda      rda      rda      0  |       \_ bash
root     rda      root     root     4  |           \_ su
root     root     root     root     4  |               \_ bash

'bash' 进程启动一个新的 'su' 子进程,其 EUID 由 SetUID 位设置为'0'(root),此时 RUID 仍设置为 rda 的 UID。 “su”进程再次使用新的 shell 启动一个新的子进程,授予用户 root 访问权限(RUID 现在'0'也设置为)。用户保留在其工作目录中,新 shell 将使用与父 shell 相同的环境,例如:

server:/home/rda# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
server:/home/rda# pwd
/home/rda

可以使用 关闭 shell exit,并且用户将使用其原始访问权限进入父 shell。

如果使用连字符参数调用“su”,情况会有所不同'-'

rda@server:~$ su -
Password:
server:~# echo $PATH
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
server:~# pwd
/root

shell 环境已更改,因为新 shell 是登录 shell,请参阅'-su',它执行一些额外的配置脚本:

 9151 ?        Ss     0:00  \_ sshd: rda [priv]
 9153 ?        S      0:00  |   \_ sshd: rda@pts/1
 9154 pts/1    Ss     0:00  |       \_ -bash
 9613 pts/1    S      0:00  |           \_ su -
 9614 pts/1    S+     0:00  |               \_ -su

登录 shell 应使用 关闭logout

从理论上讲,我认为可以通过删除sudo和来阻止用户获得提升的权限su,并且不允许用户直接登录系统(通过终端、ssh 等)并且无法物理访问设备。

更新:Android 上的 Root 过程

正如详细解释的那样这里,对 Android 设备进行 root 的可能方法取决于引导装载程序Android系统属性 ro.secure

目标始终是相同的,即安装su二进制文件/system并制作它setuid(0)

具有解锁引导加载程序的设备:

dd从设备中提取库存 ROM ,添加su、重新打包(或下载此类修改后的 ROM),以闪存模式重新启动设备并刷新修改后的 ROM。

ro.secure=0 的设备:

此系统属性控制在 中键入的命令adb shell是作为 root ( ro.secure=0) 还是作为非特权用户 ( ro.secure=1) 运行。 的值ro.secure是在引导时从目录default.prop中的文件设置的root,该目录只能由用户 root 访问,因此是安全的。

在大多数情况下,此ro.secure设置为1,但某些制造商将其设置为0。可以通过getprop ro.secure在设备上的终端模拟器或 adb shell 中运行命令来检查这一点。如果设置为0,root很容易,连接到计算机,运行adb,挂载/system为读写,安装su

引导加载程序已锁定的设备:

此类设备的恢复功能不允许刷新未经制造商签名的自定义 ROM。在这种情况下获得 root 访问权限的唯一方法是利用正在运行的系统进程之一中的安全漏洞(该进程以特权模式运行),并对其进行攻击以允许执行“任意代码”。此代码通常会永久挂载/system和安装su

答案3

一般来说,只是有效 uid 为 0。可执行文件上的“setuid”位实际上设置了有效的进程的uid。如果有效 uid 不为零且真实 uid 不为零,则程序正在以“非特权”用户身份运行。以下内容适用:

非特权进程只能将有效用户ID设置为真实用户ID、有效用户ID或保存的设置用户ID。非特权用户只能将真实用户ID设置为真实用户ID或有效用户ID。

就 Android 而言,不,我认为删除sudosu就足够了——如果任何程序可以设置 seteuid 位,则该程序可能会以 uid = 0 运行。内部文件系统在任何时候都可以作为root,那么可以引入这样的程序并且root访问是可行的。

相关内容