Плагин serverless C2-транспорта для AdaptixC2 v1.2, использующий AWS Lambda + DynamoDB в качестве инфраструктуры ретрансляции.

Плагин транспорта Serverless C2 для AdaptixC2 v1.2, использующий AWS Lambda + DynamoDB в качестве ретрансляционной инфраструктуры. Трафик агента выглядит как исходящий HTTPS к эндпоинтам AWS, не требуя входящих портов или публичных IP-адресов на C2-сервере.
Kharon Agent (цель)
|
| HTTPS GET/POST (только исходящий, случайное чередование)
v
AWS Lambda Function URL (stateless-ретранслятор)
|
| Сохранение входящих / Опрос исходящих (до 8 с)
v
DynamoDB (таблицы inbound + outbound)
^
| Опрос каждые 5 секунд
|
Плагин-листенер (внутри AdaptixC2)
|
| TsAgent API + TsExtenderData (сохранение ключей)
v
AdaptixC2 Teamserver + UI
Поток данных:
inboundoutbound до 8 секунд (сглаживает асинхронный разрыв при регистрации)inbound на предмет необработанных записейoutbound| Компонент | Путь | Назначение |
|---|---|---|
| Агент Kharon | agent/ | Встроенный имплант Kharon (исходники на C++) |
| Terraform | deploy/aws/ | Инфраструктура Lambda + DynamoDB + IAM + KMS |
| Lambda-ретранслятор | deploy/aws/lambda/ | Stateless-прокси HTTP-to-DynamoDB с опросом исходящих |
| Плагин-листенер | listener/ | Плагин AdaptixC2, опрос DynamoDB, мост протокола Kharon |
| Конфигурации Kharon | kharon/ | Регистрация команд AXS и конфигурация для расширений агента/листенера |
| Патчи | patches/ | Патчи исходников AdaptixC2 для поддержки BeaconServerless |
| Профили | profiles/ | Malleable HTTP-профиль для Lambda URL |
| Скрипты | scripts/ | Установка, сборка, развёртывание, удаление |
aws configure)apt install clang lldapt install nasmapt install binutils-mingw-w64-x86-64В консоли AWS:
adaptix-deployerAmazonDynamoDBFullAccessAWSLambda_FullAccessIAMFullAccessCloudWatchLogsFullAccess{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"kms:*","Resource":"*"}]}KMSFullAccessaws configure
# AWS Access Key ID: <paste access key>
# AWS Secret Access Key: <paste secret key>
# Default region: us-east-1
# Default output format: json
Проверка:
aws sts get-caller-identity
# Build the Lambda relay binary (cross-compiled for Amazon Linux)
./scripts/build_relay.sh
# Deploy Lambda + DynamoDB + IAM with Terraform
./scripts/deploy_infra.sh
# Note the Lambda Function URL from the output, e.g.:
# lambda_function_url = "https://xxxxx.lambda-url.us-east-1.on.aws"
./scripts/install.sh /path/to/AdaptixC2
Этот скрипт выполнит:
dist/ (сертификаты, база данных, профиль)GOEXPERIMENT из бинарника сервера.so) с совпадающими флагамиBeaconServerlessrelay_api_key в вашем terraform.tfvars)profiles/lambda_default.jsonBeaconServerlessdeploy/aws/terraform.tfvars)region = "us-east-1"
function_name = "adaptix-relay"
relay_api_key = "your-secret-key-here"
tags = {
Project = "adaptix-serverless"
}
| Поле | Описание | По умолчанию |
|---|---|---|
| AWS Region | Регион, где развёрнута инфраструктура | us-east-1 |
| Lambda URL | Function URL из вывода Terraform | (обязательно) |
| Relay API Key | Должен совпадать с relay_api_key в Terraform | (опционально) |
| Inbound Table | Таблица DynamoDB для check-in агентов | adaptix-inbound |
| Outbound Table | Таблица DynamoDB для ответов сервера | adaptix-outbound |
| Poll Interval | Как часто опрашивать DynamoDB (секунды) | 5 |
| TTL Hours | Срок жизни записей DynamoDB | 24 |
Агент Kharon использует собственный бинарный протокол поверх HTTP:
[36-byte UUID][encrypted_checkin_data][16-byte LokyCrypt key][36-byte UUID][encrypted_payload] (без завершающего ключа)TotalLen-16 перекрывает область UUID. Для 44-байтового пакета ключ начинается со смещения 28, перезаписывая байты UUID 28-35 и все зашифрованные данные.Листенер распознаёт все три формата и корректно их обрабатывает.
Асинхронная природа Lambda + DynamoDB означает, что листенер ещё не обработал входящую запись, когда Lambda впервые проверяет наличие ответа. Lambda опрашивает таблицу outbound до 8 секунд после сохранения входящей записи, давая листенеру время обработать и поставить ответ в очередь. Это критично для регистрации (ответ Checkin должен прийти во время фазы Checkin, а не при более позднем GetTask).
Ключи шифрования агентов сохраняются через TsExtenderDataSave/TsExtenderDataLoad (на базе SQLite). Это переживает перезапуски службы. При перезапуске листенер восстанавливает ключи из постоянного хранилища, когда встречает известный ID агента.