Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/rootsecdev/secretsstalker
Autenticazione e AutorizzazioneSicurezza dell'Infrastruttura CloudEscalation di PrivilegiRicognizioneMovimento LateralePost-ExploitPenetration TestingSicurezza CloudGestione Identità e Accessi (IAM)Red Teaming
GitHub
18111 mese faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
rootsecdev/secretsstalker

SecretsStalker

Valutazione in sola lettura delle credenziali delle app di Entra ID: enumera le autorizzazioni di Graph, l'RBAC di Azure e i dati cloud raggiungibili, quindi mappa i risultati sui percorsi di privilege escalation e lateral movement.

Vedi Repository

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:~
**Cosa può realmente fare questo client ID + secret di Entra ID?**

Hai trovato una credenziale applicativa di Entra ID (Azure AD) — un client ID e un secret —
durante un impegno autorizzato, e il tenant a cui appartiene è in scope.
`secret_stalker` prende questi due valori e ti dice, a partire da zero:

1. **È valido e quando scade il secret?** — e se non è valido, *perché*
   (secret errato, secret scaduto, app non presente nel tenant…). Per un secret valido
   legge le `passwordCredentials` della registrazione dell'app e riporta la data
   di scadenza + i giorni rimanenti (richiede la lettura della directory; vedi nota sotto).
2. **Quali diritti Microsoft Graph porta con sé?** — autorizzazioni applicative lette
   direttamente dal token emesso, più **ruoli di directory Entra** che detiene (anche
   rilevati passivamente dalla dichiarazione `wids` del token) e **oggetti che possiede**
   (app/SP a cui puoi aggiungere credenziali).
3. **Che controllo ha su Azure?** — assegnazioni di ruolo RBAC a livello di
   gruppo di gestione e sottoscrizione.
4. **Può raggiungere dati reali?** — controlli opzionali di raggiungibilità del data-plane
   per Key Vault (segreti / chiavi / certificati), Storage (blob / file / coda / tabella)
   e Cosmos DB.
5. **Qual è l'impatto?** — permessi pericolosi, ruoli, proprietà e dati raggiungibili
   mappati su primitive note di privesc / movimento laterale, valutati per gravità,
   con narrazioni concrete di **attack-path**.

Si autentica con un **client secret** o un **certificato** (`--cert`),
e funziona con **cloud commerciali e sovrani** (`--cloud`).

È **passivo per impostazione predefinita** e **non modifica mai nulla** — solo
enumerazione in sola lettura.

> ⚠️ **Solo test autorizzati.** Eseguilo esclusivamente contro tenant che sono
> esplicitamente in scope per un impegno che sei autorizzato a svolgere.

---

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

L'unica dipendenza runtime è requests. I token vengono decodificati localmente (base64 + JSON) — nessuna verifica della firma, nessuna libreria crittografica, nessun SDK Microsoft. L'unica eccezione è l'autenticazione tramite certificato (--cert), che richiede il pacchetto opzionale cryptography per firmare l'asserzione client JWT. Richiede Python 3.7+.

Dopo pip install . puoi invocarlo come secret_stalker … invece di python -m secret_stalker ….


Avvio rapido

Il modo più veloce per scoprire cosa può fare una credenziale:```bash python -m secret_stalker
--tenant contoso.onmicrosoft.com
--client-id 11111111-2222-3333-4444-555555555555
--secret ''

root@kitploit:~
`--tenant` accetta un GUID tenant o un dominio — un dominio viene risolto automaticamente nel relativo ID tenant tramite l'endpoint pubblico di configurazione OpenID.

### Tieni il segreto fuori dalla cronologia della shell

Passa le credenziali tramite variabili d'ambiente invece che tramite flag:```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

Ognuno di --tenant / --client-id / --secret può provenire da SS_TENANT / SS_CLIENT_ID / SS_SECRET. I flag hanno precedenza sull'ambiente.

Non si tratta solo della cronologia della shell: un valore argv è leggibile da qualsiasi utente locale per l'intera durata del processo (ps, /proc/<pid>/cmdline). Se --secret o --cert-password viene passato come flag, lo strumento stampa un promemoria di una riga su stderr — non compare mai nell'output di --json o --export.

Autenticarsi con un certificato invece che con un segreto

Le registrazioni delle app spesso usano un certificato anziché un segreto. Passa --cert (un PEM contenente la chiave privata e il certificato, o un .pfx/.p12) e lo strumento si autentica con un'asserzione client JWT firmata:```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:~
L'autenticazione tramite certificato richiede il pacchetto opzionale `cryptography` (`pip install '.[cert]'`).
Lo strumento riporta la scadenza del certificato stesso (identificata in base al relativo thumbprint presente in
`keyCredentials` dell'app), esattamente come fa per un segreto. `--cert`/`--cert-password`
vengono letti anche da `SS_CERT` / `SS_CERT_PASSWORD`.

### Cloud sovrani e governativi

Per impostazione predefinita secret_stalker si rivolge al cloud **commerciale**. Per i tenant sovrani,
passa `--cloud` (o `SS_CLOUD`) affinché l'autorità Entra e gli endpoint Graph / ARM / Key
Vault corrispondano — altrimenti credenziali valide sembrano non avere accesso:```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 ...

Sono accettati alias come gov, dod, commercial, gcc-high e 21vianet. (L'audience del data-plane di Storage, storage.azure.com, è la stessa in ogni cloud.)


Flusso di lavoro consigliato in un engagement

  1. Aggiorna la mappa delle autorizzazioni per questo tenant (una volta). Risolve i GUID delle autorizzazioni Graph in nomi autoritativi per il tenant di destinazione: ```bash python -m secret_stalker --update-manifest
    root@kitploit:~

Questo autentica, memorizza nella cache la mappa delle appRole Graph del tenant in ~/.secret_stalker/app_roles_cache.json, e esce. Salta questo passaggio se le credenziali non possono leggere i service principal — la mappa inclusa copre comunque le autorizzazioni note.

  1. Baseline passiva. Verifica la validità, le autorizzazioni Graph e l'RBAC di Azure senza toccare gli oggetti del tenant: ```bash python -m secret_stalker
    root@kitploit:~
  2. Attiva quando vuoi profondità + un report da conservare. Aggiunge campioni di oggetti Graph in sola lettura e raggiungibilità data-plane di Key Vault / Storage, e scrive un'esportazione appiattita per triage o ingestione: ```bash python -m secret_stalker --active --export results.ndjson
    root@kitploit:~

Lettura dell'output

Il report del terminale è organizzato dall'alto verso il basso, da "funziona?" a "qual è il danno." Una tipica esecuzione si presenta così:``` 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** elenca ogni audience sondato (Graph, ARM e — con
  `--active`, quando vengono scoperte risorse corrispondenti — Key Vault / Storage /
  Cosmos DB). Graph e ARM sono *indipendenti*: una credenziale può avere l'uno senza
  l'altro.
- **Secret** mostra la validità e, per un secret valido, la data di scadenza e i giorni
  rimanenti (la vicinanza alla scadenza è evidenziata). Vedi la nota sotto sui secret scaduti.
- **Findings** è la sezione da leggere per prima — permessi Graph ad alto impatto (`GRAPH`),
  ruoli ARM (`ARM`), ruoli di directory Entra (`ROLE`), app/SP posseduti (`OWN`),
  superfici data-plane raggiungibili (`DATA`) e obiettivi di attacco di consenso
  richiesti ma non autorizzati (`WANT`) — deduplicati e classificati per gravità. Poter
  leggere ogni secret di Key Vault, o detenere un ruolo di directory, è di per sé un finding
  anche senza concessioni Graph/ARM pericolose.
- **Percorsi di attacco** trasforma i finding principali in passi successivi concreti (es. *Privileged
  Role Administrator → assegnare Global Administrator a sé stessi → tenant takeover*).
- **Enumerazione Graph attiva** (`--active`) riporta ciò che ogni sonda di sola lettura ha
  restituito. La maggior parte delle sonde richiede una piccola pagina con limite, quindi una
  pagina piena viene mostrata come `N+` (es. `users  accessible  (returned 5+)`) — ovvero
  *almeno* cinque, non esattamente cinque. Le sonde senza limite (`organization`,
  `directoryRoles`) riportano un totale reale senza `+`.
- **Ruoli di directory / Oggetti posseduti / Permessi delegati** hanno sezioni dedicate.
  I ruoli di directory vengono rilevati dal claim `wids` del token anche senza lettura della
  directory; i permessi delegati non sono utilizzabili da una credenziale solo-app ma vengono
  mostrati per pivot nel contesto utente e per il targeting di attacchi di consenso.
- **Rischio complessivo** è la gravità del singolo finding di livello più alto.

> **Scadenza del secret — cosa è conoscibile.** La data di scadenza *non* è nel token;
> risiede nei `passwordCredentials` della registrazione dell'app in Entra ID. Per un
> secret **valido**, secret_stalker la legge tramite Graph e abbina il tuo secret alla
> credenziale giusta tramite il suo `hint` (primi 3 caratteri) — questo richiede la lettura
> della directory (`Application.Read.All` / `Directory.Read.All`); se l'SP non la possiede, la
> data viene riportata come non disponibile piuttosto che ipotizzata. Per un secret **scaduto**
> l'autenticazione stessa fallisce, quindi la credenziale morta non può leggere i propri
> metadati — lo strumento lo segnala come `EXPIRED (AADSTS7000222)` ma la data di fine esatta
> non è recuperabile attraverso quella sola credenziale.

### Codici di uscita

Utili per lo scripting:

| Codice | Significato |
|------|---------|
| `0`  | La credenziale è valida (ottenuto almeno un token). |
| `2`  | La credenziale non è valida / non ha accesso. |
| `1`  | Errore — il tenant non ha potuto essere risolto, il certificato non ha potuto essere caricato, o il file `--export` non ha potuto essere scritto. |

---

## Tutti i flag

| Flag | Effetto |
|------|--------|
| `--tenant` | GUID o dominio del tenant. (o `SS_TENANT`) |
| `--cloud` | Cloud Azure: `public` (predefinito), `usgov` (GCC High), `usdod` (DoD), `china` (21Vianet). Seleziona l'autorità Entra e gli endpoint Graph/ARM/Key Vault. Accettati alias come `gov`/`dod`/`commercial`. (o `SS_CLOUD`) |
| `--client-id` | ID applicazione (client). (o `SS_CLIENT_ID`) |
| `--secret` | Client secret. Preferisci `SS_SECRET` per tenerlo fuori dalla cronologia. |
| `--cert` | Certificato per l'autenticazione JWT-assertion al posto di un secret: un PEM (key+cert) o `.pfx`/`.p12`. Richiede `cryptography`. (o `SS_CERT`) |
| `--cert-password` | Password per una chiave/PFX `--cert` criptata. (o `SS_CERT_PASSWORD`) |
| `--active` | Enumerazione di sola lettura opt-in: campioni di oggetti Graph **più** raggiungibilità data-plane di Key Vault / Storage. Disattivata di default per rimanere silenziosi. |
| `--deep` | Con `--active`: scendi di un livello nello Storage raggiungibile — elenca i blob nei contenitori accessibili e i file nelle condivisioni accessibili (solo nomi, con limite). Più rumoroso. |
| `--no-arm` | Salta l'enumerazione management-group / subscription / RBAC (solo Graph). |
| `--workers N` | Worker HTTP paralleli per le ricerche di scope ARM e le sonde data-plane (predefinito 8; `1` = sequenziale). |
| `--update-manifest` | Recupera la mappa autorevole GUID→nome degli appRole dal tenant live (Graph **più** qualsiasi altra API risorsa su cui questa credenziale è assegnata), la mette in cache, poi esce. |
| `--json` | Stampa l'intero risultato nidificato come JSON invece del report. |
| `--export PATH` | Scrivi i risultati su un file. Formato dedotto dall'estensione (`.csv` / `.ndjson` / `.jsonl` / `.json` / `.html`). I file vengono scritti solo per il proprietario (`0600`). |
| `--export-format` | Forza il formato di esportazione (`ndjson` / `csv` / `json` / `html`). |
| `--timeout N` | Timeout per richiesta in secondi (predefinito 20). Le richieste al control-plane ARM (enumerazione RBAC + discovery di Resource Graph) usano un timeout più lungo — `1.5×`, minimo 30s — perché sono più lente. |
| `--verbose`, `-v` | Traccia ogni richiesta HTTP Graph/ARM/data-plane (metodo, URL, stato) su stderr. |
| `--no-banner` | Sopprimi il banner ASCII. |
| `--version` | Stampa la versione ed esci. |

---

## Esportazione dei risultati

`--export` appiattisce il risultato in **un record per ogni elemento scoperto** —
credenziale, token, permesso Graph, assegnazione app-role, ruolo ARM, hit
data-plane e finding con punteggio — ciascuno con il contesto della credenziale,
così che ogni riga sia autosufficiente.```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

Ogni record contiene un record_type (credential, secret, token, graph_permission, app_role_assignment, directory_role, owned_object, arm_role, dataplane, delegated_permission, requested_permission, finding), così un consumatore può filtrare solo ciò di cui ha bisogno — ad esempio, solo i risultati con punteggio:```bash jq 'select(.record_type=="finding")' results.ndjson

root@kitploit:~
Il report sul terminale e `--export` lavorano insieme: l'esportazione non sopprime il report (la conferma "Esportato …" va su stderr, quindi reindirizzare `--json` tramite pipe resta pulito).

I file di esportazione includono il contesto delle credenziali (claims del token, `hint` del segreto, ID delle chiavi), quindi vengono scritti **solo proprietario (`0600`)** per evitare fughe su un host condiviso o sincronizzato. Trattali come artefatti sensibili dell'engagement. La scrittura attraverso un symlink viene rifiutata direttamente, quindi un percorso di esportazione non può essere reindirizzato per troncare altro.

I nomi in un risultato provengono dal tenant oggetto di valutazione — nomi visualizzati di app e gruppi, nomi di container e blob — pertanto vengono trattati come output non fidato:

- I valori **CSV** che verrebbero letti come formula (`=`, `+`, `-`, `@` iniziali) vengono preceduti da un apice singolo, così un nome visualizzato come `=cmd|' /C calc'!A0` non può essere eseguito quando il file viene aperto in un foglio di calcolo. I fogli di calcolo rimuovono l'apice nella visualizzazione.
- L'output **Terminale, CSV e HTML** ha i caratteri di controllo rimossi, quindi un nome che trasporta sequenze ANSI non può riscrivere il titolo del tuo terminale né sovrascrivere i risultati sopra di esso — sia che tu legga il report dal vivo, esegua `cat` sul CSV o `cat` sull'HTML.
- **JSON / NDJSON restano fedeli**: `json.dumps` codifica i caratteri di controllo come `\uXXXX`, che sono inerti come testo mentre un parser ricostruisce comunque il valore esatto restituito dal tenant. Il nome grezzo è una prova, quindi viene conservato lì.

---

## Come vengono risolti i GUID dei permessi

`appRoleAssignments` arrivano come GUID. secret_stalker li risolve in nomi tramite una lookup piatta (i GUID di appRole sono globalmente unici), che continua a funzionare **anche quando le letture della directory sono negate**:

- Una mappa best-effort delle permission Graph note è inclusa in `secret_stalker/data/graph_app_roles.json`.
- `--update-manifest` la sovrascrive con dati autorevoli recuperati dal vivo dal tenant in scope — Microsoft Graph **più ogni altra API di risorsa su cui questa credenziale è assegnata** (es. Exchange Online, SharePoint), quindi anche i GUID non Graph vengono risolti.
- Un GUID sconosciuto viene mostrato **grezzo e segnalato** — lo strumento non indovina mai un nome.

---

## Come funziona (in breve)

- **Validità + permessi in una sola richiesta.** La claim `roles` di un token Graph valido *è* l'elenco dei permessi applicazione concessi. secret_stalker la legge dal token decodificato — veloce e silenzioso, nessuna chiamata Graph necessaria.
- **Graph ≠ ARM.** Sono audience token diverse. Una credenziale può avere diritti sull'una e non sull'altra, quindi ciascuna viene sondata in modo indipendente.
- **Data plane ≠ control plane.** Avere diritti ARM su un Key Vault (gestione) non equivale a poter leggere i suoi segreti (data plane). Con `--active`, la raggiungibilità del data plane viene testata con l'audience token della risorsa stessa — ed elenca **solo i nomi** degli oggetti, mai valori o contenuti.
- **Sondaggio del data plane per superficie.** La RBAC del data plane è concessa per tipo di oggetto / servizio, quindi ciascuno viene sondato in modo indipendente: Key Vault **secrets / keys / certificates**, Storage **blob / file / queue / table** e Cosmos DB **databases**. Una credenziale che possiede `Storage File Data SMB Share Reader` ma non è in grado di leggere blob viene evidenziata, non ignorata. (Cosmos usa un header REST AAD non standard ed è **best-effort** — valida un risultato `denied` con un account reale.)
- **Scoperta a livello di tenant.** Le risorse vengono trovate con una singola scansione di Azure Resource Graph attraverso tutte le subscription che il principal può vedere (rispettando la RBAC), con fallback all'elenco dei provider per subscription se ARG viene negato. Il report indica quale percorso è stato usato (`[discovery: resource-graph]` vs `per-subscription`). La scansione pagina i risultati fino a un limite (40 pagine × 1000 righe per tipo di risorsa), quindi un'esecuzione termina sempre; `--verbose` lo segnala se il limite viene mai raggiunto.
- **Mappatura della severità** si trova in `secret_stalker/risk.py` — modificala per regolare ciò che il tuo team considera ad alto impatto.

---

## Struttura del progetto```
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

Punti salienti implementati

  • Autenticazione con segreto o certificato (--cert) — JWT client-assertion (RS256) da PEM o PFX, con segnalazione della scadenza del certificato. auth.py
  • Ruoli di directory Entra posseduti dall'entità — inclusa l'identificazione passiva dall'attestazione wids del token (senza bisogno di letture in directory) — valutati per ruolo. graph.py / risk.py
  • Oggetti di proprietà — app/SP di proprietà della credenziale (un pivot per l'aggiunta di credenziali). graph.py
  • Visibilità dei permessi delegati (--active) — concessioni consentite + permessi richiesti, con i permessi pericolosi non consentiti segnalati come bersagli per attacchi di consenso. graph.py / risk.py
  • Narrazioni dei percorsi di attacco + report HTML (--export report.html). risk.py / report.py

Idee per la roadmap

  • Lettura degli attributi di chiavi/certificati di Key Vault (abilitato/scadenza) per il triage — sempre solo metadati, nessun materiale delle chiavi.
  • L'ispezione del contenuto di code/tabelle di Storage rientrerebbe nella lettura dei dati, quindi è volutamente fuori ambito per questo strumento di sola lettura.
Scarica lo strumento
--cloudEntra authorityMicrosoft GraphARMKey Vault
public (predefinito)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
  • Cloud commerciali e sovrani (--cloud) — pubblico, US Gov (GCC High), US DoD, e Cina (21Vianet), ciascuno con la corretta autorità Entra e i destinatari Graph / ARM / Key Vault. clouds.py
  • Scoperta delle risorse a livello di tenant tramite un'unica scansione di Azure Resource Graph (rispettando RBAC), con fallback per singola sottoscrizione e recupero dei discendenti dei gruppi di gestione per le sottoscrizioni che l'elenco piatto omette. arm.py
  • Copertura completa del data-plane — segreti / chiavi / certificati di Key Vault, Storage blob / file / coda / tabella e database Cosmos DB, ciascuno sondato in modo indipendente e incluso nei risultati valutati (i dati raggiungibili sono un risultato, non solo metadati). dataplane.py / risk.py
  • Conteggi accurati — gli elenchi del data-plane seguono i token di continuazione (limitati), quindi un conteggio di superficie riflette il totale reale; un + (es. 25+) segnala i casi in cui l'elenco è stato limitato anziché riportare in modo silenzioso un valore inferiore. dataplane.py
  • Richieste resilienti alla limitazione — un unico percorso HTTP condiviso ritenta su 429/503 rispettando Retry-After, così una limitazione transitoria non viene interpretata come "negato / nessun accesso." util.py
  • Discesa profonda nello Storage (--deep) — elenca i blob nei contenitori raggiungibili e i file nelle condivisioni raggiungibili, solo nomi e con limite massimo. dataplane.py
  • Risoluzione GUID non Graph — --update-manifest memorizza nella cache gli appRoles per ogni API della risorsa su cui la credenziale è assegnata, non solo Graph. graph.py / manifest.py
  • Concorrenza (--workers N) nelle ricerche degli ambiti ARM e nei sondaggi del data-plane, con isolamento degli errori per singolo elemento. util.py