Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
SecretsStalker — Schreibgeschützte Bewertung von Entra-ID-App-Anmeldeinformationen: ermittelt Graph-Berechtigungen, Azure RBAC und erreichbare Cloud-Daten und ordnet die Ergebnisse anschließend Pfaden zur Privilegieneskalation und Lateral Movement zu. | Kitploit
Tools/GitHubGitHub/rootsecdev/secretsstalker
Authentifizierung & AutorisierungCloud-Infrastruktur-SicherheitPrivilege EscalationAufklärungLaterale BewegungPost-ExploitationPenetrationstestsCloud-SicherheitIdentitäts- & Zugriffsmanagement (IAM)Red Teaming
GitHub
1811vor 1 MonatNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
rootsecdev/secretsstalker

SecretsStalker

Schreibgeschützte Bewertung von Entra-ID-App-Anmeldeinformationen: ermittelt Graph-Berechtigungen, Azure RBAC und erreichbare Cloud-Daten und ordnet die Ergebnisse anschließend Pfaden zur Privilegieneskalation und Lateral Movement zu.

Repository anzeigen

secret_stalker```


/ / ______ ___ ___ / /_ / / / /__ _ / / /_____ ____ \ / -) / -) -)/ / \ \ / __/ _ `// / '/ -) / //_/_/_/_/ _/ // _/_,////_\__/_/

root@kitploit:~
     ╔╦╦╬╬╬╬╬╬╦╦╗
 ╔╬╬╬╝╝┘      ╚╝╝╬╬╬┐
╬╬╝╚╩╬╗╔          ╚╬╬╬

╬╝ ╚╬╬╗╗ ╔ ╚╬╗ ╬╬ ╔╗ ╚╬╬╬╬╬╬╦ ╬╬ 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. \

root@kitploit:~
**Was kann diese Entra-ID-Client-ID + dieses Secret tatsächlich tun?**

Du hast eine Anwendungsanmeldeinformation von Entra ID (Azure AD) gefunden – eine Client-ID und ein Secret – bei einem autorisierten Engagement, und der Mandant, zu dem sie gehört, ist im Scope. `secret_stalker` nimmt diese beiden Werte und sagt dir, ganz ohne Vorwissen:

1. **Ist es gültig, und wann läuft das Secret ab?** – und falls nicht gültig, *warum* (falsches Secret, abgelaufenes Secret, App nicht im Mandant …). Bei einem gültigen Secret liest es die `passwordCredentials` der App-Registrierung und meldet das Ablaufdatum + verbleibende Tage (erfordert Verzeichnis-Leserechte; siehe Hinweis unten).
2. **Welche Microsoft-Graph-Rechte besitzt es?** – Anwendungsberechtigungen, die direkt aus dem ausgestellten Token gelesen werden, plus **Entra-Verzeichnisrollen**, die es innehat (auch passiv aus dem `wids`-Anspruch des Tokens erkannt) und **Objekte, die es besitzt** (Apps/SPs, zu denen du Anmeldeinformationen hinzufügen kannst).
3. **Welche Kontrolle hat es über Azure?** – RBAC-Rollenzuweisungen auf Verwaltungsgruppen- und Abonnement-Ebene.
4. **Kann es an echte Daten gelangen?** – optionale Erreichbarkeitsprüfungen für Key Vault (Geheimnisse / Schlüssel / Zertifikate), Storage (Blob / File / Queue / Table) und die Cosmos-DB-Datenebene.
5. **Wie groß ist die Auswirkung?** – gefährliche Berechtigungen, Rollen, Besitz und erreichbare Daten, abgebildet auf bekannte Privesc-/Lateral-Movement-Primitiven, nach Schweregrad bewertet, mit konkreten **Angriffspfad**-Darstellungen.

Es authentifiziert sich entweder mit einem **Clientgeheimnis** oder einem **Zertifikat** (`--cert`) und funktioniert mit **kommerziellen und souveränen Clouds** (`--cloud`).

Es ist **standardmäßig passiv** und **ändert niemals etwas** – ausschließlich lesende Enumeration.

> ⚠️ **Nur für autorisierte Tests.** Führe es ausschließlich gegen Mandanten aus, die explizit im Scope eines Engagements liegen, für das du autorisiert bist.

---

## 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

Die einzige Laufzeitabhängigkeit ist requests. Tokens werden lokal dekodiert (base64 + JSON) — keine Signaturprüfung, keine Kryptobibliothek, kein Microsoft SDK. Die eine Ausnahme ist die Zertifikatsauthentifizierung (--cert), die das optionale Paket cryptography benötigt, um die JWT-Client-Assertion zu signieren. Erfordert Python 3.7+.

Nach pip install . kannst du es als secret_stalker … aufrufen, anstatt python -m secret_stalker … zu verwenden.


Schnellstart

Der schnellste Weg, um herauszufinden, was ein Credential kann:```bash python -m secret_stalker
--tenant contoso.onmicrosoft.com
--client-id 11111111-2222-3333-4444-555555555555
--secret ''

root@kitploit:~
`--tenant` akzeptiert entweder eine Tenant-GUID oder eine Domain — eine Domain wird automatisch über den öffentlichen OpenID-Konfigurationsendpunkt in ihre
Tenant-ID aufgelöst.

### Das Geheimnis aus der Shell-Historie heraushalten

Übergeben Sie Anmeldedaten über Umgebungsvariablen anstelle von Flags:```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

Jedes von --tenant / --client-id / --secret kann aus SS_TENANT / SS_CLIENT_ID / SS_SECRET stammen. Flags haben Vorrang vor der Umgebung.

Hierbei geht es nicht nur um die Shell-Historie: Ein argv-Wert ist für jeden lokalen Benutzer während der gesamten Lebensdauer des Prozesses lesbar (ps, /proc/<pid>/cmdline). Wenn --secret oder --cert-password als Flag übergeben wird, gibt das Tool eine einzeilige Erinnerung auf stderr aus — es erscheint nie in der --json- oder --export-Ausgabe.

Mit einem Zertifikat statt eines Geheimnisses authentifizieren

App-Registrierungen verwenden oft ein Zertifikat statt eines Geheimnisses. Übergeben Sie --cert (ein PEM, das den privaten Schlüssel und das Zertifikat enthält, oder eine .pfx/.p12) und das Tool authentifiziert sich mit einer signierten JWT-Client-Assertion:```bash python -m secret_stalker --tenant contoso.onmicrosoft.com
--client-id --cert ./app.pem # or app.pfx

encrypted key / PFX:

python -m secret_stalker ... --cert app.pfx --cert-password ''

root@kitploit:~
Die Zertifikatsauthentifizierung benötigt das optionale Paket `cryptography` (`pip install '.[cert]'`).
Das Tool meldet das eigene Ablaufdatum des Zertifikats (abgeglichen anhand seines Fingerabdrucks in den
`keyCredentials` der App), genau wie bei einem Geheimnis. `--cert`/`--cert-password`
werden ebenfalls aus `SS_CERT` / `SS_CERT_PASSWORD` gelesen.

### Souveräne und Regierungs-Clouds

Standardmäßig zielt secret_stalker auf die **kommerzielle** Cloud. Für souveräne Mandanten
übergeben Sie `--cloud` (oder `SS_CLOUD`), damit die Entra-Autorität und die Graph-/ARM-/Key-
Vault-Endpunkte übereinstimmen — andernfalls sehen gültige Anmeldeinformationen so aus, als hätten sie keinen Zugriff:```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 ...

Aliase wie gov, dod, commercial, gcc-high und 21vianet werden akzeptiert. (Die Storage-Datenebenen-Zielgruppe, storage.azure.com, ist in jeder Cloud dieselbe.)


Empfohlener Workflow bei einem Engagement

  1. Aktualisieren Sie die Berechtigungszuordnung für diesen Mandanten (einmalig). Löst Graph-Berechtigungs-GUIDs in autoritative Namen für den Zielmandanten auf: ```bash python -m secret_stalker --update-manifest
    root@kitploit:~

Dies authentifiziert sich, speichert das Graph-appRole-Mapping des Mandanten in ~/.secret_stalker/app_roles_cache.json zwischen und beendet sich. Überspringen Sie es, wenn die Anmeldeinformation keine Dienstprinzipale lesen kann — das mitgelieferte Mapping deckt weiterhin die bekannten Berechtigungen ab.

  1. Passive Baseline. Gültigkeit, Graph-Berechtigungen und Azure-RBAC prüfen, ohne Mandantenobjekte zu berühren: ```bash python -m secret_stalker
    root@kitploit:~
  2. Aktiv werden, wenn Sie Tiefe + einen Bericht zum Aufbewahren möchten. Fügt schreibgeschützte Graph- Objektbeispiele und die Erreichbarkeit der Key Vault / Storage-Datenebene hinzu und schreibt einen abgeflachten Export für Triage oder Ingestion: ```bash python -m secret_stalker --active --export results.ndjson
    root@kitploit:~

Ausgabe lesen

Der Terminalbericht ist von oben nach unten organisiert – von „Funktioniert es?“ bis „Wie groß ist der Schaden?“. Ein typischer Lauf sieht so aus:``` secret_stalker — credential assessment

Credential status : VALID Tenant : aaaaaaaa-... Client (app) id : 1111... App display name : Recon App SP object id : cccc... Secret : valid — expires 2027-03-01 (in 207 days)

Token acquisition

OK graph OK arm NO storage — no storage token

Microsoft Graph application permissions (from token)

  • Application.ReadWrite.All
  • Mail.Read

...

Findings — escalation / control

[CRITICAL] (GRAPH) Application.ReadWrite.All Can add credentials to any app/SP and impersonate it — tenant-wide pivot. [CRITICAL] (ARM) Owner Full control including granting access to others. [CRITICAL] (DATA) keyvault:secrets Can read Key Vault secret values — connection strings, passwords, tokens. [MEDIUM] (GRAPH) Mail.Read Read all mailboxes — data exposure.

Overall risk: CRITICAL

root@kitploit:~
- **Token acquisition** listet jedes geprüfte Ziel auf (Graph, ARM und – bei
  `--active`, wenn passende Ressourcen gefunden werden – Key Vault / Storage /
  Cosmos DB). Graph und ARM sind *unabhängig*: Eine Anmeldedaten können das eine,
  aber nicht das andere besitzen.
- **Secret** zeigt die Gültigkeit und, bei einem gültigen Secret, das Ablaufdatum
  und die verbleibenden Tage (nahendes Ablaufdatum wird hervorgehoben). Siehe den
  Hinweis unten zu abgelaufenen Secrets.
- **Findings** ist der Teil, den man zuerst lesen sollte – Graph-Berechtigungen mit
  hoher Wirkung (`GRAPH`), ARM-Rollen (`ARM`), Entra-Verzeichnisrollen (`ROLE`),
  eigene Apps/SPs (`OWN`), erreichbare Data-Plane-Oberflächen (`DATA`) und
  angeforderte, aber nicht genehmigte Consent-Attack-Ziele (`WANT`) –
  dedupliziert und nach Schweregrad bewertet. Jedes Key-Vault-Secret lesen zu
  können oder eine Verzeichnisrolle zu besitzen, ist für sich genommen bereits
  ein Finding, selbst ohne gefährliche Graph/ARM-Zuweisung.
- **Attack paths** verwandelt die wichtigsten Findings in konkrete nächste
  Schritte (z. B. *Privileged Role Administrator → Global Administrator sich
  selbst zuweisen → Tenant-Übernahme*).
- **Active Graph enumeration** (`--active`) berichtet, was jede Nur-Lese-Sonde
  zurückgegeben hat. Die meisten Sonden fordern eine kleine, begrenzte Seite an,
  sodass eine gefüllte Seite als `N+` angezeigt wird (z. B. `users accessible
  (returned 5+)`) – also *mindestens* fünf, nicht genau fünf. Sonden ohne Limit
  (`organization`, `directoryRoles`) melden eine echte Gesamtzahl ohne `+`.
- **Directory roles / Owned objects / Delegated permissions** erhalten eigene
  Abschnitte. Verzeichnisrollen werden aus dem `wids`-Anspruch des Tokens erkannt,
  sogar ohne Verzeichnisleseberechtigung; delegierte Berechtigungen sind für eine
  App-only-Anmeldedaten nicht nutzbar, werden aber für User-Context-Pivots und
  Consent-Attack-Ausrichtung angezeigt.
- **Overall risk** ist der Schweregrad des schwerwiegendsten einzelnen Findings.

> **Secret-Ablauf – was bekannt ist.** Das Ablaufdatum ist *nicht* im Token; es
> liegt in den `passwordCredentials` der App-Registrierung in Entra ID. Bei einem
> **gültigen** Secret liest secret_stalker es über Graph und gleicht Ihr Secret
> mit der richtigen Anmeldedaten über deren `hint` (erste 3 Zeichen) ab – das
> erfordert Verzeichnisleseberechtigung (`Application.Read.All` /
> `Directory.Read.All`); wenn der SP diese nicht besitzt, wird das Datum als
> nicht verfügbar gemeldet, statt geraten. Bei einem **abgelaufenen** Secret
> schlägt die Authentifizierung selbst fehl, sodass die tote Anmeldedaten ihre
> eigenen Metadaten nicht lesen kann – das Tool kennzeichnet sie als
> `EXPIRED (AADSTS7000222)`, aber das genaue Enddatum ist über diese Anmeldedaten
> allein nicht abrufbar.

### Exit codes

Nützlich für Skripting:

| Code | Bedeutung |
|------|-----------|
| `0`  | Anmeldedaten sind gültig (mindestens ein Token erhalten). |
| `2`  | Anmeldedaten sind ungültig / haben keinen Zugriff. |
| `1`  | Fehler – Tenant konnte nicht aufgelöst werden, Zertifikat konnte nicht geladen werden oder die `--export`-Datei konnte nicht geschrieben werden. |

---

## Alle Flags

| Flag | Wirkung |
|------|---------|
| `--tenant` | Tenant-GUID oder Domain. (oder `SS_TENANT`) |
| `--cloud` | Azure-Cloud: `public` (Standard), `usgov` (GCC High), `usdod` (DoD), `china` (21Vianet). Wählt die Entra-Autorität sowie die Graph/ARM/Key-Vault-Endpunkte. Aliase wie `gov`/`dod`/`commercial` werden akzeptiert. (oder `SS_CLOUD`) |
| `--client-id` | Anwendungs-ID (Client ID). (oder `SS_CLIENT_ID`) |
| `--secret` | Client-Secret. Bevorzugen Sie `SS_SECRET`, um es aus dem Verlauf herauszuhalten. |
| `--cert` | Zertifikat für JWT-Assertion-Authentifizierung statt eines Secrets: eine PEM (Schlüssel+Zertifikat) oder `.pfx`/`.p12`. Benötigt `cryptography`. (oder `SS_CERT`) |
| `--cert-password` | Passwort für einen verschlüsselten `--cert`-Schlüssel/PFX. (oder `SS_CERT_PASSWORD`) |
| `--active` | Opt-in Nur-Lese-Enumeration: Graph-Objekt-Stichproben **plus** Key-Vault-/Storage-Data-Plane-Erreichbarkeit. Standardmäßig aus, um leise zu bleiben. |
| `--deep` | Mit `--active`: eine Ebene tiefer in erreichbaren Storage absteigen – Blobs in zugänglichen Containern und Dateien in zugänglichen Shares auflisten (nur Namen, begrenzt). Lauter. |
| `--no-arm` | Management-Group-/Subscription-/RBAC-Enumeration überspringen (nur Graph). |
| `--workers N` | Parallele HTTP-Worker für ARM-Scope-Lookups und Data-Plane-Sonden (Standard 8; `1` = sequenziell). |
| `--update-manifest` | Die maßgebliche appRole-GUID→Name-Zuordnung vom Live-Tenant abrufen (Graph **plus** alle anderen Ressourcen-APIs, denen diese Anmeldedaten zugewiesen sind), zwischenspeichern und dann beenden. |
| `--json` | Das vollständige verschachtelte Ergebnis als JSON statt des Berichts ausgeben. |
| `--export PATH` | Ergebnisse in eine Datei schreiben. Format wird aus der Erweiterung abgeleitet (`.csv` / `.ndjson` / `.jsonl` / `.json` / `.html`). Dateien werden nur für den Besitzer schreibbar erstellt (`0600`). |
| `--export-format` | Exportformat erzwingen (`ndjson` / `csv` / `json` / `html`). |
| `--timeout N` | Timeout pro Anfrage in Sekunden (Standard 20). ARM-Control-Plane-Anfragen (RBAC-Enumeration + Resource-Graph-Erkennung) verwenden ein längeres Timeout – `1,5×`, mindestens 30 s – da sie langsamer laufen. |
| `--verbose`, `-v` | Jede Graph/ARM/Data-Plane-HTTP-Anfrage (Methode, URL, Status) auf stderr aufzeichnen. |
| `--no-banner` | Das ASCII-Banner unterdrücken. |
| `--version` | Version ausgeben und beenden. |

---

## Ergebnisse exportieren

`--export` flacht das Ergebnis zu **einem Datensatz pro entdecktem Element** ab –
Anmeldedaten, Token, Graph-Berechtigung, App-Rollen-Zuweisung, ARM-Rolle,
Data-Plane-Treffer und bewertetes Finding – jeweils mit dem
Anmeldedaten-Kontext, sodass eine Zeile für sich allein steht.```bash
# NDJSON — stream into a SIEM / log pipeline
python -m secret_stalker --export results.ndjson

# CSV — open in a spreadsheet for triage
python -m secret_stalker --active --export results.csv

# Full nested JSON to a file
python -m secret_stalker --export results.json

Jeder Datensatz trägt einen record_type (credential, secret, token, graph_permission, app_role_assignment, directory_role, owned_object, arm_role, dataplane, delegated_permission, requested_permission, finding), sodass ein Konsument gezielt nach dem filtern kann, was er benötigt — zum Beispiel nur die bewerteten Treffer:```bash jq 'select(.record_type=="finding")' results.ndjson

root@kitploit:~
Der Terminalbericht und `--export` arbeiten zusammen — der Export unterdrückt nicht den Bericht (die „Exported …“-Bestätigung geht an stderr, sodass die Weiterleitung per `--json` sauber bleibt).

Exportdateien enthalten Kontext der Anmeldeinformationen (Token-Claims, der geheime `hint`, Schlüssel-IDs), daher werden sie **nur für den Besitzer (`0600`)** geschrieben, um ein Auslaufen auf einem gemeinsam genutzten oder synchronisierten Host zu vermeiden. Behandle sie als sensible Artefakte des Auftrags. Das Schreiben über einen Symlink wird grundsätzlich verweigert, sodass ein Exportpfad nicht umgeleitet werden kann, um etwas anderes zu kürzen.

Namen in einem Ergebnis stammen vom geprüften Mandanten — Anzeigenamen von Apps und Gruppen, Container- und Blob-Namen — und werden daher als nicht vertrauenswürdige Ausgabe behandelt:

- **CSV**-Werte, die als Formel gelesen würden (Beginn mit `=`, `+`, `-`, `@`), werden mit einem einfachen Anführungszeichen versehen, sodass ein Anzeigename wie `=cmd|' /C calc'!A0` nicht ausgeführt werden kann, wenn die Datei in einer Tabellenkalkulation geöffnet wird. Tabellenkalkulationen entfernen das Anführungszeichen bei der Anzeige.
- **Terminal-, CSV- und HTML**-Ausgabe: Steuerzeichen werden entfernt, sodass ein Name, der ANSI-Escape-Sequenzen enthält, dein Terminal nicht umbenennen oder die darüberliegenden Ergebnisse überschreiben kann — ob du den Bericht live liest, die CSV per `cat` anzeigst oder das HTML per `cat`.
- **JSON / NDJSON bleiben originalgetreu**: `json.dumps` kodiert Steuerzeichen als `\uXXXX`, was als Text inert ist, während ein Parser den genauen Wert, den der Mandant zurückgegeben hat, weiterhin korrekt zurückkonvertiert. Der rohe Name ist Beweismaterial und wird daher dort beibehalten.

---

## Wie Berechtigungs-GUIDs aufgelöst werden

`appRoleAssignments` werden als GUIDs zurückgegeben. secret_stalker löst sie über eine flache Suche zu Namen auf (appRole-GUIDs sind global eindeutig), was **auch dann funktioniert, wenn Verzeichniszugriffe verweigert werden**:

- Eine Best-Effort-Zuordnung bekannter Graph-Berechtigungen wird in `secret_stalker/data/graph_app_roles.json` ausgeliefert.
- `--update-manifest` überschreibt sie mit maßgeblichen Daten, die live vom Mandanten im Geltungsbereich abgerufen werden — Microsoft Graph **plus jede andere Ressourcen-API, auf der diese Anmeldeinformation zugewiesen ist** (z. B. Exchange Online, SharePoint), sodass auch Nicht-Graph-GUIDs aufgelöst werden.
- Eine unbekannte GUID wird **roh und markiert** angezeigt — das Tool errät niemals einen Namen.

---

## So funktioniert es (die Kurzfassung)

- **Gültigkeit + Berechtigungen in einer Anfrage.** Der `roles`-Anspruch eines erfolgreichen Graph-Tokens *ist* die Liste der gewährten Anwendungsberechtigungen. secret_stalker liest sie aus dem dekodierten Token — schnell und leise, keine Graph-Aufrufe nötig.
- **Graph ≠ ARM.** Es handelt sich um verschiedene Token-Audiences. Eine Anmeldeinformation kann Rechte auf der einen, aber nicht auf der anderen besitzen, daher wird jede unabhängig geprüft.
- **Datenebene ≠ Verwaltungsebene.** ARM-Rechte an einem Key Vault (Verwaltung) sind nicht dasselbe wie die Fähigkeit, seine Geheimnisse (Datenebene) zu lesen. Unter `--active` wird die Erreichbarkeit der Datenebene mit der eigenen Token-Audience der Ressource getestet — und es listet **nur Objektnamen**, niemals Werte oder Inhalte.
- **Datenebenen-Prüfung pro Oberfläche.** Die Datenebenen-RBAC wird pro Objekttyp/Dienst gewährt, daher wird jede unabhängig geprüft: Key Vault **Geheimnisse / Schlüssel / Zertifikate**, Storage **Blob / Datei / Warteschlange / Tabelle** und Cosmos DB **Datenbanken**. Eine Anmeldeinformation, die `Storage File Data SMB Share Reader`, aber kein Blob-Leser ist, wird aufgedeckt, nicht übersehen. (Cosmos verwendet einen nicht standardkonformen AAD-REST-Header und ist **Best-Effort** — validiere ein `denied`-Ergebnis gegen ein Live-Konto.)
- **Mandantenweite Ermittlung.** Ressourcen werden mit einem einzelnen Azure-Resource-Graph-Durchlauf über jedes Abonnement, das der Prinzipal sehen kann (unter Beachtung von RBAC), gefunden; falls ARG verweigert wird, erfolgt ein Rückgriff auf die Auflistung pro Abonnement. Der Bericht kennzeichnet, welcher Pfad verwendet wurde (`[discovery: resource-graph]` vs. `per-subscription`). Der Durchlauf paginiert Ergebnisse bis zu einer Grenze (40 Seiten × 1000 Zeilen pro Ressourcentyp), sodass ein Lauf immer terminiert; `--verbose` erwähnt es, falls die Grenze jemals erreicht wird.
- **Die Schweregrad-Zuordnung** befindet sich in `secret_stalker/risk.py` — bearbeite sie, um anzupassen, was dein Team als schwerwiegend einstuft.

---

## Projektstruktur```
secret_stalker/
  clouds.py      Azure cloud endpoint table (public / usgov / usdod / china)
  auth.py        client_credentials flow + tenant discovery + AADSTS decoding
  jwt_utils.py   local JWT claim extraction
  manifest.py    Graph appRole GUID -> name resolution (bundled + live cache)
  graph.py       service principal lookup + appRole resolution + active probes
  arm.py         management-group / subscription RBAC + resource discovery
  dataplane.py   Key Vault / Storage data-plane reachability probes
  risk.py        permission/role/data-plane -> impact mapping (tune this)
  report.py      terminal + JSON output
  export.py      flatten to NDJSON / CSV / JSON records for ingestion
  util.py        shared HTTP (retry/backoff + safe JSON), pmap parallel map,
                 untrusted-output sanitizing
  banner.py      ASCII banner (stderr only)
  cli.py         orchestration
  data/graph_app_roles.json   bundled permission manifest
tests/           pytest suite (run: pytest)
pyproject.toml   packaging + `secret_stalker` console entry point

