CVE-2025-32463漏洞复现
尝试复现并分析调试今年的一个 sudo 本地提权漏洞。
该漏洞描述如下:
Sudo before 1.9.17p1 allows local users to obtain root access because /etc/nsswitch.conf from a user-controlled directory is used with the –chroot option.
环境搭建
建议环境 glibc 版本 > 2.35,否则无法复现。
git clone sudo 的源码:
1 | git clone https://github.com/sudo-project/sudo.git |
编译:
1 | ./configure |
make install 会安装到 /usr/local/bin ,先将原来的 /usr/bin/sudo 重命名一下。
1 | !/bin/bash |
分为三部分:
- 创建 woot/etc 目录并填充内容 woot/etc/nsswitch.conf 以及 /etc/group;
- 编译 woot1337.c 为恶意共享库,令后续 sudo 运行时加载该库;
- sudo -R 触发
运行网上的 exp.sh,没成功 XD。
1 | eutopia@eutopia-ubuntu22 ~/Vulns/Linux_Kernel/cve-2025-32463 |
调试复现
调试发现是在 resolve_cmnd 函数内 nss_database_check_reload_and_get 函数逻辑在 427 行增加了 check 逻辑。这里如果发现 local 与 str 的变量的ino不同,则设置 reload 为 false。
glibc 2.35版本源码:
在glibc 2.39中则将该check逻辑放入 if (local->data.services[database_index] != NULL)中包裹。由于刚好我们这个漏洞触发路径上 local->data.services[database_index] == NULL,所以能够绕过该检查机制:
更换环境为 Ubuntu 24.04,验证成功
原理分析
具体流程为:
- 设置 chroot 后 runchroot 变为非空,执行 pivot_root 函数进行 chroot;
- 执行 resolve_cmnd 函数解析命令地址;
- unpivot_root 恢复根路径
问题出在 resolve_cmnd 函数中会调用 SetPerms 函数,其会调用 getgrouplist 函数,从而触发重载/etc/nsswitch.conf逻辑,此时已进行 chroot,所以会加载恶意构造的 nsswitch.conf 文件。
然后在上面源码中有一个很 trick 的点:
其实就是为什么会在 pivot_root 后会重载 nsswitch.conf,但是在 unpivot_root 后就没有进行重载。
第一部分上面已经有分析;第二部分是因为在 unpivot_root 后其 local->data.services[database_index] != NULL(此时database_index = 2),然后且 local->root_ino 与 str 的不一致导致设置 local->data.reload_disabled 为1,从而不会再重载。
然后就是在哪里加载的恶意 so 库,nsswitch.conf 设置了 passwd: /woot1337 该名称可以用作库的路径的一部分,即:libnss_/woot1337.so.2.so:
调用链如下:
1 | policy_check -> sudoers_policy_check -> sudoers_check_cmnd |
setspent函数用于打开 shadows 文件。
在 module_load 中会加载so库。
patch
其 patch 代码如下:
1 | --- sudo-1.9.17/plugins/sudoers/sudoers.c 2025-06-12 12:12:38.000000000 -0500 |
直接简单粗暴删除了 pivot_root 逻辑。