Изучение "вредоносного ПО нового поколения" - NightHawk's

Попытка обфускации и усыпления

suspicious.actor/2022/05/05/mdsec-nighthawk-study.html

5 мая 2022 г. - Остин Хадсон


За последние полтора года я часто встречал упоминания о самопровозглашенной "вредоносной программе нового поколения" под названием NightHawk.
вредоносной программе" под названием NightHawk. Обычно я знаю, что большинство таких заявлений - не более чем гордыня.
не более чем высокомерие, и решил бы игнорировать их, но мне стало скучно. Поэтому я решил
начать анализировать и размышлять о вредоносном ПО на основе образцов, которые я получил через VirusTotal, центр, который содержит множество образцов.
который содержит множество коммерческих, закрытых и открытых образцов. Этот
исследование проводится в мое личное время и не связано ни с кем, кроме меня. Я
порвал о других похожих вредоносных программах, таких как Beacon от Cobalt Strike.

TLDR: Очень простая, но эффективная техника. Можно ли это легко воспроизвести? Да! Было ли это
что-то новое? К счастью, нет. Немного разочарован? Немного.

Понимание его PE-SIEVE / Moneta Evasion

Некоторое время назад один мой друг сообщил мне о видео, в котором утверждалось, что оно способно
обойти инструмент сканирования памяти Хашерезады PE-SIEVE, а также Forrest's
Moneta, что вызвало мой интерес, поскольку я разработал аналогичную возможность за несколько лет до этого, чтобы улучшить оригинальное исследование.
лет до этого, чтобы улучшить оригинальное исследование под названием Gargoyle для x86/x64/WOW64.

Сначала я был заинтригован этой техникой. Возможно, существует более простой метод, который я
упустил? К счастью для меня, не очень. Дальнейшее изучение показало, что он поддерживает множество
спящие методы, такие как использование NtSignalAndWaitForSingleObject путем уведомления о событии, а затем ожидание в текущем процессе.
событие, затем ожидание в текущем процессе, оставаясь при этом не тревожным, или используя
NtWaitForSingleObject, чтобы ожидать на текущем объекте процесса, оставаясь не оповещаемым.

Evt = CreateEventW( NULL, 0, 0, 0, NULL );

if ( Evt != NULL ) {
Nst = NtSignalAndWaitForSingleObject( Evt, NtCurrentProcess(), FALSE, &Del );
}

  Псевдо-C, демонстрирующий основную концепцию использования NtSignalAndWaitForSingleObject

Ничего нового, к счастью. Он используется как средство обхода проверки на HuntingSleeping-Beacons для скрытия обнаружений, основанных на статусе ожидания DelayExecution для потоков.
Этого, безусловно, достаточно, и я сам так делал.
  Однако его ухищрения скрыть следы себя в памяти немного отличаются. Сначала он (как я полагаю)
использует RtlCaptureContext в качестве обратного вызова kernel32!CreateTimerQueueTimer с
аргументом структуры контекста для захвата значения адреса возврата для возврата. Вызов
ниже воспроизведет аналогичное поведение:

if ( CreateTimerQueueTimer( &TimerObj, TimerQueue, RtlCaptureContext, ContextStruct,
0, 0, WT_EXECUTEINTIMERTHREAD ))
{
WaitForSingleObject( TimerObj, 50 );
}


  Обратный вызов будет оперативно выполнен в новом потоке, и на x64 RSP будет заполнен
полным адресом возврата. После этого NightHawk заполняет структуры
структуры CONTEXT вызова функций для VirtualProtect , SuspendThread ,
GetThreadContext , SetThreadContext , и ResumeThread . Эти контекстные структуры
позволяют NightHawk перенаправить выполнение на указанные функции с полным контролем над RSP,
RCX , RDX , R8 , R9 .

Он не имеет дальнейшего контроля над любыми функциями, которые имеют более 4 аргументов на x64, из-за
из-за использования таймеров и сильной зависимости от своего обратного вызова завершения от вызова
указанного обратного вызова. Более того, он корректирует RSP до 8 байт, чтобы учесть смещение
созданное вызовом RtlCaptureContext .

__builtin_memcpy( & ContextVirtualProtect, & ContextStructure, sizeof(
ContextStructure ) );
ContextVirtualProtect.Rsp -= 8;
ContextVirtualProtect.Rip = VirtualProtect
ContextVirtualProtect.Rcx = NightHawkImageBase;
ContextVirtualProtect.Rdx = NightHawkImageLength;
ContextVirtualProtect.R8 = PAGE_READWRITE
ContextVirtualProtect.R9 = &OriginalProtect;

__builtin_memcpy( & ContextSuspendThread, & ContextStructure, sizeof(
ContextStructure ) );
ContextSuspendThread.Rsp -= 8;
ContextSuspendThread.Rip = SuspendThread;
ContextSuspendThread.Rcx = MyOriginalThreadHandle;

После того, как вызов был построен, он затем пытается поставить его в очередь, используя ту же функцию таймера с
обратным вызовом, установленным на NtContinue или RtlRestoreContext, который будет использовать контекст
структуру для выполнения указанной функции с установленными регистрами и безопасного возврата без
не вызывая потенциального сбоя - При этом оперативно регулируя временной интервал между вызовами, чтобы
чтобы избежать нарушения очередности выполнения функций.

  LARGE_INTEGER Time;
RtlSecureZeroMemory( &Time, sizeof( Time ));
Time.QuadPart += 100;
CreateTimerQueueTimer( TimerObj, TimerQueue, RtlRestoreContext,
&ContextVirtualProtect, &Time, 0, WT_EXECUTEINTIMERTHREAD );
Time.QuadPart += 100;
CreateTimerQueueTimer( TimerObj, TimerQueue, RtlRestoreContext,
&ContextSuspendThread, &Time, 0,
WT_EXECUTEINTIMERTHREAD );

В результате очередь таймеров сначала выполнит ContextVirtualProtect, а затем
ContextSuspendThread, чтобы избежать проблем, связанных с их конфликтом или запуском до того, как одна из них благополучно завершится
безопасного завершения. Но сначала! Чтобы избежать проблем, связанных с выполнением вызовов до того, как очередь достигнет состояния
состояния ожидания, он будет использовать WaitForSingleObject для блокировки до тех пор, пока очередь таймера не будет завершена
завершится. Это очень похоже на то, как я выполнил свою цепочку Foliage/Gargyoyle несколько лет назад.
лет назад, и все так же эффективно.

В ближайшие дни я поделюсь своим PoC, воспроизводящим их вариацию до конца. Для
тех из вас, кто использует Cobalt или другие аналогичные наборы инструментов, и не хочет тратить $30K,
к счастью, этого можно достичь с минимальными усилиями и инструментами, используя что-то вроде
пользовательского Reflective Loader, который я буду повторно размещать мой вариант Titan с их
реализации.