
Внедрение шелл-кода с использованием Windows Debugging API
DbgNexum — это Proof-of-Concept для внедрения шеллкода с использованием Windows Debugging API и разделяемой памяти (File Mapping). Инструмент избегает прямой записи и чтения удалённой памяти, вместо этого применяя манипуляцию контекстом, чтобы заставить целевой процесс сам загрузить и выполнить пейлоад.
Инжектор подключается к целевому процессу и создаёт приостановленный поток. В цикле отладки он устанавливает аппаратную точку останова (Hardware Breakpoint), чтобы перехватить выполнение на конкретном адресе возврата. На каждом перехвате инжектор изменяет регистры CPU, имитируя вызовы функций, и оркестрирует последовательность вызовов Windows API внутри целевого процесса.
На момент написания этого README я протестировал технику против MDE и Elastic — ни одно из решений её не обнаружило.
WriteProcessMemory / VirtualAllocEx: пейлоад передаётся через CreateFileMapping и MapViewOfFile.ReadProcessMemory: весь ключевой набор информации получается из контекста потока.В PoC используется пропущенный через XOR шеллкод msfvenom, запускающий "calc.exe". Но пожалуйста, используйте свой собственный шеллкод!
shellcode.hDbgNexum.exe <PID>
Пример вывода:
[i] Section 'MZ' created and shellcode copied
[+] Bait thread created. Setting HWBP on FileTimeToSystemTime
[i] Execution Redirected:
|-> [0] Preparation & anchoring stack
|-> [1] Setting HWBP & buffer alloc
|-> [2] Copying File-Mapping name
|-> [3] Zeroing stack slot
|-> [4] Opening handle to named file mapping
|-> [5] Mapping payload into mem. with exec. perm.
|-> [6] Cleanup & shellcode execution
[+] Successfully detached from process 19256
[i] Orchestration complete.
Поток выполнения представляет собой постоянное переключение между циклом отладки (Debug Loop) инжектора и целевым процессом.
Стадии внедрения
Функция DebugLoop содержит основную логику внедрения и управляет "конечным автоматом":
0. Подготовка:
ret.1. Выделение памяти:
LocalAlloc для (очевидного) выделения небольшого буфера.2. Подготовка данных:
memcpy, чтобы скопировать строку MZ в ранее выделенный буфер.3. Подготовка стека:
memset, чтобы обнулить слот в стеке. Это подготовка к стадии 5, на которой будет вызван MapViewOfFile. Поскольку функция использует >4 аргументов, 5-й аргумент передаётся через стек (который мы настраиваем здесь).4. Открытие отображения:
OpenFileMappingA, используя имя MZ, "созданное" на стадиях 2 и 3.5. Отображение пейлоада:
MapViewOfFile. Это отображает раздел разделяемой памяти (содержащий шеллкод) в адресное пространство цели с правами EXECUTE.6. Выполнение:
RIP на адрес, возвращённый MapViewOfFile.