AdaptixC2 Extraction de configuration et TTPs
Reading time: 9 minutes
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
AdaptixC2 est un framework modulaire et openâsource de postâexploitation/C2 avec des beacons Windows x86/x64 (EXE/DLL/service EXE/raw shellcode) et prise en charge de BOF. Cette page documente :
- Comment sa configuration chiffrée RC4 est intégrée et comment l'extraire des beacons
- Indicateurs réseau/profil pour les listeners HTTP/SMB/TCP
- TTPs courants de loader et de persistence observés dans la nature, avec des liens vers des pages de techniques Windows pertinentes
Profils et champs des beacons
AdaptixC2 prend en charge trois types principaux de beacons :
- BEACON_HTTP: C2 web avec serveurs/ports/SSL configurables, mĂ©thode, URI, headers, userâagent, et un nom de paramĂštre personnalisĂ©
- BEACON_SMB: C2 peerâtoâpeer via namedâpipe (intranet)
- BEACON_TCP: sockets directs, éventuellement avec un marqueur préfixé pour obfusquer le démarrage du protocole
Champs de profil typiques observés dans les configs HTTP des beacons (aprÚs déchiffrement) :
- agent_type (u32)
- use_ssl (bool)
- servers_count (u32), servers (array of strings), ports (array of u32)
- http_method, uri, parameter, user_agent, http_headers (lengthâprefixed strings)
- ans_pre_size (u32), ans_size (u32) â used to parse response sizes
- kill_date (u32), working_time (u32)
- sleep_delay (u32), jitter_delay (u32)
- listener_type (u32)
- download_chunk_size (u32)
Example default HTTP profile (from a beacon build):
{
"agent_type": 3192652105,
"use_ssl": true,
"servers_count": 1,
"servers": ["172.16.196.1"],
"ports": [4443],
"http_method": "POST",
"uri": "/uri.php",
"parameter": "X-Beacon-Id",
"user_agent": "Mozilla/5.0 (Windows NT 6.2; rv:20.0) Gecko/20121202 Firefox/20.0",
"http_headers": "\r\n",
"ans_pre_size": 26,
"ans_size": 47,
"kill_date": 0,
"working_time": 0,
"sleep_delay": 2,
"jitter_delay": 0,
"listener_type": 0,
"download_chunk_size": 102400
}
Profil HTTP malveillant observé (attaque réelle) :
{
"agent_type": 3192652105,
"use_ssl": true,
"servers_count": 1,
"servers": ["tech-system[.]online"],
"ports": [443],
"http_method": "POST",
"uri": "/endpoint/api",
"parameter": "X-App-Id",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.6167.160 Safari/537.36",
"http_headers": "\r\n",
"ans_pre_size": 26,
"ans_size": 47,
"kill_date": 0,
"working_time": 0,
"sleep_delay": 4,
"jitter_delay": 0,
"listener_type": 0,
"download_chunk_size": 102400
}
Empaquetage de la configuration chiffrée et chemin de chargement
Lorsque l'opérateur clique sur Create dans le builder, AdaptixC2 intÚgre le profil chiffré en tant que tail blob dans le beacon. Le format est :
- 4 bytes: taille de la configuration (uint32, littleâendian)
- N bytes: données de configuration chiffrées par RC4
- 16 bytes: RC4 key
Le beacon loader copie la key de 16 bytes depuis la fin et RC4âdecrypts le bloc de N bytes en place:
ULONG profileSize = packer->Unpack32();
this->encrypt_key = (PBYTE) MemAllocLocal(16);
memcpy(this->encrypt_key, packer->data() + 4 + profileSize, 16);
DecryptRC4(packer->data()+4, profileSize, this->encrypt_key, 16);
Implications pratiques :
- L'ensemble de la structure se trouve souvent dans la section .rdata du PE.
- L'extraction est déterministe : lire la taille, lire le ciphertext de cette taille, lire la clé de 16 octets placée immédiatement aprÚs, puis déchiffrer avec RC4.
Flux de travail d'extraction de configuration (défenseurs)
Ăcrire un extracteur qui imite la logique du beacon :
- Localisez le blob dans le PE (gĂ©nĂ©ralement .rdata). Une approche pragmatique consiste Ă scanner .rdata Ă la recherche d'une mise en page plausible [size|ciphertext|16âbyte key] et tenter RC4.
- Lire les 4 premiers octets â size (uint32 LE).
- Lire les N=size octets suivants â ciphertext.
- Lire les 16 derniers octets â clĂ© RC4.
- Déchiffrer le ciphertext avec RC4. Puis analyser le profil en clair comme suit :
- scalaires u32/boolean comme indiquĂ© ciâdessus
- chaĂźnes prĂ©fixĂ©es par la longueur (u32 length suivi des octets ; un NUL terminal peut ĂȘtre prĂ©sent)
- tableaux : servers_count suivi de autant de paires [string, u32 port]
Preuve de concept Python minimale (autonome, sans dĂ©pendances externes) fonctionnant avec un blob prĂ©âextrait :
import struct
from typing import List, Tuple
def rc4(key: bytes, data: bytes) -> bytes:
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) & 0xFF
S[i], S[j] = S[j], S[i]
i = j = 0
out = bytearray()
for b in data:
i = (i + 1) & 0xFF
j = (j + S[i]) & 0xFF
S[i], S[j] = S[j], S[i]
K = S[(S[i] + S[j]) & 0xFF]
out.append(b ^ K)
return bytes(out)
class P:
def __init__(self, buf: bytes):
self.b = buf; self.o = 0
def u32(self) -> int:
v = struct.unpack_from('<I', self.b, self.o)[0]; self.o += 4; return v
def u8(self) -> int:
v = self.b[self.o]; self.o += 1; return v
def s(self) -> str:
L = self.u32(); s = self.b[self.o:self.o+L]; self.o += L
return s[:-1].decode('utf-8','replace') if L and s[-1] == 0 else s.decode('utf-8','replace')
def parse_http_cfg(plain: bytes) -> dict:
p = P(plain)
cfg = {}
cfg['agent_type'] = p.u32()
cfg['use_ssl'] = bool(p.u8())
n = p.u32()
cfg['servers'] = []
cfg['ports'] = []
for _ in range(n):
cfg['servers'].append(p.s())
cfg['ports'].append(p.u32())
cfg['http_method'] = p.s()
cfg['uri'] = p.s()
cfg['parameter'] = p.s()
cfg['user_agent'] = p.s()
cfg['http_headers'] = p.s()
cfg['ans_pre_size'] = p.u32()
cfg['ans_size'] = p.u32() + cfg['ans_pre_size']
cfg['kill_date'] = p.u32()
cfg['working_time'] = p.u32()
cfg['sleep_delay'] = p.u32()
cfg['jitter_delay'] = p.u32()
cfg['listener_type'] = 0
cfg['download_chunk_size'] = 0x19000
return cfg
# Usage (when you have [size|ciphertext|key] bytes):
# blob = open('blob.bin','rb').read()
# size = struct.unpack_from('<I', blob, 0)[0]
# ct = blob[4:4+size]
# key = blob[4+size:4+size+16]
# pt = rc4(key, ct)
# cfg = parse_http_cfg(pt)
Tips:
- Lors de l'automatisation, utilisez un parseur PE pour lire .rdata puis appliquez une fenĂȘtre glissante : pour chaque offset o, essayez size = u32(.rdata[o:o+4]), ct = .rdata[o+4:o+4+size], candidate key = next 16 bytes; RC4âdecrypt et vĂ©rifiez que les champs string se dĂ©codent en UTFâ8 et que les longueurs sont cohĂ©rentes.
- Analysez les profils SMB/TCP en suivant les mĂȘmes conventions prĂ©fixant la longueur.
Empreintes réseau et chasse
HTTP
- Fréquent : POST vers des URI choisies par l'opérateur (par ex., /uri.php, /endpoint/api)
- ParamĂštre d'enâtĂȘte personnalisĂ© utilisĂ© pour l'ID du beacon (par ex., XâBeaconâId, XâAppâId)
- Userâagents imitant Firefox 20 ou des builds Chrome contemporains
- Cadence de sondage visible via sleep_delay/jitter_delay
SMB/TCP
- Listeners de namedâpipe SMB pour C2 intranet lorsque la sortie web est limitĂ©e
- Les beacons TCP peuvent préfixer quelques octets avant le trafic pour obscurcir le début du protocole
TTPs de loader et de persistance observés dans des incidents
Chargeurs PowerShell en mémoire
- TĂ©lĂ©chargent des payloads Base64/XOR (InvokeâRestMethod / WebClient)
- Allouent de la mémoire non gérée, copient le shellcode, changent la protection en 0x40 (PAGE_EXECUTE_READWRITE) via VirtualProtect
- Exécutent via invocation dynamique .NET : Marshal.GetDelegateForFunctionPointer + delegate.Invoke()
Consultez ces pages pour l'exécution en mémoire et les considérations AMSI/ETW :
Mécanismes de persistance observés
- Raccourci dans le dossier Startup (.lnk) pour relancer un loader au logon
- Clés Run du registre (HKCU/HKLM ...\CurrentVersion\Run), souvent avec des noms à consonance bénigne comme "Updater" pour démarrer loader.ps1
- DLL searchâorder hijack en dĂ©posant msimg32.dll sous %APPDATA%\Microsoft\Windows\Templates pour des processus susceptibles
Approfondissements et vérifications techniques :
Privilege Escalation with Autoruns
Idées de chasse
- Transitions RWâRX initiĂ©es par PowerShell : VirtualProtect vers PAGE_EXECUTE_READWRITE dans powershell.exe
- Schémas d'invocation dynamique (GetDelegateForFunctionPointer)
- .lnk dans les dossiers Startup utilisateur ou communs
- Clés Run suspectes (ex., "Updater"), et noms de loader comme update.ps1/loader.ps1
- Chemins DLL inscriptibles par l'utilisateur sous %APPDATA%\Microsoft\Windows\Templates contenant msimg32.dll
Notes sur les champs OpSec
- KillDate : horodatage aprĂšs lequel l'agent s'autoâexpire
- WorkingTime : heures pendant lesquelles l'agent doit ĂȘtre actif pour se fondre dans l'activitĂ© professionnelle
Ces champs peuvent ĂȘtre utilisĂ©s pour le clustering et pour expliquer des pĂ©riodes d'inactivitĂ© observĂ©es.
YARA et pistes statiques
Unit 42 a publiĂ© des YARA basiques pour les beacons (C/C++ et Go) et des constantes de hachage d'API du loader. Envisagez de complĂ©ter avec des rĂšgles cherchant la mise en page [size|ciphertext|16âbyteâkey] prĂšs de la fin de .rdata du PE et les chaĂźnes du profil HTTP par dĂ©faut.
References
- AdaptixC2: A New Open-Source Framework Leveraged in Real-World Attacks (Unit 42)
- AdaptixC2 GitHub
- Adaptix Framework Docs
- Marshal.GetDelegateForFunctionPointer â Microsoft Docs
- VirtualProtect â Microsoft Docs
- Memory protection constants â Microsoft Docs
- Invoke-RestMethod â PowerShell
- MITRE ATT&CK T1547.001 â Registry Run Keys/Startup Folder
tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :
HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
HackTricks