Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
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.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-53360-POC — PoC für CVE-2026-53360: gastausgelöster Heap-Out-of-Bounds-Lese-/Schreibzugriff in der KVM SEV-SNP Page State Change (PSC)-Verarbeitung. | Kitploit
Tools/GitHubGitHub/0xcyberstan/cve-2026-53360-poc
SpeicherforensikSchwachstellenanalyseExploitationHardware-SicherheitBinary-Exploitation
GitHub0xcyberstan/cve-2026-53360-poc

CVE-2026-53360-POC

PoC für CVE-2026-53360: gastausgelöster Heap-Out-of-Bounds-Lese-/Schreibzugriff in der KVM SEV-SNP Page State Change (PSC)-Verarbeitung.

Repository anzeigen
1vor 1 MonatNoch 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-53360: KVM SEV-SNP PSC Heap-Out-of-Bounds

Proof of Concept für einen Heap-Out-of-Bounds-Read und -Write in der SEV-SNP Page State Change (PSC)-Behandlung von KVM. Ein bösartiger SEV-SNP-Gast bringt den Host-Kernel dazu, ein PSC-Eintragsarray über das Ende seiner Slab-Allokation hinaus zu durchlaufen. Dadurch wird das Layout benachbarter kmalloc-cg-32-Objekte preisgegeben, und ein kontrollierter kleiner Wert wird in diese geschrieben. Der Gast kann dies beliebig oft wiederholen.

Ausführlicher Artikel: https://cyberstan.co.uk/sev-snp-oob/

CVECVE-2026-53360
KomponenteKVM SNP Host-Unterstützung, arch/x86/kvm/svm/sev.c
Eingeführt9b54e248d264 (erste KVM SNP PSC-Behandlung, Mai 2024, ~v6.10)
Behebungdb3f219 (Mainline, Mai 2026, Cc: stable), getaggt Fixes: 4af663c
Gemeldet[email protected], 8. April 2026
BetroffenNur SEV-SNP-Host-Pfad. KVM aktiviert PSC nicht für normale SEV-ES-Gäste.

Auswirkungen

Jeder SEV-SNP-Gast kann den Heap des Host-Kernels korrumpieren und Informationen über dessen Layout auslesen, indem er eine fehlerhafte PSC-Anfrage sendet. Dies ist die Richtung Gast → Host: SEV-SNP soll den Gast vor einem nicht vertrauenswürdigen Host schützen, aber der Host muss sich auch gegen einen bösartigen Gast verteidigen – und dieser Handler tut das nicht.

Voraussetzungen

Hierfür wird echte SEV-SNP-Hardware benötigt. Es kann nicht auf Intel reproduziert werden, und durch verschachtelte Virtualisierung erhält man keinen SNP-Gast.

Hardware:

  • Ein AMD EPYC-Server-Chip mit SEV-SNP: Milan (7003) oder neuer, also Genoa (9004), Bergamo, Siena oder Turin. SEV-SNP ist ausschließlich EPYC-Silizium. Es ist nicht auf Ryzen oder Threadripper verfügbar, und es gibt kein Intel-Äquivalent (Intel verwendet TDX).
  • Bare Metal. Auch eine Bare-Metal-Cloud-Instanz funktioniert (Vultr, AWS *.metal, Hetzner AX und ähnliche).
  • Im BIOS: SEV, SEV-ES, SEV-SNP, SME, IOMMU und SVM aktivieren. Managed Bare-Metal-Clouds haben diese normalerweise bereits vorkonfiguriert.

Host-Kernel:

  • Mit KASAN bauen, damit die Out-of-Bounds-Zugriffe gemeldet werden. Ohne KASAN korrumpiert der Fehler trotzdem den Host-Speicher, wird aber nicht ausgegeben. Getestet mit 6.11.11.
    root@kitploit:~
    CONFIG_KASAN=y
    CONFIG_KASAN_GENERIC=y
    CONFIG_KVM=y
    CONFIG_KVM_AMD=y
    CONFIG_KVM_AMD_SEV=y
    CONFIG_CRYPTO_DEV_SP_PSP=y
    
  • Booten mit aktiviertem SNP und KASAN im Multi-Shot-Modus, damit jeder Treffer protokolliert wird:
    root@kitploit:~
    kvm_amd.sev=1 kvm_amd.sev_es=1 kvm_amd.sev_snp=1 kasan_multi_shot
    
  • Bestätigen, dass der Host bereit ist:
    root@kitploit:~
    cat /sys/module/kvm_amd/parameters/sev_snp     # Y
    ls /dev/sev                                     # /dev/sev
    

Host-Benutzerbereich:

  • Ein SNP-fähiges QEMU. Das Standard-QEMU unterstützt SNP nicht, daher den AMD-Fork bauen:
    root@kitploit:~
    git clone https://github.com/AMDESE/qemu.git
    cd qemu && git checkout snp-latest
    mkdir build && cd build
    ../configure --target-list=x86_64-softmmu && make -j$(nproc)
    
  • SNP-OVMF-Firmware von https://github.com/AMDESE/AMDSEV/releases.

Gast:

  • Ein beliebiger Linux-Gast, der unter SNP bootet, mit installierten Paketen build-essential und linux-headers-$(uname -r), um das Modul darin bauen zu können.

Der Fehler

SEV-SNP-Gäste kommunizieren mit dem Host über die GHCB, eine 4-KB-seitige Shared Page. Eine PSC-Anfrage setzt SW_EXITCODE auf SVM_VMGEXIT_PSC (0x80000010), zeigt mit SW_SCRATCH auf einen Deskriptor und legt die Deskriptorlänge in SW_EXITINFO2 ab.

Der Deskriptor ist ein struct psc_buffer: ein 8-Byte-Header, gefolgt von einem Array aus 8-Byte-Einträgen. Es gibt kein explizites Zählfeld. Der Host verarbeitet Einträge von hdr->cur_entry bis hdr->end_entry, beide vom Gast gesteuert.

root@kitploit:~
struct psc_hdr {
        u16 cur_entry;
        u16 end_entry;
        u32 reserved;
} __packed;                     /* 8 Bytes */

struct psc_entry {
        u64 cur_page    : 12;
        u64 gfn         : 40;
        u64 operation   :  4;
        u64 pagesize    :  1;
        u64 reserved    :  7;
} __packed;                     /* 8 Bytes */

Ein GHCB-v2+-Gast soll seinen Scratch-Bereich innerhalb des 2032-Byte Shared Buffers der GHCB halten, damit der Host sein bestehendes Mapping wiederverwenden kann. (2032 - 8) / 8 = 253 Einträge passen hinein – daher kommt das Protokoll-Maximum VMGEXIT_PSC_MAX_COUNT (253). Diese Zahl ergibt nur Sinn, wenn der Puffer wirklich der Shared Buffer ist.

Wenn der Gast den Scratch-Bereich außerhalb der GHCB platziert, kann der Host sein Mapping nicht verwenden, daher allokiert setup_vmgexit_scratch() einen separaten Puffer in der vom Gast angeforderten Größe. SNP sollte diesen Pfad nie nehmen, aber nichts verhindert es:

root@kitploit:~
scratch_va = kvzalloc(len, GFP_KERNEL_ACCOUNT);   /* len == exit_info_2, vom Gast gesteuert */

len kommt direkt vom Gast, und GFP_KERNEL_ACCOUNT platziert die Allokation in den Cgroup-kontierten kmalloc-cg-N-Caches. Fordert man exit_info_2 = 24 an, erhält man eine 24-Byte-Allokation im 32-Byte-Slot kmalloc-cg-32: Platz für den Header plus zwei Einträge. Alles jenseits von entries[1] ist der Speicher eines anderen Objekts.

Dann prüft snp_begin_psc() die Anzahl der Einträge gegen die Protokollkonstante, nicht gegen den tatsächlich allokierten Puffer:

root@kitploit:~
idx_end = hdr->end_entry;

if (idx_end >= VMGEXIT_PSC_MAX_COUNT) {   /* prüft auf 253, NICHT auf die Puffergröße */
        snp_complete_psc(svm, ...);
        return 1;
}

for (idx = idx_start; idx <= idx_end; idx++) {
        entry_start = entries[idx];       /* OOB sobald idx >= 2 */
        ...
}

Bei einem 24-Byte-Puffer existieren nur zwei Einträge, aber die Prüfung erlaubt end_entry bis zu 252. Setzt man es auf 252, durchläuft die Schleife etwa 2 KB über die Allokation hinaus, über angrenzende Slab-Objekte hinweg.

Primitive

Jeder Schritt über das Ende hinaus interpretiert die nächsten 8 Bytes des Slab-Speichers als psc_entry und führt sie durch den PSC-Code. Das ergibt drei Dinge:

  1. Lese-Orakel. Der Host liest das benachbarte Qword nur zum Dekodieren aus und extrahiert entry.gfn und entry.operation aus Speicher, der dem Puffer nie gehörte. Dies ist der Slab-Out-of-Bounds-Read, den KASAN abfängt.
  2. Eingeschränkter Write. Wenn der dekodierte Eintrag gültig erscheint und als KVM_HC_MAP_GPA_RANGE abgesetzt wird, schreibt der Abschlusscode zurück in denselben OOB-Slot: entries[idx].cur_page = entry.pagesize ? 512 : 1. Einer von zwei kleinen Werten in die unteren 12 Bits eines Wortes, das der Gast auswählt – wiederholbar.
  3. Fehler-Orakel. Wenn der Eintrag nicht validiert wird, meldet die Antwort in SW_EXITINFO2 den Index, bei dem abgebrochen wurde. Erhöht man end_entry schrittweise, wird Slot für Slot preisgegeben, ob der benachbarte Speicher als No-Op oder als etwas Fehlschlagendes dekodiert wurde. Das reicht aus, um Objektgrenzen zu finden und Null von Nicht-Null zu unterscheiden.

Jeder VMGEXIT allokiert den Scratch-Puffer neu, daher landen wiederholte Anfragen in verschiedenen Freelist-Slots und lassen den Gast über Nachbarn streifen, anstatt bei einem hängenzubleiben. Zusammen ergibt dies Heap-Layout-Offenlegung, den eingeschränkten Write von oben und Use-After-Free über Anfragen hinweg.

Was der PoC tut

trigger.c ist ein Gast-Kernel-Modul. Lädt man es innerhalb eines SEV-SNP-Gasts, durchläuft es ab einem einzigen insmod vier Stufen gegen den Host:

  • Stufe 1 testet 48 Out-of-Bounds-Einträge einzeln und erstellt eine Karte des Host-Heaps (Null vs. Nicht-Null im benachbarten Speicher).
  • Stufe 2 beweist, dass der OOB-Write VMGEXIT-übergreifend bestehen bleibt, indem cur_page in einen Null-Nachbarn geschrieben wird und eine spätere Anfrage bestätigt, dass dieser übersprungen wird.
  • Stufe 3 feuert eine Anfrage mit end_entry=200 und misst, wie weit der OOB-Read reicht, bevor er auf Nicht-Null-Daten trifft.
  • Stufe 4 feuert 200 Anfragen mit entries[3..10] außerhalb der Grenzen, von denen jede einen KASAN-Bericht auf dem Host auslöst.

Das Modul allokiert eine Seite, markiert sie mit set_memory_decrypted() als entschlüsselt, verwendet sie als Scratch-Bereich und baut die GHCB-PSC-Anfrage manuell zusammen. Es beendet sich mit -EAGAIN, bleibt also nicht geladen.

Bauen und Ausführen

1. SNP-Gast starten

Passen Sie OVMF- und Disk-Pfade an Ihre Umgebung an:

root@kitploit:~
qemu-system-x86_64 \
    -enable-kvm -cpu EPYC-v4 \
    -machine q35,confidential-guest-support=sev0,memory-backend=ram1 \
    -object memory-backend-memfd,id=ram1,size=4G \
    -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,policy=0x30000 \
    -smp 4 -m 4G \
    -bios OVMF_SNP.fd \
    -drive file=guest.qcow2,format=qcow2,if=virtio \
    -netdev user,id=net0,hostfwd=tcp::2222-:22 \
    -device virtio-net-pci,netdev=net0 \
    -nographic

2. Im Gast bauen und laden

Kopieren Sie trigger.c und Makefile in den Gast, dann:

root@kitploit:~
make
insmod trigger.ko

Das Modul prüft zuerst per CPUID auf SEV-SNP und weigert sich, woanders zu laufen. Es durchläuft seine vier Stufen und entlädt sich selbst (init gibt -EAGAIN zurück, sodass es nie resident bleibt).

3. Host beobachten

Auf dem Host:

root@kitploit:~
dmesg | grep -E "KASAN|BUG|snp_begin_psc"

Erwartete Ausgabe:

root@kitploit:~
BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x126/0x890
Read of size 8 at addr ffff888219ffb5e0 by task qemu-system-x86/2199

BUG: KASAN: slab-out-of-bounds in snp_begin_psc+0x468/0x890
Write of size 8 at addr ffff888351566648 by task qemu-system-x86/2199

The buggy address belongs to the object at ffff888XXXXXXXXX
 which belongs to the cache kmalloc-cg-32 of size 32

Ein einziges insmod erzeugte 73 KASAN-Berichte auf dem Testhost (62 slab-out-of-bounds, 7 slab-use-after-free, 4 use-after-free), alle gegen kmalloc-cg-32. Testhost: AMD EPYC 7443P, Ubuntu 24.04.4, Kernel 6.11.11 mit KASAN, Gast unter AMDESE QEMU (snp-latest).

Die Behebung

Der Upstream-Fix lehnt jeden Scratch-Bereich außerhalb der GHCB für GHCB v2 und höher in setup_vmgexit_scratch() ab, wodurch der Puffer auf eine feste, bekannte Größe festgelegt wird, sodass die Schleife niemals über das Ende hinauslaufen kann:

root@kitploit:~
  } else {
+         /* GHCB v2 erfordert, dass der Scratch-Bereich innerhalb der GHCB liegt. */
+         if (to_kvm_sev_info(svm->vcpu.kvm)->ghcb_version >= 2)
+                 goto e_scratch;
+
          /*
           * Der Gastspeicher muss in einen Kernel-Puffer eingelesen werden, daher
           * die Größe begrenzen.

Diese vier Zeilen sind db3f219. Sie waren Teil einer größeren Serie, die auch die Eintragsanzahl gegen die tatsächliche Puffergröße begrenzt und den Deskriptor einmalig über READ_ONCE() erneut einliest, wodurch eine Offset-in-den-Puffer-Variante und eine Time-of-Check/Time-of-Use-Race im selben Handler geschlossen werden.

Dateien

DateiBeschreibung
trigger.cGast-Kernel-Modul, das die vier PoC-Stufen durchführt
MakefileBaut trigger.ko gegen den laufenden Gast-Kernel

Fehlerbehebung

  • not an SEV-SNP guest: QEMU wurde nicht mit sev-snp-guest gestartet, oder Host-SNP ist deaktiviert.
  • QEMU SEV-SNP not supported: Überprüfen Sie /sys/module/kvm_amd/parameters/sev_snp, die BIOS-Einstellungen und die Boot-Parameter.
  • QEMU LAUNCH_START failed: Das PSP ist nicht initialisiert. Überprüfen Sie dmesg | grep psp und CONFIG_CRYPTO_DEV_SP_PSP=y.
  • Keine KASAN-Ausgabe: Stellen Sie sicher, dass CONFIG_KASAN=y und kasan_multi_shot in der Host-Befehlszeile gesetzt sind.

Warnung

Dies korrumpiert den Host-Kernel-Heap-Speicher, löst KASAN aus und kann den Host zum Absturz bringen. Führen Sie es nur auf einem von Ihnen kontrollierten Einweg-Testhost innerhalb einer eigenen VM aus. Führen Sie es nicht gegen geteilte oder Produktionsinfrastruktur aus.

Referenzen

  • Artikel: https://cyberstan.co.uk/sev-snp-oob/
  • CVE-2026-53360 (Commit db3f219 auf linux-cve-announce verfolgen)
  • Behebung: db3f219, Autor Mike Roth, Reviewed by Tom Lendacky, committed by Paolo Bonzini
  • Eingeführt: 9b54e248d264; Fix getaggt Fixes: 4af663c
  • GHCB-Spezifikation, Abschnitt 2.1 (SW_SCRATCH muss innerhalb des GHCB-Shared-Buffers liegen)

Lizenz

trigger.c ist GPL-2.0, entsprechend seiner MODULE_LICENSE. Siehe LICENSE.

Tool herunterladen
LICENSEGPL-2.0, entsprechend der MODULE_LICENSE des Moduls