
Évaluation en lecture seule des informations d'identification d'applications Entra ID : énumère les autorisations Graph, l'Azure RBAC et les données cloud accessibles, puis mappe les résultats aux chemins d'élévation de privilèges et de mouvement latéral.
/ / ______ ___ ___ / /_ / / / /__ _ / / /_____ ____ \ / -) / -) -)/ / \ \ / __/ _ `// / '/ -) / //_/_/_/_/ _/ // _/_,////_\__/_/
╔╦╦╬╬╬╬╬╬╦╦╗
╔╬╬╬╝╝┘ ╚╝╝╬╬╬┐
╬╬╝╚╩╬╗╔ ╚╬╬╬
╬╝ ╚╬╬╗╗ ╔ ╚╬╗ ╬╬ ╔╗ ╚╬╬╬╬╬╬╦ ╬╬ we found your secret... ╔╬┤ ╬╬╬ ╬╬╬╬╬╬╬╬╝╝╝╬╬╗ ...now let's see what it ╬╬┤ ╚╩┘ ╚╬╬╬╬╬╩ ╠╬╬ can REALLY do. ( o_o)>=|= ╬╬┤ ╠╬╬ ╬╬ ╦╗ ╗╗ ╬╬ [ client_id + secret -> total recall ] └╬┐ ╚╬╗╗ ╔╬╬╝ ╔╬┘ └╬╗ ╚╩╩╬╬╬╩╩╝╝ ╔╬╬ ╚╬╬╬╗ ┌╗╬╬╝┘ ╚╩╬╬╬╦╦╦╦╦╦╬╬╬╝╝ ╚╚╝╝╝╝ // pst... that app registration talks too much. \
**Que peut réellement faire cet ID client + secret Entra ID ?**
Vous avez trouvé un identifiant d'application Entra ID (Azure AD) — un ID client et un secret —
lors d'un engagement autorisé, et le locataire auquel il appartient est dans le périmètre.
`secret_stalker` prend ces deux valeurs et vous indique, à froid :
1. **Est-il valide et quand le secret expire-t-il ?** — et s'il n'est pas valide, *pourquoi*
(mauvais secret, secret expiré, application absente du locataire…). Pour un secret valide, il
lit les `passwordCredentials` de l'inscription de l'application et rapporte la date d'expiration
+ les jours restants (nécessite une lecture de l'annuaire ; voir la note ci-dessous).
2. **Quels droits Microsoft Graph possède-t-il ?** — autorisations d'application lues
directement depuis le jeton émis, plus les **rôles d'annuaire Entra** qu'il détient (même
détectés passivement via la revendication `wids` du jeton) et les **objets qu'il possède**
(applications / principaux de service auxquels vous pouvez ajouter des informations d'identification).
3. **Quel contrôle a-t-il sur Azure ?** — attributions de rôles RBAC au niveau des
groupes de gestion et des abonnements.
4. **Peut-il atteindre des données réelles ?** — vérifications facultatives de l'accessibilité du plan de données
de Key Vault (secrets / clés / certificats), Storage (blob / fichier / file d'attente / table) et Cosmos DB.
5. **Quel est l'impact ?** — permissions dangereuses, rôles, propriété et données accessibles
mappés à des primitives connues d'élévation de privilèges / mouvement latéral, classés par sévérité,
avec des scénarios concrets de **chemin d'attaque**.
Il s'authentifie avec un **secret client** ou un **certificat** (`--cert`),
et fonctionne avec les **clouds commerciaux et souverains** (`--cloud`).
Il est **passif par défaut** et **ne modifie jamais rien** — énumération en lecture seule
uniquement.
> ⚠️ **Test autorisé uniquement.** Exécutez-le uniquement contre des locataires qui sont
> explicitement dans le périmètre d'un engagement que vous êtes autorisé à effectuer.
---
## Installation```bash
pip install -r requirements.txt # just runs it from source
# — or —
pip install . # installs the `secret_stalker` command
pip install '.[cert]' # + certificate (--cert) auth support
pip install '.[dev]' # + pytest for the test suite
La seule dépendance d’exécution est requests. Les jetons sont décodés localement (base64 +
JSON) — pas de vérification de signature, pas de bibliothèque cryptographique, pas de SDK Microsoft. La seule
exception est l’authentification par certificat (--cert), qui nécessite le paquet optionnel cryptography
pour signer l’assertion du client JWT. Nécessite Python 3.7+.
Après pip install ., vous pouvez l’invoquer comme secret_stalker … au lieu de
python -m secret_stalker ….
Le moyen le plus rapide de découvrir ce qu’un identifiant peut faire :```bash
python -m secret_stalker
--tenant contoso.onmicrosoft.com
--client-id 11111111-2222-3333-4444-555555555555
--secret ''
`--tenant` accepte soit un GUID de tenant, soit un domaine — un domaine est résolu automatiquement en son identifiant de tenant via le point de terminaison public de configuration OpenID.
### Gardez le secret hors de votre historique de shell
Transmettez les identifiants via des variables d'environnement plutôt que par des options :```bash
export SS_TENANT=contoso.onmicrosoft.com
export SS_CLIENT_ID=11111111-2222-3333-4444-555555555555
export SS_SECRET='<client-secret>'
python -m secret_stalker
Tout --tenant / --client-id / --secret peut provenir de SS_TENANT /
SS_CLIENT_ID / SS_SECRET. Les drapeaux ont priorité sur l’environnement.
Il ne s’agit pas uniquement de l’historique du shell : une valeur d’argv est lisible par tout
utilisateur local pendant toute la durée de vie du processus (ps, /proc/<pid>/cmdline). Si --secret
ou --cert-password est passé comme drapeau, l’outil affiche un rappel d’une ligne sur
stderr — il n’apparaît jamais dans la sortie --json ou --export.
Les inscriptions d’application utilisent souvent un certificat plutôt qu’un secret. Passez --cert
(un PEM contenant la clé privée et le certificat, ou un .pfx/.p12) et
l’outil s’authentifie avec une assertion client JWT signée :```bash
python -m secret_stalker --tenant contoso.onmicrosoft.com
--client-id --cert ./app.pem # or app.pfx
python -m secret_stalker ... --cert app.pfx --cert-password ''
L'authentification par certificat nécessite le paquet optionnel `cryptography` (`pip install '.[cert]'`).
L'outil signale l'expiration du certificat lui-même (correspondant à son empreinte dans `keyCredentials` de l'application), tout comme il le fait pour un secret. `--cert`/`--cert-password` sont également lus depuis `SS_CERT` / `SS_CERT_PASSWORD`.
### Clouds souverains et gouvernementaux
Par défaut, secret_stalker cible le cloud **commercial**. Pour les locataires souverains, passez `--cloud` (ou `SS_CLOUD`) afin que l'autorité Entra et les points de terminaison Graph / ARM / Key Vault correspondent — sinon des identifiants valides semblent ne donner aucun accès :```bash
# US Government (GCC High)
python -m secret_stalker --cloud usgov --tenant contoso.onmicrosoft.us ...
# US DoD (L5)
python -m secret_stalker --cloud usdod ...
# Azure operated by 21Vianet (China)
python -m secret_stalker --cloud china --tenant contoso.partner.onmschina.cn ...
--cloud | Autorité Entra | Microsoft Graph | ARM | Key Vault |
|---|---|---|---|---|
public (par défaut) | login.microsoftonline.com | graph.microsoft.com | management.azure.com | vault.azure.net |
usgov (GCC High) | login.microsoftonline.us | graph.microsoft.us | management.usgovcloudapi.net | vault.usgovcloudapi.net |
usdod (DoD) | login.microsoftonline.us | dod-graph.microsoft.us | management.usgovcloudapi.net | vault.usgovcloudapi.net |
china (21Vianet) | login.chinacloudapi.cn | microsoftgraph.chinacloudapi.cn | management.chinacloudapi.cn | vault.azure.cn |
Les alias comme gov, dod, commercial, gcc-high et 21vianet sont acceptés.
(L'audience du plan de données de Stockage, storage.azure.com, est la même dans tous les clouds.)
Cette étape authentifie, met en cache la carte des appRole Graph du locataire dans
~/.secret_stalker/app_roles_cache.json, puis se termine. Ignorez-la si
l'identifiant ne peut pas lire les service principals — la carte incluse couvre toujours les
autorisations bien connues.