Vectored Overloading PE Injection

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Technikübersicht

Vectored Overloading ist eine Windows PE injection primitive, die klassisches Module Overloading mit Vectored Exception Handlers (VEHs) und hardware breakpoints verbindet. Anstatt LoadLibrary zu patchen oder einen eigenen Loader zu schreiben, geht der Angreifer wie folgt vor:

  1. Erstellt eine SEC_IMAGE Section, die von einer legitimen DLL gestützt wird (z. B. wmp.dll).
  2. Überschreibt die gemappte Ansicht mit einem vollständig relocierten bösartigen PE, lässt jedoch das Section-Objekt weiterhin auf das harmlose Image auf Platte zeigen.
  3. Registriert einen VEH und programmiert die Debug-Register so, dass jeder Aufruf von NtOpenSection, NtMapViewOfSection und optional NtClose einen User-Mode-Breakpoint auslöst.
  4. Ruft LoadLibrary("amsi.dll") (oder eine andere harmlose Ziel-DLL) auf. Wenn der Windows-Loader diese Syscalls ausführt, überspringt der VEH den Kernel-Übergang und liefert die Handles und Basisadressen des vorbereiteten bösartigen Images zurück.

Weil der Loader weiterhin glaubt, die angeforderte DLL gemappt zu haben, sehen Tools, die nur die Section-Backing-Dateien prüfen, wmp.dll, obwohl der Speicher jetzt die Payload des Angreifers enthält. Gleichzeitig werden Imports/TLS-Callbacks weiterhin vom echten Loader aufgelöst, wodurch der Umfang an eigenem PE-Parsing-Code, den der Angreifer pflegen muss, deutlich reduziert wird.

Phase 1 – Erstellen der getarnten Section

  1. Create and map a section for the decoy DLL
NtCreateSection(&DecoySection, SECTION_ALL_ACCESS, NULL,
0, PAGE_READWRITE, SEC_IMAGE, L"\??\C:\\Windows\\System32\\wmp.dll");
NtMapViewOfSection(DecoySection, GetCurrentProcess(), &DecoyView, 0, 0,
NULL, &DecoySize, ViewShare, 0, PAGE_READWRITE);
  1. Kopiere das bösartige PE in diese View Abschnitt für Abschnitt, unter Beachtung von SizeOfRawData/VirtualSize und passe anschließend die Protektionen an (PAGE_EXECUTE_READ, PAGE_READWRITE, etc.).
  2. Wende Relocations an und löse Imports auf genau wie ein reflective loader. Da die View bereits als SEC_IMAGE gemappt ist, stimmen Section-Alignments und Guard-Pages mit dem überein, was der Windows-Loader später erwartet.
  3. Normalisiere den PE-Header:
  • Wenn die Payload eine EXE ist, setze IMAGE_FILE_HEADER.Characteristics |= IMAGE_FILE_DLL und nulliere den Entry-Point, damit LdrpCallTlsInitializers nicht in EXE-spezifische Stubs springt.
  • DLL-Payloads können ihre Header unverändert lassen.

An diesem Punkt besitzt der Prozess eine RWX-fähige View, deren Backing-Objekt weiterhin wmp.dll ist, obwohl die Bytes im Speicher vom Angreifer kontrolliert werden.

Phase 2 – Den Loader mit VEHs manipulieren

  1. Registriere einen VEH und lege hardware breakpoints: programmiere Dr0 (oder ein anderes Debug-Register) mit der Adresse von ntdll!NtOpenSection und setze DR7, sodass jede Ausführung STATUS_SINGLE_STEP auslöst. Wiederhole das später für NtMapViewOfSection und optional NtClose.
  2. Starte das Laden der DLL mit LoadLibrary("amsi.dll"). LdrLoadDll wird schließlich NtOpenSection aufrufen, um das echte Section-Handle zu erhalten.
  3. VEH-Hook für NtOpenSection:
  • Lokalisieren des Stack-Slots für das [out] PHANDLE SectionHandle-Argument.
  • Schreibe das zuvor erstellte DecoySection-Handle in diesen Slot.
  • Setze RIP/EIP auf die ret-Anweisung, sodass der Kernel niemals aufgerufen wird.
  • Re-aktive den hardware breakpoint, um als Nächstes NtMapViewOfSection zu beobachten.
  1. VEH-Hook für NtMapViewOfSection:
  • Überschreibe das [out] PVOID *BaseAddress (und die Größen/Protektions-Outputs) mit der Adresse der bereits gemappten bösartigen View.
  • Überspringe den Syscall-Body wie zuvor.
  1. (Optional) VEH-Hook für NtClose verifiziert, dass das gefälschte Section-Handle bereinigt wird, verhindert resource leaks und bietet eine letzte Plausibilitätsprüfung.

Da die Syscalls nie ausgeführt werden, sehen Kernel-Callbacks (ETWti, minifilter, etc.) die verdächtigen NtOpenSection/NtMapViewOfSection-Ereignisse nicht, was die Telemetrie drastisch reduziert. Aus Sicht des Loaders ist alles erfolgreich verlaufen und amsi.dll befindet sich im Speicher, sodass er mit der Import-/TLS-Auflösung gegen die Bytes des Angreifers fortfährt.

Phase 3 – Payload ausführen

  • EXE-Payload: Der Injector springt einfach zum ursprünglichen Entry-Point, sobald die Relocations angewendet sind. Wenn der Loader glaubt, DllMain aufzurufen, führt der custom Code stattdessen den EXE-ähnlichen Entry aus.
  • DLL-Payload / Node.js addon: Löse den vorgesehenen Export auf und rufe ihn auf (Kidkadi stellt z. B. eine benannte Funktion für JavaScript bereit). Da das Modul bereits in LdrpModuleBaseAddressIndex registriert ist, sehen nachfolgende Lookups es als die harmlose DLL.

In Kombination mit einem Node.js native addon (.node-Datei) bleibt die schwere Windows-Interna-Arbeit außerhalb der JavaScript-Schicht und erlaubt dem Bedrohungsakteur, denselben Loader mit vielen verschiedenen obfuszierten Node-Wrappern zu verwenden.

Referenzen

Tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks