
POC для затруднения/обхода аналитиков вредоносного ПО
Последующая работа является PoC, позволяющим вредоносному ПО «привязать» себя к конкретной жертве, чтобы затруднить усилия аналитиков вредоносных программ.
Я не несу ответственности за злонамеренное использование любых идей или кода, содержащихся в этом проекте. Я предоставляю это исследование для дальнейшего обучения специалистов по информационной безопасности, а также для дополнительного обучения/пищи для размышлений аналитиков вредоносных программ, специалистов по обратной разработке и Blue Team в целом.
При первом запуске вредоносной программы на жертве она шифрует AES фактическую полезную нагрузку (RDLL), используя данные окружения этой жертвы. При каждом последующем запуске вредоносная программа собирает те же данные окружения, расшифровывает AES полезную нагрузку, хранящуюся в виде массива байтов внутри программы, и запускает её. Если расшифровка не удаётся или полезная нагрузка не запускается, вредоносная программа удаляет себя сама. Защита от специалистов по обратной разработке и аналитиков вредоносных программ.


Я решил, что проект ещё не завершён, поэтому вернулся и сделал довольно существенную переработку. Оригинальное исследование и методы можно найти здесь.
Основные изменения следующие:
Есть довольно много разных вещей, которые можно взять из исходного кода этого проекта для использования в других местах. Надеюсь, кому-то это будет полезно.
Было несколько недостатков в оригинальном релизе BeatRev, которые я решил попытаться исправить.
Ранее Stage2 был отдельным исполняемым файлом, хранящимся в альтернативном потоке данных (ADS) Stage1. Для достижения AES-шифрования жертвой и последующей расшифровки и выполнения каждый раз при запуске Stage1 он читал ADS, расшифровывал его, записывал обратно в ADS, вызывал CreateProcess, а затем снова шифровал Stage2 и записывал его обратно на диск в ADS. Это было много операций ввода-вывода, и вызов CreateProcess, конечно, был не очень хорош.
Я наткнулся на исследование Стивена Фьюера о Reflective DLL, и оно показалось подходящим. Теперь Stage2 — это RDLL; наше вредоносное ПО/запускатель шелл-кода/что угодно, что мы хотим защитить, можно портировать в формат RDLL и хранить в виде массива байтов внутри Stage1, который затем расшифровывается во время выполнения и выполняется Stage1. Это устраняет все операции ввода-вывода и вызов CreateProcess из версии 1, что является приятным изменением.
Stage1 не имел никаких реальных мер обхода AV; это было сделано намеренно, так как это дополнительная работа и не было основной целью этого исследования. Во время переработки я принял это как дополнительный вызов и добавил хэширование API для удаления функций из таблицы импорта Stage1. Это помогло с обнаружением, и Stage1 имеет показатель обнаружения 4/66 на VirusTotal. Мне было комфортно загружать Stage1, поскольку он уже привязан к исходной машине, на которой он был запущен, и файловая подпись постоянно меняется из-за происходящего AES-шифрования.
Недавно я начал обращать внимание на энтропию как на средство обнаружения вредоносных ПО; чтобы попытаться снизить иначе очень высокую энтропию, которую огромный зашифрованный AES двоичный блок придаёт исполняемому файлу, я изучил интеграцию шелл-кода, хранящегося в виде UUID. Поскольку двоичный файл хранится в строковом представлении, общая энтропия в исполняемом файле ниже. Используя этот метод, энтропия Stage0 теперь составляет ~6,8, а Stage1 ~4,5 (по максимальной шкале 8).
Наконец, интегрировать и создать полный Stage0 — огромная работа из-за всех компонентов, которыми нужно манипулировать. Чтобы упростить это, я создал приложение-конструктор, которое принимает файл шаблона Stage0.c, заглушку Stage1, заглушку Stage2 и файл сырого шелл-кода (это было построено вокруг Stage2 как запускателя шелл-кода, содержащего шелл-код CobaltStrike) и создаёт скомпилированную полезную нагрузку Stage0 для использования на цели.
Код Reflective DLL от Стивена Фьюера содержит некоторые инструкции, специфичные для компилятора Visual Studio; я уверен, что можно портировать эту технику на MingW, но у меня нет навыков для этого. Основная проблема здесь в том, что шелл-код CobaltStrike (без состояния ~265К) должен быть помещён внутрь RDLL и скомпилирован. Чтобы обойти это и красиво интегрировать с остальным процессом, я написал свой Stage2 RDLL, содержащий глобальную переменную — блок памяти размером с шелл-код CS; этот блок памяти размером ~265К содержит небольшой заполнитель, который можно найти в скомпилированном двоичном файле. Код в src/Stage2 уже содержит это.
После компиляции эта заглушка Stage2stub переносится на kali, где может быть выполнено двоичное патчирование, чтобы вставить реальный шелл-код CS в то место памяти, где он должен быть. Это даёт полный Stage2.
Чтобы избежать ранее описанной катастрофы с вводом-выводом и CreateProcess, полный Stage2 также должен быть пропатчен в скомпилированный Stage1 с помощью Stage0; это необходимо для того, чтобы Stage2 мог быть зашифрован один раз на цели, а также чтобы предотвратить хранение Stage2 отдельно на диске. Та же концепция, описанная ранее для Stage2, выполняется Stage0 на цели для сборки конечной полезной нагрузки Stage1. Следует отметить, что функция memmem используется для поиска заполнителя внутри каждой заглушки; эта функция недоступна в Windows, поэтому была использована пользовательская реализация. Спасибо Foxik384 за его код.
Для выполнения двоичного патча мы должны заранее выделить необходимую память; это оказывает эффект накопления, так как Stage1 теперь должен быть достаточно большим, чтобы также содержать Stage2. С добавленным шагом преобразования Stage2 в строку UUID размер Stage2 и Stage1 увеличивается, чтобы вместить его. RDLL Stage2 скомпилированного размера ~290К приводит к полезной нагрузке Stage0 ~1.38М и полезной нагрузке Stage1 ~700К.
Приложение-конструктор поддерживает только создание x64 EXE. Однако при небольшой дополнительной работе теоретически можно сделать Stage0 DLL, а также Stage1, и сделать весь жизненный цикл реализованным как угон DLL вместо автономного исполняемого файла.
Эти инструкции помогут вам начать использовать этот PoC.