Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-8933 — C-Proof-of-Concept für CVE-2026-8933, eine lokale Rechteausweitung in snap-confine, die cgroup-Freezing, Symlink-Races und udev-Regel-Injection nutzt, um Befehle als root auszuführen. | Kitploit
Tools/GitHubGitHub/yifengchen-cc/cve-2026-8933
Privilege EscalationContainer-SicherheitSchwachstellenanalyseExploitation
GitHubyifengchen-cc/cve-2026-8933

CVE-2026-8933

C-Proof-of-Concept für CVE-2026-8933, eine lokale Rechteausweitung in snap-confine, die cgroup-Freezing, Symlink-Races und udev-Regel-Injection nutzt, um Befehle als root auszuführen.

Repository anzeigen
vor 14 TagenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-8933 — snap-confine set-capabilities lokale Rechteausweitung PoC

Reproduziere die Qualys-Advisory „Local Privilege Escalation in set-capabilities versions of snap-confine“ (https://cdn2.qualys.com/advisory/2026/07/21/snap-confine-set-capabilities.txt).

Auf diesem Rechner (Ubuntu 25.10 / snapd 2.73+ubuntu25.10.1 / Kernel 6.17) praktisch verifiziert: Ausgehend von uid 1000 wird der Befehl schließlich von systemd-udevd als root ausgeführt, und /tmp/pwned erhält uid=0(root) gid=0(root) groups=0(root), was mit der abschließenden Demonstration in der Ankündigung übereinstimmt.

Aufzeichnungen über die Fallstricke während der Reproduktion sowie darüber, warum die erste Bewertung fälschlicherweise zu dem Schluss "nicht ausnutzbar" kam, siehe NOTES.md.

Dateien

DateiBeschreibung
poc.cVollständiger PoC (einzelne Datei)
MakefileBuild (linkt die im System installierte libfuse3.so.3.17.4)
include/libfuse3 3.17.4 Header-Dateien (passend zur Laufzeitbibliothek des Systems)
NOTES.mdAufzeichnung der Fallstricke + Retrospektive der Methodik zur Erreichbarkeitsanalyse

Schwachstellenprinzip

cmd/snap-confine/mount-support.c (snapd 2.73):

sc_bootstrap_mount_namespace()      // 第 475 行起
  479:  mkdtemp("/tmp/snap.rootfs_XXXXXX")          <- 目录先归调用者所有
  491:  sc_do_mount(scratch, scratch, NULL, MS_BIND)
  498:  sc_do_mount("none", scratch, NULL, MS_UNBINDABLE)
  503:  sc_do_mount("none", scratch, "tmpfs", ...)
  504:  sc_replicate_base_rootfs(scratch, rootfs_dir, mounts)

sc_replicate_base_rootfs()
  330:  chown(scratch, 0, 0)
  418:  fd = open(full_path, O_CREAT | O_TRUNC, 0644)   <- 缺少 O_NOFOLLOW
  422:  fchown(fd, 0, 0)

Die Zeilennummern stammen aus dem Quellcode des lokalen snapd 2.73 (cmd/snap-confine/mount-support.c). Die Qualys- Meldung zitiert ihre eigene Kopie dieser Datei; die entsprechenden Zeilennummern sind 511 / 523 / 530 / 535 / 536 / 362 / 450 / 454 – die Anweisungen entsprechen sich eins zu eins, nur die Zeilennummern unterscheiden sich.

Das lokale /usr/lib/snapd/snap-confine hat mode=755 + Datei-Capabilities (nicht setuid-root), daher läuft es mit der euid des Angreifers, besitzt aber nahezu Root-Capabilities: Die von ihm erstellten Verzeichnisse und Dateien gehören für kurze Zeit dem Angreifer, und das open() in Zeile 418 folgt symbolischen Links.

Die Disassemblierung bestätigt: Die Flags von open@plt sind lokal 0x240 (O_CREAT|O_TRUNC, ohne O_NOFOLLOW); an derselben Stelle im gepatchten 2.77.1 lauten sie 0x20240.

Die sechs Schritte des PoC

  1. snap-confine in eine eigene cgroup stecken: systemd-run --user --scope --unit=snap.<snap>.<app>. Dieser Scope gehört dem aktuellen Benutzer, cgroup.freeze ist beschreibbar, sodass snap-confine Syscall für Syscall freigegeben werden kann.
  2. An der richtigen Stelle einfrieren: Mit SNAPD_DEBUG=1 gibt snap-confine associated snap application process ... with device cgroup aus. Diese Zeile erscheint nach dem Anhängen des BPF-Programms der Device-cgroup, aber vor mkdtemp(). Nicht früher einfrieren: Der BPF-Verifier gibt bei vorhandener Freeze-Falle EAGAIN zurück, und snap-confine beendet sich sofort. stderr ist mit einem pty verbunden (keine Pipe): Andernfalls wäre stdio blockgepuffert, und der Marker würde oft erst nach mkdtemp() und dem Bind-Mount herausgespült. Außerdem startet der Scope mit CPUQuota=1%: Vom Marker bis mkdtemp() bleiben nur wenige hundert Mikrosekunden CPU-Zeit, in derselben Größenordnung wie die Aufwachverzögerung des abgreifenden Prozesses; die Drosselung dehnt dieses Fenster in realer Zeit auf Millisekunden aus, und nach Bestätigung des Einfrierens wird cpu.max sofort wieder auf 100% gesetzt.
  3. Das Scratch-Verzeichnis durch einen Symlink auf unser eigenes Verzeichnis ersetzen: mount(2) folgt Symlinks im Zielpfad, sodass die Bind-/Unbindable-/tmpfs-Mounts von snap-confine alle auf <scratch>.dA landen, während die Kopierschleife weiterhin den String des Scratch-Verzeichnisses verwendet.
  4. Nachdem tmpfs eingehängt ist (ns_mount_count(sc, .dA) >= 2), den Symlink auf <scratch>.dB umbiegen und in dB Symlinks mit denselben Namen wie die regulären Dateien der obersten Ebene des Base-Rootfs ablegen, die auf /run/udev/rules.d/97-cve-2026-8933-<pid>-<rand>.rules zeigen. Nun landet die Pfadauflösung der Kopierschleife in dB – einem gewöhnlichen Verzeichnis, das wir vollständig kontrollieren. Das tmpfs bleibt in dA zurück und stört uns nicht mehr. Achtung: Bei nur 1 Mount auf .dA handelt es sich um einen Bind-Mount (/tmp ist selbst tmpfs, nach dem Bind ist der fstype weiterhin tmpfs); erst wenn der 2. Mount (das eigentliche tmpfs) erscheint, darf umgebogen werden, sonst scheitert mount --make-unbindable von snap-confine mit EINVAL, weil der Pfad kein Mount-Root mehr ist.
  5. Das Fenster zwischen open() und fchown() gewinnen: Die Kopierschleife führt für die erste reguläre Datei open(O_CREAT|O_TRUNC) aus (folgt dem Symlink und erstellt die Datei als root unter /run/udev/rules.d), danach folgt fchown(fd,0,0). In diesem Augenblick gehört die Datei noch uns. Der PoC nutzt zwei Mittel gleichzeitig:
    • Hauptpfad: Weiter mit dem Freezer jeweils nur etwa einen Syscall freigeben; sobald stat() die Datei sieht und die uid noch die eigene ist, sofort chmod 0666 + Schreiben der udev-Regel (snap-confine ist dann eingefroren, das Fenster wird „aufgespreizt“);
    • Rückfallebene: Mehrere Spinner-Prozesse greifen mit einer chmod()-Heißschleife dasselbe Fenster ab. Hat ein Spinner es erwischt, gehört die Datei root, hat aber den Modus 0666 – die Modusbits bleiben nach fchown(0,0) erhalten, sodass auch der Hauptpfad sie fertig schreiben kann (im Code wird geprüft, ob man schreiben kann, nicht ob man Eigentümer ist).
  6. udev auslösen: Das AppArmor-Profil von snap-confine erlaubt /run/udev/** rw. Das Ein- und Aushängen eines FUSE-Dateisystems veranlasst den Kernel, für das bdi-Subsystem ein add-uevent auszusenden, woraufhin systemd-udevd als root das PROGRAM= aus der Regel ausführt.

Verwendung

make
./poc --diagnose            # 只读自检,不改动任何系统状态
./poc                       #  exploit,默认最多 5 次尝试
./poc --attempts 8          # 增加尝试次数
./poc --file default256.png # 只用 base rootfs 里的这一个普通文件
sudo ./poc --cleanup        # 清理(仅在异常中断留下残留时需要)

Parameter:

ParameterBeschreibung
--snap NAMEWelches snap-Rootfs verwendet wird (Standard: firefox, alternativ über die Umgebungsvariable CVE8933_SNAP)
--app NAMEDie App dieses snaps (standardmäßig die erste unter apps: in meta/snap.yaml)
--file NAMENur diese eine reguläre Datei aus dem Basis-Rootfs verwenden; bei fehlender Übereinstimmung mit Fehler beenden
--attempts NAnzahl der Versuche (Standard: 5)
--step US / --step2 USCPU-Zeit pro Slice für die beiden Phasen (Mikrosekunden), zum Debuggen
--keepDie Verzeichnisse <scratch>.dA / .dB und Symlinks behalten (zum Debuggen)
--diagnoseNur-Lese-Selbsttest
--cleanupHistorische Reste bereinigen (erfordert root)

Logs werden nach /tmp/cve8933.log geschrieben, die Debug-Ausgabe von snap-confine nach /tmp/cve8933-debug.txt.

Mit CVE8933_PAYLOAD_CMD='<Shell-Befehl>' kann der Payload-Rumpf ersetzt werden (um die Ausführung anderer root-Befehle zu demonstrieren); in diesem Fall erfolgt keine automatische Bereinigung; der benutzerdefinierte Befehl muss weiterhin /tmp/pwned schreiben, da der PoC sonst davon ausgeht, dass dieser Versuch nicht erfolgreich war.

Testergebnisse

$ ./poc
[+] WIN: uid=0(root) gid=0(root) groups=0(root)
[+] exploit succeeded, evidence in /tmp/pwned
Tool herunterladen