Magasin de jetons¶
Le magasin de jetons assure une gestion persistante des jetons sur tous les commutateurs d'usurpation d'identité. Les jetons volés dans les processus ou créés avec des informations d'identification sont stockés sous forme de doublons indépendants qui survivent à rev2self. Les opérateurs peuvent répertorier, basculer entre et supprimer les jetons stockés sans les voler à nouveau.
Cela correspond au comportement du magasin de jetons Cobalt Strike v4.12.
ATTAQUE À ONGLET&CK
La manipulation de jeton correspond à T1134.001 - Manipulation de jeton d'accès : usurpation d'identité/vol de jeton et T1134.002 - Créer un processus avec un jeton.
Commandes du magasin de jetons¶
| Commande | Syntaxe | Description | ONGLET |
|---|---|---|---|
token_store_steal | token_store_steal <pid> | Voler, usurper l'identité et stocker un jeton de manière atomique | T1134.001 |
token_store_show | token_store_show | Lister tous les jetons stockés | -- |
token_store_use | token_store_use <id> | Passer à un jeton stocké par ID | T1134.001 |
token_store_remove | token_store_remove <id> | Supprimer un jeton du magasin | -- |
token_store_remove_all | token_store_remove_all | Effacer tout le magasin de jetons | -- |
Commandes de base des jetons¶
| Commande | Syntaxe | Description | ONGLET |
|---|---|---|---|
steal_token | steal_token <pid> | Voler et usurper l'identité (non stocké) | T1134.001 |
make_token | make_token <DOMAIN\user> <password> | Créer un jeton de connexion réseau | T1134.002 |
rev2self | rev2self | Revenir à l'identité d'origine | -- |
getuid | getuid | Interroger l'identité actuelle | -- |
getprivs | getprivs | Activer tous les privilèges disponibles | -- |
Flux de travail du magasin de jetons¶
sequenceDiagram
participant Op as Operator
participant BC as Beacon
participant TM as Token Manager
Op->>BC: token_store_steal 1234
BC->>TM: OpenProcess(1234) → DuplicateToken
TM->>TM: Store token (ID=1)
TM->>TM: Impersonate DOMAIN\DomainAdmin
BC-->>Op: [+] Impersonating DOMAIN\DomainAdmin (stored ID=1)
Op->>BC: token_store_steal 5678
TM->>TM: Store token (ID=2)
TM->>TM: Impersonate DOMAIN\svc_sql
BC-->>Op: [+] Impersonating DOMAIN\svc_sql (stored ID=2)
Op->>BC: token_store_use 1
TM->>TM: Switch to stored ID=1
BC-->>Op: [+] Switched to DOMAIN\DomainAdmin
Op->>BC: rev2self
TM->>TM: Revert (tokens still in store)
BC-->>Op: [*] Reverted to original identity
Op->>BC: token_store_use 2
TM->>TM: Re-impersonate ID=2
BC-->>Op: [+] Switched to DOMAIN\svc_sql Référence des commandes¶
token_store_steal <pid>¶
Volez atomiquement un jeton à un processus, usurpez-le et stockez-le dans le magasin de jetons. Il s’agit d’une seule opération aller-retour (et non de deux tâches distinctes).
Syntaxe du shell :
Exemple d'API :
# Via REST endpoint
curl -s -X POST "https://stentor.app/api/v1/c2/beacons/$BEACON_ID/token/steal" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"pid": 1234}'
Scripts CNA :
token_store_show¶
Répertoriez tous les jetons actuellement dans le magasin avec leurs métadonnées.
Syntaxe du shell :
Exemple d'API :
curl -s "https://stentor.app/api/v1/c2/beacons/$BEACON_ID/token/list" \
-H "Authorization: Bearer $TOKEN"
Exemple de résultat :
Token Store (3 entries):
ID Type PID Username SID
-- ---- --- -------- ---
1 stolen 1234 CORP\DomainAdmin S-1-5-21-...-512
2 stolen 5678 CORP\svc_sql S-1-5-21-...-1105
3 created -- CORP\jsmith (network) S-1-5-21-...-1103
Scripts CNA :
token_store_use <id>¶
Basculez vers un jeton précédemment stocké grâce à son identifiant de magasin.
Syntaxe du shell :
Exemple d'API :
curl -s -X POST "https://stentor.app/api/v1/c2/beacons/$BEACON_ID/token/use" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"store_id": 1}'
Scripts CNA :
token_store_remove <id>¶
Supprimez un jeton spécifique du magasin et fermez sa poignée.
Syntaxe du shell :
Scripts CNA :
token_store_remove_all¶
Effacez l’intégralité du magasin de jetons, en fermant tous les handles stockés.
Syntaxe du shell :
Scripts CNA :
Modèle d'identité¶
Le gestionnaire de jetons distingue deux types d'usurpation d'identité :
| Méthode | Identité locale | Identité du réseau | Cas d'utilisation |
|---|---|---|---|
steal_token | Changé | Changé | Usurpation d'identité complète (local + réseau) |
make_token | Inchangé | Changé | Identifiants réseau uniquement (WMI, SMB, WinRM) |
steal_tokenduplique un jeton de processus existant. Changement d'identité locale et réseau pour le propriétaire du jetonmake_tokencrée un jeton de connexion avecLogonUser(LOGON32_LOGON_NEW_CREDENTIALS). L'identité locale du beacon reste la même, mais les opérations réseau s'authentifient en tant qu'utilisateur spécifié
Magasin de jetons et commandes de base
Utilisez token_store_steal au lieu de steal_token lorsque vous envisagez de basculer entre plusieurs identités. Les jetons stockés survivent à rev2self et peuvent être réutilisés sans être volés à nouveau lors du processus d'origine.
Stockage automatique des jetons¶
Depuis la version 20.0, steal_token et make_token stockent automatiquement les jetons dans le coffre-fort de jetons aux côtés des commandes explicites token_store_*. Chaque opération de jeton enregistre des métadonnées pour le suivi opérationnel :
| Métadonnées | Description |
|---|---|
| Identifiant du magasin | Identifiant à incrémentation automatique du jeton |
| Source | stolen (à partir du processus) ou created (à partir des informations d'identification) |
| PID | ID du processus source (pour les jetons volés) |
| Niveau d'intégrité | Niveau d'intégrité du jeton (faible/moyen/élevé/système) via la vérification de la sous-autorité SID |
| Nom d'utilisateur | Identité du propriétaire du jeton (format DOMAINE\utilisateur) |
| Horodatage | Quand le jeton a été acquis |
| Actif | Si ce jeton est actuellement usurpé |
Les échecs de stockage automatique ne sont pas fatals : l'opération réussit et renvoie storeID=0 en cas d'échec du stockage. L'ID de magasin actif est suivi sur plusieurs plates-formes (défini dans tokenmanager.go).
Indicateur d'interface utilisateur
L'interface utilisateur de l'opérateur affiche un texte d'information lorsque steal_token ou make_token est utilisé, confirmant que le jeton a été automatiquement stocké. Utilisez token_store_show pour voir tous les jetons stockés avec leurs métadonnées, y compris les niveaux d'intégrité.
Points de terminaison de l'API REST¶
| Méthode | Point de terminaison | Description |
|---|---|---|
GET | /api/v1/c2/beacons/:id/token/list | Liste des jetons stockés |
POST | /api/v1/c2/beacons/:id/token/steal | Voler et stocker un jeton |
POST | /api/v1/c2/beacons/:id/token/make | Créer un jeton avec des informations d'identification |
POST | /api/v1/c2/beacons/:id/token/use | Passer au jeton stocké |
POST | /api/v1/c2/beacons/:id/token/revert | Revenir à l'identité d'origine |
POST | /api/v1/c2/beacons/:id/token/getprivs | Activer tous les privilèges |
Considérations OPSEC
steal_token/token_store_stealouvre un handle vers le processus cible (PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE) - génère l'ID d'événement Sysmon 10make_tokenappelleLogonUserqui génère l'ID d'événement 4624 (Type de connexion 9 - NewCredentials)- L'usurpation d'identité du jeton est locale au thread sous Windows ; le gestionnaire épingle la goroutine à un thread du système d'exploitation via
runtime.LockOSThread() - Les jetons stockés sont des doublons indépendants : ils restent valides même si le processus source se termine
- MITRE ATT&CK : T1134.001 (usurpation d'identité/vol de jeton), T1134.002 (créer un processus avec un jeton)