cve-2021-3156的poc流程分析
字数 1607 2025-08-10 08:28:35
CVE-2021-3156 (Sudo堆溢出漏洞) POC流程分析
漏洞概述
CVE-2021-3156是Sudo程序中的一个堆缓冲区溢出漏洞,由Qualys安全团队发现并命名为"Baron Samedit"。该漏洞存在于Sudo的set_cmnd函数中,允许本地攻击者通过精心构造的参数在无需身份验证的情况下获得root权限。
前置知识
1. Linux动态链接库机制
- LD_PRELOAD环境变量:允许用户在程序运行前预加载指定的共享库
- 常用于PHP的bypass_disable_function攻击中
- 攻击方式:
- 通过设置LD_PRELOAD加载恶意动态链接库
- 可以重写函数或使用
__attribute__特殊函数直接执行恶意代码
- 限制:glibc对setuid程序有验证,会禁用LD_PRELOAD加载
2. SUID文件特性
- SUID (Set User ID)文件允许执行者以文件所有者权限运行
- 典型例子:/usr/bin/sudo,普通用户执行时具有root权限
- 安全限制:SUID程序运行时环境变量受到严格限制
漏洞原理分析
漏洞位置
漏洞存在于sudoers.so模块的set_cmnd函数中,该函数在处理命令行参数时存在堆缓冲区溢出。
关键漏洞代码行为
set_cmnd函数中to变量分配的缓冲区大小有限(0x70字节)- 处理转义字符时逻辑错误:
- 当遇到
\字符时,from指针会向后移动一位 - 然后写入
\x00到to缓冲区 from指针再次增加,跳过后续字符- 导致可以写入超出分配缓冲区大小的数据
- 当遇到
利用条件
- 需要构造特定的命令行参数触发溢出
- 溢出数据可以覆盖堆中的关键数据结构
- 最终目标是修改
service_user结构体,加载恶意动态链接库
POC流程详细分析
环境准备
- 下载与系统相同版本的sudo源码(示例使用sudo 1.8.21)
- 编译安装调试版本sudo:
./configure --enable-debug make make install - 复制生成的可执行文件并设置SUID权限:
cp /usr/bin/sudo /usr/bin/sudd chown root:root /usr/bin/sudd chmod u+s /usr/bin/sudd
调试过程
-
初始调试设置:
- 在
hax.c的execve处设置断点 - 在
__libc_start_main设置断点跟踪子进程 - 在源码310行设置断点
- 在
-
动态链接库加载分析:
- 使用
_dl_open断点跟踪sudoers.so加载 - 加载完成后,在
set_cmnd函数设置断点
- 使用
-
堆溢出观察:
- 观察
to变量分配的0x70字节缓冲区 - 后面跟随的是unsortedbin的chunk(调试版本布局)
- 通过构造的转义字符序列可以溢出写入后续内存区域
- 观察
-
关键数据结构修改:
- 使用
find命令定位systemd字符串 - 设置内存观察点(watch)跟踪修改
- 确认
service_user结构体被成功修改
- 使用
利用技术细节
-
service_user结构体攻击:
- 修改
compat字段的名称 - 确保修改后的名称不在
database->library中 - 使
ni->library->lib_handle为NULL
- 修改
-
恶意库加载机制:
nss_load_library函数检查ni->library->lib_handle- 如果为NULL,则触发
__libc_dlopen加载库 - 加载路径构造为
libnss_X/P0P_SH3LLZ_ .so.2
-
提权完成:
- 恶意库中包含提权代码
- 成功加载后获得root shell
防御措施
- 及时更新sudo到安全版本
- 限制不必要的SUID权限
- 使用Linux内核防护机制(如ASLR, SELinux)
- 监控异常sudo调用行为
总结
CVE-2021-3156通过精心构造的命令行参数触发sudo的堆溢出,修改关键数据结构导致恶意动态链接库加载,最终实现权限提升。该漏洞利用涉及Linux动态链接机制、堆内存管理和SUID特性等多个系统组件的深入理解。