Implementierte Highlights

  • Authentifizierung per Secret oder Zertifikat (--cert) — JWT-Client-Assertion (RS256) aus einer PEM- oder PFX-Datei, mit Bericht zum Zertifikatsablauf. auth.py
  • Entra-Verzeichnisrollen, die der Prinzipal innehat — einschließlich passiver Erkennung anhand des wids-Anspruchs im Token (kein Verzeichnislesen erforderlich) — nach Rolle bewertet. graph.py / risk.py
  • Eigene Objekte — apps/SPs, die der Prinzipal besitzt (ein Pivot zum Hinzufügen von Anmeldeinformationen). graph.py
  • Sichtbarkeit delegierter Berechtigungen (--active) — zugestimmte Berechtigungen + angeforderte Berechtigungen, wobei nicht zugestimmte gefährliche Berechtigungen als Ziele für Consent-Angriffe markiert werden. graph.py / risk.py
  • Angriffspfad-Beschreibungen + HTML-Bericht (--export report.html). risk.py /

Roadmap-Ideen

  • Lesen der Attribute von Key-Vault-Schlüsseln/-Zertifikaten (aktiviert/ablaufend) für die Sichtung — weiterhin nur Metadaten, kein Schlüsselmaterial.
  • Ein Blick in Storage-Warteschlangen-/Tabelleninhalte würde bedeuten, Daten zu lesen, daher ist es für dieses reine Lesetool bewusst außerhalb des Anwendungsbereichs.
Tool herunterladen
--cloudEntra authorityMicrosoft GraphARMKey Vault
public (default)login.microsoftonline.comgraph.microsoft.commanagement.azure.comvault.azure.net
usgov (GCC High)login.microsoftonline.usgraph.microsoft.usmanagement.usgovcloudapi.netvault.usgovcloudapi.net
usdod (DoD)login.microsoftonline.usdod-graph.microsoft.usmanagement.usgovcloudapi.netvault.usgovcloudapi.net
china (21Vianet)login.chinacloudapi.cnmicrosoftgraph.chinacloudapi.cnmanagement.chinacloudapi.cnvault.azure.cn
report.py
  • Kommerzielle + souveräne Clouds (--cloud) — öffentlich, US Gov (GCC High), US DoD, und China (21Vianet), jeweils mit der korrekten Entra-Autorität und den Graph-/ARM-/Key Vault-Audienzen. clouds.py
  • Mandantenweite Ressourcenermittlung über einen einzigen Durchlauf des Azure Resource Graph (RBAC-respektierend), mit Fallback pro Abonnement und Wiederherstellung von Verwaltungsgruppen-Nachfahren für Abonnements, die die flache Liste auslässt. arm.py
  • Volle Data-Plane-Abdeckung — Key-Vault-Geheimnisse / -Schlüssel / -Zertifikate sowie Storage-Blob / -Datei / -Warteschlange / -Tabelle und Cosmos-DB-Datenbanken, jeweils unabhängig geprüft und in die bewerteten Ergebnisse einbezogen (erreichbare Daten sind ein Befund, nicht nur Metadaten). dataplane.py / risk.py
  • Genaue Zählungen — Data-Plane-Listings folgen Fortsetzungstokens (begrenzt), sodass eine Oberflächenanzahl die echte Gesamtzahl widerspiegelt; ein + (z. B. 25+) markiert, wo die Auflistung begrenzt wurde, anstatt stillschweigend zu wenig zu melden. dataplane.py
  • Drosselungsresistente Anfragen — ein gemeinsamer HTTP-Pfad wiederholt 429/503 unter Beachtung von Retry-After, sodass vorübergehende Drosselung nicht als "verweigert / kein Zugriff." fehlinterpretiert wird. util.py
  • Tiefer Storage-Abstieg (--deep) — listet Blobs in erreichbaren Containern und Dateien in erreichbaren Freigaben, nur Namen und begrenzt. dataplane.py
  • Nicht-Graph-GUID-Auflösung — --update-manifest speichert appRoles für jede Ressourcen-API, auf der der Prinzipal zugewiesen ist, nicht nur Graph. graph.py / manifest.py
  • Parallelität (--workers N) über ARM-Scope-Abfragen und Data-Plane-Prüfungen, mit Fehlerisolierung pro Element. util.py