Vectored Overloading PE Injection

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Огляд техніки

Vectored Overloading — це Windows PE injection primitive, що поєднує класичний Module Overloading з Vectored Exception Handlers (VEHs) та hardware breakpoints. Замість того, щоб патчити LoadLibrary або писати власний лоадер, нападник:

  1. Створює SEC_IMAGE section, підкріплену легітимною DLL (наприклад, wmp.dll).
  2. Перезаписує відображений view повністю релокованим шкідливим PE по секціях, при цьому об’єкт section лишається прив’язаний до benign image на диску.
  3. Реєструє VEH і програмує debug registers так, щоб кожен виклик NtOpenSection, NtMapViewOfSection, і за потреби NtClose викликав user-mode breakpoint.
  4. Викликає LoadLibrary("amsi.dll") (або будь-яку іншу benign ціль). Коли Windows loader викликає ці syscall’и, VEH перериває перехід у kernel і повертає дескриптори і базові адреси підготовленого шкідливого образу.

Оскільки loader все ще вважає, що відобразив запитану DLL, інструменти, які дивляться лише на section backing files, бачать wmp.dll, хоча в пам’яті тепер міститься payload нападника. Тим часом imports/TLS callbacks все ще резолвляться genuine loader’ом, значно зменшуючи обсяг власної логіки розбору PE, яку мусить підтримувати нападник.

Stage 1 – Build the disguised 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. Copy the malicious PE into that view секція за секцією, дотримуючись SizeOfRawData/VirtualSize і оновлюючи права доступу після цього (PAGE_EXECUTE_READ, PAGE_READWRITE тощо).
  2. Apply relocations and resolve imports точно так само, як це робив би reflective loader. Оскільки view вже змеплена як SEC_IMAGE, вирівнювання section і guard pages відповідають тому, що очікує Windows loader пізніше.
  3. Normalize the PE header:
  • Якщо payload — EXE, встановіть IMAGE_FILE_HEADER.Characteristics |= IMAGE_FILE_DLL і зануліть entry point, щоб LdrpCallTlsInitializers не стрибав у EXE-специфічні заглушки.
  • DLL payload’и можуть залишити свої заголовки без змін.

На цьому етапі процес має RWX-можливий view, чиє backing object все ще wmp.dll, проте байти в пам’яті контролює нападник.

Stage 2 – Hijack the loader with VEHs

  1. Register a VEH and arm hardware breakpoints: запрограмуйте Dr0 (або інший debug register) з адресою ntdll!NtOpenSection і встановіть DR7, щоб кожне виконання породжувало STATUS_SINGLE_STEP. Повторіть пізніше для NtMapViewOfSection і за потреби NtClose.
  2. Trigger DLL loading викликом LoadLibrary("amsi.dll"). LdrLoadDll врешті викличе NtOpenSection, щоб отримати реальний section handle.
  3. VEH hook for NtOpenSection:
  • Знайдіть слот в стеку для [out] PHANDLE SectionHandle аргумента.
  • Запишіть туди раніше створений DecoySection handle.
  • Просуньте RIP/EIP до інструкції ret, щоб виклик до kernel не відбувся.
  • Перезарядьте hardware breakpoint, щоб стежити за NtMapViewOfSection наступним.
  1. VEH hook for NtMapViewOfSection:
  • Перезапишіть [out] PVOID *BaseAddress (та вихідні поля для розміру/прав доступу) адресою вже змепленого шкідливого view.
  • Пропустіть тіло syscall так само, як і раніше.
  1. (Optional) VEH hook for NtClose перевіряє, що фейковий section handle очищено, запобігаючи resource leaks і надаючи фінальну перевірку коректності.

Оскільки syscalls ніколи не виконуються, kernel callbacks (ETWti, minifilter тощо) не спостерігають підозрілих NtOpenSection/NtMapViewOfSection подій, що різко знижує телеметрію. З точки зору loader’а все пройшло успішно і amsi.dll знаходиться в пам’яті, тому він продовжує резолв imports/TLS проти байтів нападника.

Stage 3 – Execute the payload

  • EXE payload: injector просто стрибає до оригінального entry point після завершення relocations. Коли loader вважає, що має викликати DllMain, натомість виконується код у стилі EXE.
  • DLL payload / Node.js addon: резолвте і викличте цільовий export (Kidkadi експонує іменовану функцію для JavaScript). Оскільки модуль вже зареєстрований в LdrpModuleBaseAddressIndex, подальші пошуки бачать його як benign DLL.

У поєднанні з Node.js native addon (.node файл) вся важка робота з Windows-інтернами залишається поза шаром JavaScript, що допомагає threat actor’у постачати той же loader з різними обфусцированими Node-обгортками.

References

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks