Vectored Overloading PE Injection
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Przegląd techniki
Vectored Overloading to Windows PE injection primitive, które łączy klasyczny Module Overloading z Vectored Exception Handlers (VEHs) i hardware breakpoints. Zamiast patchować LoadLibrary lub pisać własny loader, adversary:
- Tworzy sekcję
SEC_IMAGEopartą na legalnym DLL (np.wmp.dll). - Nadpisuje zmapowany widok w pełni zrelokowanym złośliwym PE, ale utrzymuje obiekt sekcji wskazujący na benign obraz na dysku.
- Rejestruje VEH i programuje rejestry debugowania tak, aby każde wywołanie
NtOpenSection,NtMapViewOfSection, i opcjonalnieNtClosepodnosiło user-mode breakpoint. - Wywołuje
LoadLibrary("amsi.dll")(lub dowolny inny benign target). Kiedy Windows loader wywołuje te syscall’e, VEH pomija przejście do jądra i zwraca uchwyty oraz base addresses przygotowanego złośliwego obrazu.
Ponieważ loader nadal uważa, że zmapował żądany DLL, narzędzia patrzące jedynie na pliki backing section widzą wmp.dll, nawet jeśli pamięć zawiera teraz payload adversary. Tymczasem imports/TLS callbacks są nadal rozwiązywane przez prawdziwy loader, co znacząco zmniejsza ilość własnej logiki parsującej PE, którą adversary musi utrzymywać.
Etap 1 – Build the disguised section
- 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);
- Skopiuj złośliwy PE do tego widoku sekcja po sekcji, respektując
SizeOfRawData/VirtualSizei aktualizując ochrony później (PAGE_EXECUTE_READ,PAGE_READWRITE, itd.). - Zastosuj relocacje i rozwiąż importy dokładnie tak, jak zrobiłby to reflective loader. Ponieważ widok jest już zmapowany jako
SEC_IMAGE, wyrównania sekcji i guard pages odpowiadają temu, czego spodziewa się Windows loader. - Normalizuj nagłówek PE:
- Jeśli payload jest EXE, ustaw
IMAGE_FILE_HEADER.Characteristics |= IMAGE_FILE_DLLi wyzeruj entry point, aby powstrzymaćLdrpCallTlsInitializersprzed skokiem do stubów specyficznych dla EXE. - DLL payloady mogą pozostawić nagłówki bez zmian.
W tym momencie proces posiada widok z możliwością RWX, którego backing object to nadal wmp.dll, a jednak bajty w pamięci są kontrolowane przez adversary.
Etap 2 – Hijack the loader with VEHs
- Zarejestruj VEH i uzbraj hardware breakpoints: zaprogramuj
Dr0(lub inny rejestr debugowania) adresemntdll!NtOpenSectioni ustawDR7, tak by każde wykonanie zgłaszałoSTATUS_SINGLE_STEP. Powtórz później dlaNtMapViewOfSectioni opcjonalnieNtClose. - Wywołaj ładowanie DLL przez
LoadLibrary("amsi.dll").LdrLoadDllostatecznie wywołaNtOpenSection, aby uzyskać realny section handle. - VEH hook dla
NtOpenSection:
- Znajdź slot na stosie odpowiadający argumentowi
[out] PHANDLE SectionHandle. - Zapisz wcześniej utworzony uchwyt
DecoySectiondo tego slotu. - Przesuń
RIP/EIPdo instrukcjiret, aby nigdy nie wywoływać jądra. - Ponownie uzbrój hardware breakpoint, aby obserwować
NtMapViewOfSectionnastępnie.
- VEH hook dla
NtMapViewOfSection:
- Nadpisz
[out] PVOID *BaseAddress(i pola rozmiaru/ochrony) adresem już zmapowanego złośliwego widoku. - Pomiń ciało syscall tak jak wcześniej.
- (Opcjonalne) VEH hook dla
NtCloseweryfikuje, że fałszywy section handle jest czyszczony, zapobiegając resource leaks i dostarczając ostatecznego sanity check.
Ponieważ syscall’e nigdy nie są wykonywane, kernel callbacks (ETWti, minifilter, itd.) nie obserwują podejrzanych zdarzeń NtOpenSection/NtMapViewOfSection, co drastycznie obniża telemetry. Z perspektywy loadera wszystko zakończyło się sukcesem i amsi.dll znajduje się w pamięci, więc kontynuuje rozwiązywanie importów/TLS względem bajtów adversary.
Etap 3 – Execute the payload
- EXE payload: Injector po prostu skacze do oryginalnego entry point po wykonaniu relocations. Gdy loader uważa, że wywoła
DllMain, custom code zamiast tego wykonuje entry w stylu EXE. - DLL payload / Node.js addon: Rozwiąż i wywołaj zamierzony export (Kidkadi udostępnia nazwaną funkcję do JavaScript). Ponieważ moduł jest już zarejestrowany w
LdrpModuleBaseAddressIndex, kolejne wyszukiwania widzą go jako benign DLL.
Po połączeniu z Node.js native addon (.node file), całe ciężkie operacje związane z Windows-internals pozostają poza warstwą JavaScript, co pomaga threat actorowi dostarczyć ten sam loader z wieloma różnymi obfuskowanymi Node wrapperami.
Referencje
- Check Point Research – GachiLoader: Defeating Node.js Malware with API Tracing
- VectoredOverloading – PoC implementation
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


