
C2Bridges позволяют разработчикам создавать новые пользовательские протоколы связи и быстро использовать их в Covenant.
C2Bridges позволяют разработчикам создавать новые пользовательские протоколы связи и быстро использовать их в Covenant.
C2Bridges используются для разработки исходящего протокола управления и контроля без редактирования кода Covenant. Для разработчиков, которые чувствуют себя комфортно при интеграции новых слушателей, новый протокол C2 следует добавлять как полноценный тип слушателя первого класса, полностью интегрированный в интерфейс. Однако в некоторых ситуациях может быть быстрее создать C2Bridge вне Covenant и подключить его к BridgeListener для концептуальных прототипов или тестирования новых протоколов.
Разработчики могут использовать проект C2Bridge в качестве шаблона для создания новых C2Bridges. В проекте C2Bridge есть абстрактный класс C2Bridge. Разработчик может унаследоваться от этого класса и реализовать необходимые функции для чтения и записи имплантов в BridgeListener с помощью нового выбранного протокола C2.
using System.Threading;
using System.Threading.Tasks;
namespace C2Bridge
{
/// <summary>
/// IC2Bridge — это интерфейс, реализуемый классом C2Bridge.
/// </summary>
public interface IC2Bridge
{
Task RunAsync(CancellationToken token);
}
/// <summary>
/// C2Bridge — это абстрактный класс, от которого должны наследоваться новые C2Bridges.
/// </summary>
public abstract class C2Bridge : IC2Bridge
{
// BridgeConnector обрабатывает связь между сервером Covenant и C2Bridge
protected BridgeConnector BridgeConnector { get; set; }
// BridgeProfile обрабатывает парсинг и форматирование данных, передаваемых между имплантом и Covenant
protected BridgeProfile BridgeProfile { get; set; }
/// <summary>
/// Конструктор для C2Bridge. Новые C2Bridges должны использовать свой собственный конструктор,
/// который принимает любые аргументы командной строки, необходимые для работы C2Bridge.
/// </summary>
/// <param name="Connector">BridgeConnector, который обрабатывает связь с сервером Covenant.</param>
/// <param name="Profile">BridgeProfile, который обрабатывает парсинг и форматирование данных.</param>
protected C2Bridge(BridgeConnector Connector, BridgeProfile Profile)
{
this.BridgeConnector = Connector;
this.BridgeProfile = Profile;
BridgeConnector.OnReadBridge += OnReadBridge;
}
/// <summary>
/// Функция RunAsync является основной функцией, которая должна запустить C2Bridge и продолжать работу, пока
/// вы не завершите свою операцию. Разработчики C2Bridge должны реализовать логику запуска и работы слушателя
/// в этой функции.
/// </summary>
/// <param name="Token">CancellationToken, который отменит C2Bridge, если источник токена будет отменён.</param>
/// <returns></returns>
public abstract Task RunAsync(CancellationToken Token);
/// <summary>
/// Функция OnReadBridge вызывается каждый раз, когда с сервеера Covenant считываются данные, предназначенные для импланта.
/// Разработчики C2Bridge должны реализовать логику для определения, какому импланту предназначены эти данные, и записать
/// эти данные в имплант.
/// </summary>
/// <param name="sender">
/// Sender — это объект, который вызвал функцию OnReadBridge. Разработчики C2Bridge могут игнорировать этот параметр.
/// </param>
/// <param name="args">Args содержит данные, которые должны быть записаны с сервера Covenant в имплант.</param>
protected abstract void OnReadBridge(object sender, BridgeConnector.ReadBridgeArgs args);
/// <summary>
/// Функция WriteToConnector обрабатывает запись данных от импланта на сервер Covenant. Эта логика должна быть
/// одинаковой для всех типов C2Bridge, но может быть перегружена разработчиком C2Bridge, если требуется пользовательская логика.
///
/// При вызове этой функции возвращаемая строка GUID должна использоваться для отслеживания значений GUID импланта в C2Bridge.
/// </summary>
/// <param name="Data">Данные, прочитанные из импланта, которые должны быть записаны на сервер Covenant.</param>
/// <returns>
/// Возвращает значение GUID, извлечённое из Data. Это значение должно использоваться для отслеживания значений GUID импланта в C2Bridge.
/// </returns>
protected virtual string WriteToConnector(string Data)
{
var parsed = this.BridgeProfile.ParseWrite(Data);
if (parsed != null)
{
_ = this.BridgeConnector.Write(this.BridgeProfile.FormatRead(parsed));
return parsed.Guid;
}
return null;
}
/// <summary>
/// Функция GetBridgeMessengerCode должна содержать код, который будет встроен в имплант для связи с
/// C2Bridge. Эта функция нигде не используется в проекте, но она здесь для того, чтобы необходимый
/// код импланта можно было найти вместе с C2Bridge. Разработчики C2Bridge должны разместить код здесь для использования в
/// свойстве BridgeMessengerCode BridgeProfile.
/// </summary>
/// <returns></returns>
protected abstract string GetBridgeMessengerCode();
}
}
Проект C2Bridge содержит пример класса TCPC2Bridge, который наследуется от этого интерфейса и предоставляет пример того, как его реализовать.

После того как вы написали свой новый C2Bridge, вызов конструктора TCPC2Bridge в функции Main() можно заменить на новый конструктор:

Абстрактный метод GetBridgeMessengerCode() нигде не используется в проекте C2Bridge, но он используется для связывания C2Bridge с имплантом. Импланту нужен код, который может читать и записывать данные в исходящий C2Bridge. Этот код специфичен для конкретного C2Bridge и должен быть помещён в унаследованный метод GetBridgeMessengerCode(). Пользователь Covenant, использующий C2Bridge, возьмёт BridgeMessengerCode из этого метода и использует его в BridgeProfile.
Пользователям Covenant, использующим C2Bridge, необходимо будет настроить BridgeProfile, специфичный для этого C2Bridge. Импланты Grunt должны знать, как читать и записывать данные в исходящий C2Bridge. Свойство BridgeProfile.BridgeMessengerCode представляет собой код, который будет помещён в имплант и отвечает за чтение и запись в исходящий C2Bridge. Этот код должен быть найден в методе GetBridgeMessengerCode() C2Bridge.
Пользователи могут создать совершенно новый BridgeProfile или отредактировать DefaultBridgeProfile, указав правильный BridgeMessengerCode. Для этого перейдите на страницу навигации слушателей и выберите вкладку "Profiles":

Чтобы создать новый профиль, нажмите кнопку "Create". Чтобы отредактировать конкретный профиль, нажмите на его название. Имейте в виду, что вы не можете редактировать профили, связанные с активными слушателями.
После нажатия "Create" выберите вкладку "BridgeProfile":

При редактировании или создании профиля необходимо настроить следующие параметры: