Conti Ransomware malware leak WITH LOCKER
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

117 lines
6.0 KiB

ЦЕЛЬ
Новый бот является развитием идеи о легковесности.
В предыдущей версии был реализован минимальный набор функций - разные варианты запуска нагрузки, скачивание файла итд.
В новой версии даже эти функции будут вынесены из ядра и будут подгружаться по требованию в виде имплантов.
Таким образом мы попробуем минимизировать поверхность контакта с АВ.
Бот и его протокол является над/под-множеством предыдущих версий, то есть стыкуется с имеющимися и кодовой базой бэкендом бесшовно.
Часть команд протокола не используется, часть команд новые.
АРХИТЕКТУРА
Бот состоит из загрузчика, ядра и имплантов.
Загрузчик является опциональным, может быть можно грузить ядро напрямую ввиду его минимализма.
Функции ядра:
- запрос импланта (команды)
- отправка результата команды
- отправка телеметрии
Функции импланта - все остальное.
Формат импланта - либо двоичный позиционно-независимый код, либо .dll (вероятней всего .dll; станет ясно в процессе разработке).
Ядро вертится в цикле запроса команд, загружает имплант, загружает параметры и нагрузку к нему, запускает, отправляет результаты.
Есть противоречие между устойчивостью бота к сбою и обнаружимостью АВ:
- для устойчивости имплант лучше запускать в отдельном процессе;
- для необнаружимости лучше запускать имплант в своём процессе.
Противоречие снимаем добавлением флага контекста запуска.
Запуск в собственном процессе делается с помощью бесфайлового PE-загрузчика .dll - исходный код есть в сети.
Второй вариант - https://github.com/DimopoulosElias/SimpleShellcodeInjector/blob/master/SimpleShellcodeInjector.c
Для достижения устойчивости к сбою ядро бота должно быть обернуто в SEH/VEH-обработчики исключений.
Запускаемые потоки также должны иметь обработку исключений, позволяющую безопасно завершить и отцепить .dll после исключения.
Окончательная архитектура определится по результатам работы.
ПРОТОКОЛ
Общая канва протокола (цикл запрос-ответ, обработка ошибок, формат ответов итд) совпадает с протоколом версии 1.
Если не оговорено иначе, нагрузка отправляется в виде тела HTTP GET ответа.
Формат команды:
%code% %timeout% [%args%]
где
code - код команды
timeout - таймаут ожидания ответа (0 - запуск команды в фоновом режиме и готовность к запросу следующей команды)
args - аргументы различаются для разных типов команд
0 %timeout% - нет операции. Время - число секунд, на которое должен заснуть бот до следующего отстука на сервер.
117 %timeout% %payload% - запуск импланта в виде shell-кода. Другие параметры отсутствуют. Shell-код запускается в контексте текущего процесса.
Заметим, что отличие от команды 17 только в наличии таймаута. Возможно, эти две команды сольем в одну.
Нагрузка в двоичном виде, является позиционно-независимым двоичным кодом, выполняется ботом как есть, без каких-либо конверсий.
111 %timeout% ?caching? %payload% [%URI% [%args]] - запуск импланта в виде .dll.
caching == 0 разрешается кешировать данный имплант. FIXME а как бот поймет что это за имплант? нужен ид импланта?
== 1 имплант следует немедленно выгрузить после его завершения
URI - ссылка на основную нагрузку импланта.
Если основная нагрузка для данного импланта не используется, и это не последний аргумент команды,
то в качестве значения ставится знак - (минус).
Более подробная трактовка аргументов описана в соответствующем разделе.
?114 %timeout% - сброс кеша имплантов. Все закешированные импланты должны быть выгружены.
Отправка ответов и телеметрия совпадает с протоколом версии 1.
ИНТЕРФЕЙС ЯДРО-ИМПЛАНТ
Основной нюанс в передаче параметров импланту и получению ответа от импланта.
Для этого и ядро, и имплант предоставляют друг другу интерфейс.
Dll должна экспортировать минимум одну функцию со следующим интерфейсом:
DWORD WINAPI EntryPoint(
TELEMETRY_PROC lpTelemetryProc,
LPVOID payload,
SIZE_T paylen,
LPVOID args,
SIZE_T arglen
)
TELEMETRY_PROC определена так:
VOID WINAPI send_telemetry(CONST LPVOID message, SIZE_T len)
и является callback'ом для отправки телеметрии в админку.
Если оба аргумента функции send_telemetry являются нулями, это является сигналом от импланта к родителю о необходимости его выгрузки.
payload, paylen - нагрузка для импланта. Нагрузка скачивается ботом из %URI% (команда 111) и расшифровывается приватным ключом перед передачей в имплант.
FIXME тут вопрос как лучше - упростить бота и дать импланту самостоятельно возиться со своей нагрузкой? или подготовить это для него, раз уж для этого все есть.
args, arglen - указатель на буфер и его длину с кастомными аргументами импланта.
Имплант самостоятельно парсит и трактует аргументы.
Ядро модифицирует буфер перед передачей его импланту:
- производит замену подстроки %id% на идентификатор бота
- возможны другие макросы
Для этого ядро должно позаботиться о безопасности такой подстановки (реаллокациях буфера, при необходимости)
АДМИНКА
Команды типа "запустить .exe", "запустить скрипт" теперь будут реализованы через импланты.
Потому билдер команд должен конфигурироваться - ранее он был захардкожен, теперь пункты меню и доп.поля к ним будут браться из конфигов/конфигуратора.
Потому нужен конфигуратор команд, либо в виде формы, либо хотя бы в виде конфига.
Команда описывается следующими полями:
- имя команды
- файл с имплантом
- наличие основной нагрузки импланта
- тип основной нагрузки импланта: бинарная/текстовая
- дополнительный параметр 1 (тип поля)
- дополнительный параметр 2 (тип поля)
- ...
Основная нагрузка импланта - это запускаемый командами выполнения 10-13 файл.
Дополнительные параметры - это (в основном) командная строка для команд 10-13.