Plugin di trasporto C2 serverless per AdaptixC2 v1.2 che utilizza AWS Lambda + DynamoDB come infrastruttura di relay.

Plugin di trasporto C2 serverless per AdaptixC2 v1.2 che utilizza AWS Lambda + DynamoDB come infrastruttura di relay. Il traffico dell'agente appare come HTTPS in uscita verso gli endpoint AWS, senza richiedere porte in ingresso o IP pubblici sul server C2.
Kharon Agent (target)
|
| HTTPS GET/POST (outbound only, randomly alternated)
v
AWS Lambda Function URL (stateless relay)
|
| Store inbound / Poll outbound (up to 8s)
v
DynamoDB (inbound + outbound tables)
^
| Poll every 5 seconds
|
Listener Plugin (inside AdaptixC2)
|
| TsAgent API + TsExtenderData (key persistence)
v
AdaptixC2 Teamserver + UI
Flusso dei dati:
inboundoutbound per un massimo di 8 secondi (colma il divario asincrono per la registrazione)inbound per i record non elaboratioutbound| Componente | Percorso | Scopo |
|---|---|---|
| Agente Kharon | agent/ | Impianto Kharon incluso (sorgente C++) |
| Terraform | deploy/aws/ | Infrastruttura Lambda + DynamoDB + IAM + KMS |
| Relay Lambda | deploy/aws/lambda/ | Proxy stateless da HTTP a DynamoDB con polling in uscita |
| Plugin listener | listener/ | Plugin AdaptixC2, polling DynamoDB, bridge del protocollo Kharon |
| Configurazioni Kharon | kharon/ | Registrazione dei comandi AXS e configurazione per gli extender dell'agente/listener |
| Patch | patches/ | Patch del sorgente di AdaptixC2 per il supporto a BeaconServerless |
| Profili | profiles/ | Profilo HTTP malleabile per l'URL Lambda |
| Script | scripts/ | Installazione, build, deploy, disinstallazione |
aws configure)apt install clang lldapt install nasmapt install binutils-mingw-w64-x86-64Nella console 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
Verifica:
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
Questo script:
dist/ (certificati, database, profilo)GOEXPERIMENT dal binario del server.so) con i flag corrispondentiBeaconServerlessrelay_api_key nel tuo 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"
}
| Campo | Descrizione | Predefinito |
|---|---|---|
| AWS Region | Regione in cui viene distribuita l'infrastruttura | us-east-1 |
| Lambda URL | URL della funzione dall'output di Terraform | (obbligatorio) |
| Relay API Key | Deve corrispondere a relay_api_key di Terraform | (facoltativo) |
| Inbound Table | Tabella DynamoDB per i check-in degli agenti | adaptix-inbound |
| Outbound Table | Tabella DynamoDB per le risposte del server | adaptix-outbound |
| Poll Interval | Frequenza di controllo di DynamoDB (secondi) | 5 |
| TTL Hours | Scadenza dei record DynamoDB | 24 |
L'agente Kharon utilizza un protocollo binario personalizzato su HTTP:
[36-byte UUID][encrypted_checkin_data][16-byte LokyCrypt key][36-byte UUID][encrypted_payload] (nessuna chiave finale)TotalLen-16 si sovrappone all'area dell'UUID. Per un pacchetto di 44 byte, la chiave inizia all'offset 28, sovrascrivendo i byte 28-35 dell'UUID e tutti i dati cifrati.Il listener rileva tutti e tre i formati e li gestisce correttamente.
La natura asincrona di Lambda + DynamoDB fa sì che il listener non abbia ancora elaborato il record inbound quando Lambda controlla per la prima volta la presenza di una risposta. Lambda esegue il polling della tabella outbound per un massimo di 8 secondi dopo aver memorizzato un record inbound, dando al listener il tempo di elaborare e accodare la risposta. Questo è fondamentale per la registrazione (la risposta Checkin deve arrivare durante la fase Checkin, non in un successivo GetTask).