Linux SUID 提权


1. 先看普通文件权限

1.1 查看文件当前权限

1
2
3
ls -l filename

-rw-r--r-- 1 username username 138 Mar 28 15:12 test.jwt

下面按字段拆开理解这个输出。

-rw-r--r--:文件类型与权限

  • 第 1 个字符 -:代表这是一个普通文件

    接下来每三个字符为一组,分别代表:

    • 文件所有者(Owner)
    • 文件所属组(Group)
    • 其他所有人(Others)
  • 第 2-4 个字符 rw-:代表**文件所有者(Owner)**的权限。username(用户)拥有可读(r)和可写/修改(w)权限,但不能执行(执行位是 -)。

  • 第 5-7 个字符 r--:代表**文件所属组(Group)**的权限。同属于 username 用户组的其他成员只能读取(r),不能修改。

  • 第 8-10 个字符 r--:代表**其他所有人(Others)**的权限。同样是只能读取(r)。

1:硬链接数

  • 表示有 1 个文件名指向该文件的物理数据块(普通文件通常都是 1)。

username:文件所有者

  • 这个文件的拥有者是用户 username

username:文件所属的用户组

  • 这个文件被分配给了名为 username 的用户组。在 Linux 系统中,创建一个新用户时,通常会自动创建一个与用户名同名的专属用户组。

138:文件大小

  • 文件大小为 138 字节(Bytes)

Mar 28 15:12:最后修改时间

test.jwt:文件名


2. 如何判断一个文件是否设置了 SUID

要查看一个文件是否设置了 SUID(Set-User-ID) 权限,依然只需要使用我们刚才讨论过的 ls -l 命令。

关键在于观察文件权限的 第 4 个字符,也就是文件所有者(Owner)执行权限 x 所在的位置

正常的权限如果是 rwx,加上 SUID 后会出现以下情况。

2.1 出现小写字母 s(最常见且有效)

  • 示例: -rwsr-xr-x
  • 含义: 这个文件原本就拥有执行权限(x),并且被设置了 SUID。这是 SUID 的正常工作状态。

2.2 出现大写字母 S(通常是配置错误)

  • 示例: -rwSr--r--
  • 含义: 这个文件被设置了 SUID,但是它本身并没有执行权限(原本是 -)。因为文件连运行都运行不了,所以这个 SUID 其实是无效的。系统用大写 S 来提醒你这里存在逻辑冲突。

2.3 如果没有 s

  • 输出的权限中没有 s,则表示尚未设置 SUID。

可以直接看一个常见例子:

1
2
ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 114072 Sep 17 2025 /usr/bin/passwd

3. 如何设置 SUID

设置 SUID 时,通常使用 chmod 命令。

3.1 基本语法

语法结构是:

chmod [谁][操作][权限] 文件名

1)[谁](Who)

  • u(User)= 文件所有者
  • g(Group)= 所属群组
  • o(Others)= 其他人
  • a(All)= 所有人(等同于 ugo

2)[操作](Operator)

  • + = 添加权限
  • - = 移除权限
  • = = 设定为唯一权限(覆盖原有权限)

3)[权限](Permission)

  • r
  • w
  • x
  • s

3.2 设置命令示例

1
chmod u+s filename
  • u+s 表示给文件所有者(user)增加 SUID 权限。

3.3 确认设置结果

再次查看文件权限:

1
ls -l filename

如果文件权限中显示类似 -rwsr-xr-x(注意 s),说明 SUID 设置成功。


4. 如何查找已有 SUID 的文件

在渗透测试或提权场景中,最常做的一步就是先把系统里已有的 SUID 文件找出来。

4.1 常用查找命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
find / -user root -perm -4000 2>/dev/null
find / -perm -4000 -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null

#find / -perm -u=s -type f 2>/dev/null
#/表示从文件系统的顶部(根)开始并找到每个目录
#-perm 表示搜索随后的权限
#-u = s表示查找root用户拥有的文件
#-4000:查找 SUID 文件(权限位的 SUID 为 4)
#-type表示我们正在寻找的文件类型
#f 表示常规文件,而不是目录或特殊文件
#2表示该进程的第二个文件描述符,即stderr(标准错误)
#>表示重定向
#/dev/null是一个特殊的文件系统对象,它将丢弃写入其中的所有内容。

4.2 每条命令的含义

1)find / -user root -perm -4000 2>/dev/null

作用:只找那些“属于 root 且带有 SUID”的文件,并打印路径。

  • -user root:增加了一个过滤条件,文件拥有者必须是最高管理员 root。这是渗透测试中最常敲的命令,因为只有拿到属于 root 的 SUID 文件,黑客才有机会借此变成 root。

2)find / -perm -4000 -type f 2>/dev/null

作用:寻找全系统所有带有 SUID 的“普通文件”(不限拥有者)。

  • -type f:指定只查找普通文件(file)。排除了目录、软链接等其他类型,让结果更精准。
  • 注意这里去掉了 -user root,所以它也会把你系统中其他普通用户设置了 SUID 的文件一并找出来。

3)find / -perm -u=s -type f 2>/dev/null

作用:和第 2 条命令的效果 100% 一样,只是写法不同。

  • -perm -u=s:这里使用了符号表示法来代替数字表示法。-u=s 的意思就是“User(所有者)被设置了 S 权限”。

4)find / -user root -perm -4000 -exec ls -ldb {} \;

作用:不仅找出 root 的 SUID 文件,还会立刻把它们的详细权限信息列出来。

这条命令最长,但也最实用,因为它能让你直接看到文件的详细状态。

  • -exec ... {} \;:这是 find 命令的高级玩法。它的意思是:对每一个找到的文件(用 {} 代表),都去执行后面的那串命令,最后用 \; 结尾。
  • ls -ldb:也就是对找到的文件执行 ls
    • l:使用长格式(就像你一开始问的那样,显示 -rwsr-xr-x 详细信息)。
    • d:如果是目录,只显示目录本身的属性,不显示里面的内容。
    • b:这是一个安全参数(打印不可见字符的转义序列)。如果故意把文件名改成带换行符等奇怪字符的乱码,-b 可以把它们转义显示出来,防止终端显示错乱。

5.查询GTFOBins

访问GTFOBins搜索命令(github项目离线版下载),例如findlessawk

例如: 利用find

如果suid允许执行find

1
find . -exec /bin/sh -p \; -quit

6. 关于 $PATH 的理解

这一部分虽然不是直接讲 SUID,但它和命令执行路径、环境变量理解密切相关,放在一起很有参考价值。

1
2
3
4
5
6
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin:/sbin
/bin:/usr/games
/usr/local/games

当你敲下一个命令时,系统就会严格按照从上到下的顺序去这些目录里挨个查找。

为了更容易理解,我们可以先记住两个核心词根:

  • bin(binaries):存放普通用户就能用的常规命令(比如 lsfind)。
  • sbin(system binaries):存放只有管理员(Root)或者加了 sudo 才能执行的系统级管理命令(比如重启系统、格式化硬盘的命令)。

掌握了这两个词根后,再来看这份列表的具体分工就会清晰很多。

6.1 管理员定制区(最高优先级)

  • /usr/local/sbin:系统管理员自己手动编译、安装的底层系统管理命令
  • /usr/local/bin:系统管理员自己手动编译、安装的常规软件或命令
  • Linux 默认“管理员手动安装的软件优先级最高”。如果管理员装了一个新版本的工具,系统会优先用它,而不是系统自带的老版本。

6.2 官方标准软件区

  • /usr/sbin:通过官方应用商店(如 apt)安装的系统级管理命令
  • /usr/bin:通过官方应用商店安装的绝大多数普通命令(你的 find 原生文件就住在这里)。
  • 这是系统中程序最庞大、最集中的地方。

6.3 系统核心区

  • /sbin:系统启动、修复和最基础运行所必须的核心系统命令
  • /bin:系统启动和进入单用户模式(类似于 Windows 的安全模式)所必须的最基础常规命令

6.4 游戏区

  • /usr/games:系统官方包管理器安装的游戏。
  • /usr/local/games:你自己手动下载安装的游戏。
  • 把游戏和核心工作命令分开,是老派 UNIX 系统留下来的优良传统。