Rooting with chwoot: Deep Dive into CVE-2025-32463
Discovered in Sudo version 1.9.15 and fixed in 1.9.17p1, CVE-2025-32463 is a logic vulnerability that allows an attacker to load arbitrary `.so` libraries via a controlled `nsswitch.conf` path, leveraging unsafe pivot root logic. This blog walks through the vulnerability analysis, control flow trace, and source code references.
Ref:
- Vulnerability Advisory
- Exploit:
- Maybe it will not work with you if this happens, try to write your own vulnerable directory, and try the exploit after understanding it.
Background
Sudo is a widely used tool that allows users to run commands with elevated privileges. In version "1.9.15", a vulnerable code path allowed privilege escalation by abusing a (pivot_root + chroot) sequence in combination with dynamic library loading through "nsswitch.conf".
The vulnerable behavior was removed in the patched version 1.9.17p1.
What is NSSwitch
NSS stands for Name Service Switch It's the system responsible for resolving user, group, host, and service information. Controlled by the file: bash Copy Edit "/etc/nsswitch.conf"
When your system calls getpwnam, glibc reads the contents of nsswitch.conf to determine how to locate user data. For example, if we used the following file:
passwd: files systemd
It means using passwd for "/etc/passwd" and "systemd".
Why is this useful in the exploit? If we used the following file
passwd: flexdb
The glibc will try to load "/lib/lbnss_flexdb.so.2" if this file is controlled by the attacker and binary runes with root the attacker will do privilege escalation.
Key Problem
- pivot_root(): changes the root directory to a user-controlled location (e.g. woot).
- Later, during authentication after pivot call, these functions are called (check_user → sudo_auth_init → sudo_passwd_init), Sudo uses `dlopen()` to load the NSS shared object "libnss_*.so.2" based on the modified root.
- This leads to arbitrary ".so" loading, resulting in code execution as root.
Debugging
First to compile "sudo" with debug to be used with GDB, you can remove sudo if not needed and change the path
To use gdb with sudo, in this case, we can use
This is the tree of the exploit directory:
If we used this setup, it would gain root access:
if you checked the above trace call of the functions the issue happen when the binary calls "set_cmnd_path" which call "(un)pivot_root" the call came from "sudoers.c:1104" in debug you can breakpoint on the previous file with the line or "set_cmnd_path+379" and you can breakpoint using the filename and line number because of debug (-g) mode compile.
The "pivot_root" and "unpivot_root" functions from "pivot.c" calls "chroot" to the current directory which we control and here is the issue.
when we continue the execution flow after "pivot_root" after that it will function "check_user" at "sudoers.c:468" and will continue as follows:
The call of "asprintf" from GDB that set the path for "libnss" so path:
the final value will be "libnss_/woot1337.so.2", the call of "__libc_dlopen_mode" from GDB:
You can find the "libnss" so file that we will load "libnss_/woot1337.so.2" and here is the load of the controlled so library that will give us a shell, and you can see the backtrace of the functions.
We compiled the exploit so file with
~$ gcc -shared -fPIC -Wl,-init,woot -o libnss_/woot1337.so.2 woot1337.c
And the source code is:
Finally, when we exploit the vulnerability using the following:
The NSS file will be:
Try to do the debugging process by yourself, and you will learn a lot.
Vulnerable Flow – sudo-1.9.15
Here is a high-level trace of the vulnerable control flow starting from main():
Safe Flow – sudo-1.9.17p1
In the patched version, the pivot_root() logic is completely removed
Vulnerability Mechanics
- Calling "pivot_root()" inside "set_cmnd_path()", effectively sandboxing the process in a new root (woot) current directory.
- This new root affects how paths are resolved, including NSS ".so" libraries that are dynamically loaded using "dlopen()" based on "nsswitch.conf".
- dlopen() attempts to load paths like "libnss_files.so.2" under the "new root', allowing the attacker to provide a malicious shared object at the expected location (libnss_*.so.2).
Exploitation Path
- Write malicious ".so" (e.g., "libnss_/woot1337.so.2") in attacker-controlled root.
- Modify "nsswitch.conf" to point to "woot1337" in "passwd" line.
- Trigger sudo with an environment that executes "dlopen()" through "getspnam()".
PoC Reminder
- Create folder "libnss_"
- Creating a fake root with "libnss_/woot1337.so.2"
- Editing "/etc/nsswitch.conf" to point to "woot1337" under "passwd"
- Running "sudo" with crafted setup (in a container/VM).
References:
- pivot.c (vulnerable logic)
- set_cmnd_path() source
- sudoers.c
Comments
Post a Comment