
Python API для использования со спецификацией External C2 от Cobalt Strike
Python-фреймворк для создания и использования интерфейсов передачи данных между фреймворками, с особым акцентом на использование в качестве расширения для фреймворков управления командными центрами (Command and Control).
В настоящее время это предполагается только как реализация спецификации External C2 от Cobalt Strike, описанной в этом документе спецификации, но по мере развития проекта это может измениться.
Огромная благодарность xychix. Этот проект был бы вообще невозможен без его ценного вклада. По сути, этот проект является переработкой и расширением проекта External C2 от Outflank
Этот проект состоит из следующих основных частей:
Builder считывает файл конфигурации и использует настроенные параметры для генерации сборки путём замены маркеров внутри skeletons.
Builder можно использовать с помощью . Пример конфигурации builder'а предоставлен как .
build_files.pysample_builder_config.config.sampleskeletons — это различные «скелеты» кода, которые builder динамически заполняет для генерации полностью рабочей сборки. skeletons содержат маркеры, которые будут заменены builder'ом на используемые значения. Существует три различных «типа» скелетов:
Маркер может быть размещён в любом файле внутри skeleton, и он будет заменён значением, указанным в конфигурации builder'а. Согласно лучшим практикам, маркеры никогда не должны использоваться для непосредственной записи переменных и должны использоваться только для установки значений. Если значение маркера необходимо использовать повторно, следует сохранить значение в переменной и ссылаться на него таким образом, вместо повторного использования того же маркера.
Формат маркера: ```[var:::identifier_for_the_marker]```
Строки будут записаны в скелет, обрамлённые одинарными кавычками, а числа будут записаны как есть.
В случае, если строка в конфигурации заключена в двойные кавычки, строка будет записана в файл в двойных кавычках, а обрамляющие одинарные кавычки будут удалены.
Эту зависимость можно продемонстрировать так:
#################
# Skeleton Code #
#################
# Skeleton contains the following line of code:
foo = ```[var:::bar]```
##############
# End Result #
##############
# Stored in config as:
# foo = bar
# Written as:
foo = 'bar'
# Stored in config as:
# foo = "bar"
# Written as:
foo = "bar"
# Stored in config as:
# foo = 2
# Written as:
foo = 2
# Stored in config as:
# foo = "2"
# Written as:
foo = "2"
Frameworks — это базовое приложение, которое определяет, какие данные используются transport и encoder, и как эти данные используются. То, что конкретный framework фактически делает, не имеет большого значения, если существует логика для импорта и использования encoder и transport. Большинство важных частей фреймворка (в первую очередь логика client) будут храниться в виде skeleton, а интерфейс для взаимодействия с серверной его частью будет храниться как базовый объект framework.
Как правило, фреймворк содержит server и client и использует encoders и transports для передачи данных между ними.
При создании framework следует учитывать несколько основных моментов:
framework отвечает за то, чтобы encoder был доступен transport для использования.framework использует связь клиент-сервер, они должны быть соответствующим образом организованы.client фреймворка, поэтому если вы хотите, чтобы что-то можно было перенастраивать на client, ему необходимо уметь делать это во время выполнения без прямого взаимодействия.skeleton для server, потому что конечный пользователь будет напрямую взаимодействовать с server фреймворка. Вместо этого следует как считывать параметры из конфигурации, так и давать конечному пользователю возможность изменять параметры (например, таймер блокировки или подробность вывода) во время выполнения.Skeleton фреймворка будет обработан builder'ом, который перебирает каждый файл в нём, поэтому, если определённый аргумент должен быть настраиваемым во время сборки, это можно легко сделать.server фреймворка должен иметь возможность взаимодействовать с общим framework_manager.Сервер — это приложение, которое обеспечивает связь между client и c2 server. Логика сервера в основном статична. Логика сервера для фреймворка cobalt_strike, называемая в спецификации third-party Client Controller, показана ниже:
encodertransporttransportencodertransporttransportencoderserver должен поддерживать возможность работы с несколькими клиентами (ещё не реализовано) и иметь интерфейс для взаимодействия с framework_manager.
Клиент — это, по сути, полезная нагрузка (payload), которая запускается на конечной точке. Логика клиента для фреймворка cobalt_strike в основном статична и показана ниже:
transporttransporttransport на предмет новых задачtransportКлиент использует указанные encoder и transport для передачи данных между собой и соответствующим server.
Encoders получают данные, а затем преобразуют их либо для подготовки к отправке через transport, либо декодируют данные, полученные через transport, обратно в исходную форму для интерпретации тем компонентом framework, который их использует.
Encoders должны рассчитывать на прямое взаимодействие с transport и обрабатывать данные независимо от фреймворка и компонента.
Transports выполняют роль отправки и получения данных через канал связи, а также взаимодействуют с encoder, чтобы гарантировать преобразование данных в необходимый формат. Transports должны получать данные от компонента фреймворка или через канал связи и иметь возможность передавать данные через канал связи. Transports отвечают за вызов encoder для кодирования или декодирования данных по мере необходимости.
Transports должны рассчитывать на прямое взаимодействие с компонентом framework и обрабатывать данные независимо от фреймворка и компонента.
Сначала определите, какие модули транспорта и кодирования вы хотите использовать. В следующем примере мы будем использовать transport_imgur и encoder_lsbjpg.
Затем создайте builder_config.config в соответствии с вашими потребностями; обратитесь к предоставленному примеру конфигурации и шаблону для понимания того, как это сделать.
Сгенерируйте сборку с помощью build_files.py. Например, можно сгенерировать сборку в каталоге builds, используя encoder_lsbjpg и transport_imgur для Cobalt Strike, с подробным выводом, следующей командой:
python build_files.py -b builds -f cobalt_strike -c sample_builder_config.config.sample -e encoder_lsbjpg -t transport_imgur -v
На машине, где запущен сервер, выполните:
python server.py
Для более подробного вывода можно выполнить:
python server.py -v
Для более подробного вывода и дополнительной информации, полезной для отладки, можно выполнить:
python server.py -d
Затем запустите клиента на целевой конечной точке.
Если всё сработало, в консоли Cobalt Strike будет зарегистрирован новый beacon, с которым вы можете взаимодействовать.
Зачем это писать?: Было выпущено не так много реализаций спецификации Cobalt Strike, а из тех, что выпущены, либо они написаны не на знакомом мне языке, либо в них нет модульности и абстракции, которые я искал.
Почему Python 2?: Я ленив, и на нём легко реализовывать новые каналы транспорта и кодирования.
Ваш код — отстой: Это не вопрос.
Могу ли я отправить новые модули транспорта и/или кодирования?: Да, пожалуйста! Отправьте pull request, и я с радостью его рассмотрю.
Как скомпилировать клиент в исполняемый файл, который можно распространять?:
Я успешно протестировал это в Kali. Чтобы воссоздать моё окружение, просто убедитесь, что у вас установлен veil-evasion и что вы прошли его настройку. Он должен настроить окружение wine с установленным python, в котором есть все необходимые зависимости. Возможно, вам также придётся установить модуль pefile в это окружение.
Затем вы можете перейти в каталог клиента, для которого хотите сгенерировать исполняемый файл, и выполнить:
chmod +x compile_dll.sh
./compile_dll.sh
wine "C:\\Python27\\python.exe" /usr/share/veil/pyinstaller/pyinstaller.py -F -r c2file.dll -w --key "ayyyyyyylmao" client.py
Замените значение key на то, которое вы хотите. Исполняемый файл клиента должен появиться в каталоге dist/. Если вы хотите сгенерировать исполняемый файл с консолью для отладки, скомпилируйте его с помощью wine "C:\\Python27\\python.exe" /usr/share/veil/pyinstaller/pyinstaller.py -F -r c2file.dll -c client.py.