Skip to content

airbus-cert/unsafe-chroot

Repository files navigation

unsafe-chroot

Detect unsafe chroot execution regarding the NSS context. Based on the sudo CVE-2025-32463 vulnerability.

Prerequisites

  1. stable rust toolchains: rustup toolchain install stable
  2. nightly rust toolchains: rustup toolchain install nightly --component rust-src
  3. bpf-linker: cargo install bpf-linker
  4. debug symbols for libc: sudo apt install libc6-dbg (on debian)

Build & Run

cargo build --release

# Warn mode
RUST_LOG=warn ./unsafe-chroot --libc-path /usr/lib/x86_64-linux-gnu/libc.so.6

# Info mode: verbose output for uprobe and syscall triggers
RUST_LOG=warn ./unsafe-chroot --libc-path /usr/lib/x86_64-linux-gnu/libc.so.6

# pid mode: attach to a specific pid
RUST_LOG=warn ./unsafe-chroot --libc-path /usr/lib/x86_64-linux-gnu/libc.so.6 --pid 1090

If RUST_LOG is not set, the program will output nothing. If --libc-path is not specified, it will look for /usr/lib/libc.so.6. If --pid is not specified, it will trace all pids.

Technical description

I herbily recommand to read the original CVE-2025-32463 writeup to understand the work done here.

The glibc avoid reloading nsswitch.conf context when changing root to avoid these kind of issues. See the related issue tracker and the actual code.

However, if the NSS context is not properly set when chrooting, nsswitch.conf can still be reloaded. This could result on priviledge escalation in the case of sudo or container escape in Docker CVE-2019-14271.

This project tracks the NSS service databases with eBPF, and check if any of them is null when a chroot occurs.

glibc debug symbols

To track nsswitch.conf reloading in the glibc, the project sets an uprobe on nss_database_check_reload_and_get. However, this function does not have symbols, and you need glibc debug symbols to resove it.

For now, only debian based distributions are supported. With libc6-dbg, the debug symbols will be loaded from /usr/lib/debug/.build-id.

Example: detection of CVE-2025-32463

The following example shows the output of unsafe-chroot when exploiting the sudo CVE-2025-32463 (using this public exploit):

$ RUST_LOG=warn ./unsafe-chroot --libc-path /usr/lib/x86_64-linux-gnu/libc.so.6 &
Attaching nss tracker to offset: 1257216
Waiting for Ctrl-C...

$ sudo -R woot woot
[WARN  unsafe_chroot] [1896] Unsafe chroot detected: database id 6 is null
[WARN  unsafe_chroot] [1896] Unsafe chroot detected: database id 6 is null
[WARN  unsafe_chroot] [1896] Unsafe chroot detected: database id 6 is null
[WARN  unsafe_chroot] [1896] Unsafe chroot detected: database id 6 is null

root@debian:/# id
uid=0(root) gid=0(root) groups=0(root),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),100(users),101(netdev),1000(user)
root@debian:/# exit

The database id 6 (initgroups) is null, which prevents the reload security when changing root. Setting the initgroups in /etc/nsswitch.conf will prevent this priviledge escalation:

# Set initgroups database with empty value
$ echo 'initgroups:' | sudo tee -a /etc/nsswitch.conf
$ sudo -R woot woot
sudo: you are not permitted to use the -R option with woot

About

Detect unsafe chroot regarding NSS databases based on ebpf

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages