Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
SecretsStalker — 只读 Entra ID 应用凭据评估:枚举 Graph 权限、Azure RBAC 和可访问的云数据,然后将发现映射到权限提升和横向移动路径。 | Kitploit
工具/GitHubGitHub/rootsecdev/secretsstalker
身份验证与授权云基础设施安全权限提升侦察横向移动后渗透利用渗透测试云安全身份与访问管理 (IAM)红队
GitHubrootsecdev/secretsstalker

SecretsStalker

1114天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

只读 Entra ID 应用凭据评估:枚举 Graph 权限、Azure RBAC 和可访问的云数据,然后将发现映射到权限提升和横向移动路径。

查看仓库

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:~
**这个 Entra ID 客户端 ID + 客户端机密实际上能做什么?**

你发现了一个 Entra ID(Azure AD)应用程序凭据 — 一个客户端 ID 和客户端机密 —
它来自一次授权评估,并且其所属租户在范围内。
`secret_stalker` 获取这两个值,并从零开始告诉你:

1. **它是否有效,机密何时过期?** — 并且如果无效,*为什么*
   (错误的机密、已过期的机密、应用不在租户中…)。对于有效的机密,它
   会读取应用注册的 `passwordCredentials` 并报告过期
   日期 + 剩余天数(需要目录读取;见下方说明)。
2. **它拥有哪些 Microsoft Graph 权限?** — 应用程序权限直接读取自
   颁发的令牌,加上**它所持有的 Entra 目录角色**(甚至
   被动地从令牌的 `wids` 声明中检测到)以及**它拥有的对象**
   (应用/SP,你可以为其添加凭据)。
3. **它对 Azure 有什么控制权?** — RBAC 角色分配在
   管理组和订阅范围。
4. **它能接触到真实数据吗?** — 可选的 Key Vault(机密 / 密钥 / 证书),
   Storage(blob / file / queue / table)以及 Cosmos DB 数据平面可达性检查。
5. **影响是什么?** — 危险的权限、角色、所有权,以及可触达的
   数据映射到已知的权限提升 / 横向移动原语,按严重性评级,
   并附有具体的**攻击路径**说明。

它可以使用**客户端机密**或**证书**(`--cert`)进行身份验证,
并且可用于**商业云和主权云**(`--cloud`)。

它**默认为被动模式**,并且**从不修改任何内容** — 仅进行只读
枚举。

> ⚠️ **仅限授权测试。** 请仅针对那些
> 明确在你获授权执行的项目范围内的租户运行。

---

## 安装```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

唯一的运行时依赖是 requests。令牌在本地解码(base64 + JSON)——不涉及签名验证、加密库或 Microsoft SDK。唯一的例外是证书认证(--cert),它需要可选的 cryptography 包来签署 JWT 客户端断言。需要 Python 3.7+。

执行 pip install . 之后,你可以用 secret_stalker … 来调用它,而不用再写 python -m secret_stalker …。


快速上手

找出一个凭据能做什么的最快方式:```bash python -m secret_stalker
--tenant contoso.onmicrosoft.com
--client-id 11111111-2222-3333-4444-555555555555
--secret ''

root@kitploit:~
`--tenant` 接受租户 GUID 或域名 — 域名会通过公共 OpenID 配置端点自动解析为其租户 ID。

### 让机密远离 shell 历史记录

通过环境变量而不是标志传递凭据:```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

--tenant / --client-id / --secret 中的任意一个都可以来自 SS_TENANT / SS_CLIENT_ID / SS_SECRET。命令行标志优先于环境变量。

这不仅与 shell 历史记录有关:argv 值在进程的整个生命周期内可被任何本地 用户读取(ps、/proc/<pid>/cmdline)。如果 --secret 或 --cert-password 作为标志传入,工具会打印一行提醒到 stderr — 该值绝不会出现在 --json 或 --export 输出中。

使用证书而非机密进行身份验证

应用注册通常使用证书而非机密。传递 --cert (一个包含私钥 和 证书的 PEM,或一个 .pfx/.p12),并且 工具将使用带签名的 JWT 客户端断言进行身份验证:```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:~
证书认证需要可选的 `cryptography` 包(`pip install '.[cert]'`)。
该工具报告证书自身的有效期(根据应用 `keyCredentials` 中的指纹进行匹配),与处理机密的方式相同。`--cert`/`--cert-password` 也会从 `SS_CERT` / `SS_CERT_PASSWORD` 中读取。

### 主权云和政府云

默认情况下,secret_stalker 以**商业**云为目标。对于主权租户,请传递 `--cloud`(或 `SS_CLOUD`),以便 Entra 颁发机构以及 Graph / ARM / Key Vault 端点匹配 — 否则有效的凭据看起来就像没有访问权限:```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 ...

接受 gov、dod、commercial、gcc-high 和 21vianet 等别名。 (Storage 数据平面的受众 storage.azure.com 在所有云中均相同。)


参与评估时的推荐工作流程

  1. 刷新此租户的权限映射(一次)。 将 Graph 权限 GUID 解析为目标租户的权威名称: ```bash python -m secret_stalker --update-manifest
    root@kitploit:~

这会进行身份验证,将租户的 Graph appRole 映射缓存到 ~/.secret_stalker/app_roles_cache.json,然后退出。如果该凭据 无法读取服务主体 — 内置映射仍然覆盖了 众所周知的权限。

  1. 被动基线。 查看有效性、Graph 权限和 Azure RBAC,无需 接触租户对象: ```bash python -m secret_stalker
    root@kitploit:~
  2. 需要深入分析并保留报告时,请启用主动模式。 添加只读的 Graph 对象采样以及 Key Vault / Storage 数据平面可达性,并写入扁平化导出, 供分类或摄取: ```bash python -m secret_stalker --active --export results.ndjson
    root@kitploit:~

阅读输出

终端报告按自上而下的顺序排列,从“是否有效”到“造成了何种 损害。”典型运行如下所示:``` 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)** 列出每个探测到的受众(Graph、ARM,以及在
  `--active` 下发现匹配资源时的 Key Vault / Storage / Cosmos DB)。Graph 与
  ARM 是*相互独立*的:一个凭据可以持有其中之一而不持有另一个。
- **机密(Secret)** 显示有效性;对于有效机密,还显示过期日期和剩余天数
  (临近过期会高亮显示)。关于过期机密,请参阅下面的说明。
- **发现项(Findings)** 是最先要阅读的部分——高影响的 Graph 权限(`GRAPH`)、
  ARM 角色(`ARM`)、Entra 目录角色(`ROLE`)、拥有的应用/服务主体(`OWN`)、
  可达的数据平面(`DATA`),以及已请求但未获同意的同意攻击目标(`WANT`)——
  经去重并按严重性评级。即使没有危险的 Graph/ARM 授权,能够读取每个
  Key Vault 机密或持有目录角色本身也是一项发现项。
- **攻击路径(Attack paths)** 将最重要的发现转成具体的后续步骤(例如
  *Privileged Role Administrator → 为自己分配 Global Administrator → 租户接管*)。
- **Active Graph 枚举**(`--active`)报告每个只读探测返回的结果。大多数探测
  请求的是小而有上限的分页,因此已满的页面会显示为 `N+`(例如
  `users  accessible  (returned 5+)`)——表示*至少*五个,而非正好五个。
  没有上限的探测(`organization`、`directoryRoles`)会报告不带 `+` 的
  真实总数。
- **目录角色 / 拥有的对象 / 委派权限** 各自拥有独立的小节。即使没有目录读取
  权限,也会根据令牌的 `wids` 声明检测目录角色;委派权限无法被仅应用(app-only)
  凭据使用,但会显示出来,用于用户上下文 pivot 和同意攻击目标定位。
- **整体风险(Overall risk)** 是单项发现中最高的严重性等级。

> **机密过期——哪些信息可知。** 过期日期*不在*令牌中;它存在于 Entra ID 中
> 应用注册的 `passwordCredentials` 里。对于**有效**的机密,secret_stalker 会
> 通过 Graph 读取它,并根据 `hint`(前 3 个字符)将你的机密匹配到正确的
> 凭据——这需要目录读取权限(`Application.Read.All` / `Directory.Read.All`);
> 如果服务主体缺少该权限,日期会报告为不可用,而不会进行猜测。对于
> **已过期**的机密,身份验证本身会失败,因此失效的凭据无法读取其自身的
> 元数据——该工具会将其标记为 `EXPIRED (AADSTS7000222)`,但仅凭该凭据无法
> 检索确切的结束日期。

### 退出码

便于脚本化使用:

| 代码 | 含义 |
|------|---------|
| `0`  | 凭据有效(至少获得一个令牌)。 |
| `2`  | 凭据无效 / 没有访问权限。 |
| `1`  | 错误——无法解析租户、无法加载证书,或无法写入 `--export` 文件。 |

---

## 所有标志

| 标志 | 作用 |
|------|--------|
| `--tenant` | 租户 GUID 或域名。(或 `SS_TENANT`) |
| `--cloud` | Azure 云:`public`(默认)、`usgov`(GCC High)、`usdod`(DoD)、`china`(21Vianet)。选择 Entra 颁发机构以及 Graph/ARM/Key Vault 端点。接受 `gov`/`dod`/`commercial` 等别名。(或 `SS_CLOUD`) |
| `--client-id` | 应用程序(客户端)ID。(或 `SS_CLIENT_ID`) |
| `--secret` | 客户端机密。建议优先使用 `SS_SECRET`,避免其出现在历史记录中。 |
| `--cert` | 用于 JWT 断言身份验证(而非客户端机密)的证书:PEM(密钥+证书)或 `.pfx`/`.p12`。需要 `cryptography`。(或 `SS_CERT`) |
| `--cert-password` | 加密的 `--cert` 密钥/PFX 的密码。(或 `SS_CERT_PASSWORD`) |
| `--active` | 选择加入的只读枚举:Graph 对象样本**以及** Key Vault / Storage 数据平面可达性。默认关闭以保持安静。 |
| `--deep` | 与 `--active` 一起使用:深入一层进入可达的 Storage——列出可访问容器中的 blob 和可访问共享中的文件(仅名称,有上限)。噪音更大。 |
| `--no-arm` | 跳过管理组 / 订阅 / RBAC 枚举(仅 Graph)。 |
| `--workers N` | ARM 范围查找和数据平面探测的并行 HTTP worker 数(默认 8;`1` = 顺序执行)。 |
| `--update-manifest` | 从实时租户获取权威的 appRole GUID→名称映射(Graph **以及**此凭据被分配到的任何其他资源 API),缓存后退出。 |
| `--json` | 将完整的嵌套结果以 JSON 形式打印,而不是报告。 |
| `--export PATH` | 将结果写入文件。格式根据扩展名推断(`.csv` / `.ndjson` / `.jsonl` / `.json` / `.html`)。文件以仅所有者可读写(`0600`)权限写入。 |
| `--export-format` | 强制指定导出格式(`ndjson` / `csv` / `json` / `html`)。 |
| `--timeout N` | 每个请求的超时时间(秒,默认 20)。ARM 控制平面请求(RBAC 枚举 + Resource Graph 发现)使用更长的超时时间——`1.5×`,最少 30 秒——因为它们运行较慢。 |
| `--verbose`, `-v` | 将每个 Graph/ARM/数据平面 HTTP 请求(方法、URL、状态)跟踪输出到 stderr。 |
| `--no-banner` | 抑制 ASCII 横幅。 |
| `--version` | 打印版本并退出。 |

---

## 导出结果

`--export` 将结果扁平化为**每个发现项一条记录**——
凭据、令牌、Graph 权限、应用角色分配、ARM 角色、数据平面
命中以及评分发现项——每条记录都带有凭据上下文,因此每一行都能独立
成立。```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

每条记录都带有一个 record_type(credential、secret、token、 graph_permission、app_role_assignment、directory_role、owned_object、 arm_role、dataplane、delegated_permission、requested_permission、 finding),因此使用者可以只筛选出自己需要的内容——例如,仅筛选 已计分的命中项:```bash jq 'select(.record_type=="finding")' results.ndjson

root@kitploit:~
终端报告与 `--export` 协同工作 —— 导出不会抑制
报告(“已导出 …”确认信息进入 stderr,因此通过管道传递 `--json` 时仍保持
干净)。

导出文件携带凭据上下文(令牌声明、secret `hint`、密钥 ID),
因此以 **仅所有者(`0600`)** 权限写入,以避免在共享或同步的
主机上泄露。请将它们视为敏感的参与产物。通过符号链接写入会被
直接拒绝,这样导出路径无法被重定向以截断其他
文件。

结果中的名称来自被评估的租户 —— 应用和组显示
名称、容器和 Blob 名称 —— 因此它们被视为不受信任的输出:

- **CSV** 值若会被读取为公式(以 `=`、`+`、`-`、`@` 开头),则
  会添加单引号前缀,因此像 `=cmd|' /C calc'!A0` 这样的显示名称无法
  在电子表格中打开文件时执行。电子表格会在显示时
  移除引号。
- **终端、CSV 和 HTML** 输出中的控制字符会被剥离,因此一个名称
  如果携带 ANSI 转义序列,就无法重设你的终端标题或覆盖上方的发现结果
  —— 无论你是实时阅读报告、`cat` CSV 还是 `cat` HTML。
- **JSON / NDJSON 保持原样**:`json.dumps` 将控制字符编码为
  `\uXXXX`,作为文本它是惰性的,但解析器仍能往返还原租户返回的精确
  值。原始名称是证据,因此会在其中保留。

---

## 如何解析权限 GUID

`appRoleAssignments` 返回的是 GUID。secret_stalker 通过
扁平查找(appRole GUID 全局唯一)将其解析为名称,即使在
目录读取被拒绝时也能正常工作:

- 一份尽力而为的已知 Graph 权限映射随附于
  `secret_stalker/data/graph_app_roles.json`。
- `--update-manifest` 会用从范围内租户实时拉取的权威数据覆盖它 —— Microsoft Graph **以及此凭据
  被分配到的每个其他资源 API**(例如 Exchange Online、SharePoint),因此非 Graph GUID
  也能解析。
- 未知 GUID 会 **原样显示并标记** —— 该工具从不猜测名称。

---

## 工作原理(简介)

- **有效性和权限在一次请求中完成。** 成功的 Graph 令牌的 `roles`
  声明*就是*已授予的应用程序权限列表。secret_stalker 从解码后的令牌中读取它
  —— 快速且安静,无需 Graph 调用。
- **Graph ≠ ARM。** 它们是不同的令牌受众。凭据可能在一个上拥有权限
  而在另一个上没有,因此每个都会被独立探测。
- **数据平面 ≠ 控制平面。** 对 Key Vault(管理)拥有 ARM 权限
  并不等同于能够读取其机密(数据平面)。在 `--active` 下,
  会使用资源自身的令牌受众测试数据平面可达性 —— 并且它
  仅列出对象的**名称**,从不列出值或内容。
- **按表层进行数据平面探测。** 数据平面 RBAC 按对象类型 /
  服务授予,因此每个都被独立探测:Key Vault **机密 / 密钥 /
  证书**、Storage **blob / 文件 / 队列 / 表**,以及 Cosmos DB
  **数据库**。如果凭据是 `Storage File Data SMB Share Reader` 但不是
  blob 读取器,它就会被发现而不会漏掉。(Cosmos 使用非标准 AAD REST 头
  并且是 **尽力而为** —— 请针对实际账户验证 `denied` 结果。)
- **租户级发现。** 使用单个 Azure Resource Graph
  扫描主体可以看到的每个订阅(尊重 RBAC),如果 ARG 被拒绝,则
  回退到按订阅列出提供程序。报告会标记使用了哪条
  路径(`[discovery: resource-graph]` 与 `per-subscription`)。扫描
  会分页获取结果,直到达到上限(每种资源类型 40 页 × 1000 行),因此
  运行总能终止;`--verbose` 会在达到上限时说明这一点。
- **严重性映射** 位于 `secret_stalker/risk.py` 中 —— 编辑它以调整
  你的团队认为高风险的内容。

---

## 项目结构```
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

已实现亮点

  • 机密或证书认证 (--cert) — JWT 客户端断言(RS256),从 PEM 或 PFX 生成,并报告证书过期时间。 auth.py
  • 主体持有的 Entra 目录角色 — 包括从令牌的 wids 声明进行被动检测 (无需读取目录)— 按角色评分。 graph.py / risk.py
  • 拥有的对象 — 凭据所拥有的应用/服务主体(一个凭据添加的跳板)。 graph.py
  • 委托权限可见性 (--active) — 已同意的授权 + 已请求的 权限,将未经同意的危险权限标记为同意攻击目标。 graph.py / risk.py
  • 攻击路径说明 + HTML 报告 (--export report.html)。 risk.py / report.py
  • 商业云 + 主权云 (--cloud) — 公有云、美国政府云(GCC High)、美国国防部云, 以及中国(21Vianet),各自使用正确的 Entra 颁发机构和 Graph / ARM / Key Vault 受众。

路线图构想

  • Key Vault 密钥/证书的 属性 读取(启用/过期)用于分类 — 仍然仅限元数据,不涉及密钥材料。
  • 查看 Storage 队列/表内容会越界到读取数据,因此对于这个只读工具 来说,它被有意列为 超出范围。
下载工具
--cloudEntra 颁发机构Microsoft GraphARMKey Vault
public(默认)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
clouds.py
  • 租户级资源发现 通过一次 Azure Resource Graph 扫描(遵循 RBAC), 支持按订阅回退,并针对平面列表遗漏的订阅进行管理组 后代恢复。 arm.py
  • 完整的数据平面覆盖 — Key Vault 机密 / 密钥 / 证书、Storage blob / 文件 / 队列 / 表,以及 Cosmos DB 数据库,每个都独立探测 并合并到评分结果中(可访问的数据是一项发现,而不仅仅是 元数据)。 dataplane.py / risk.py
  • 准确的计数 — 数据平面列表遵循延续令牌(有界),因此表面计数 反映真实总数;+(例如 25+)表示列表被截断,而不是 静默少报。 dataplane.py
  • 抗限流请求 — 一个共享的 HTTP 路径重试 429/503, 并遵循 Retry-After,因此瞬时限流不会被误读为“拒绝 / 无访问权限”。 util.py
  • 深度存储下钻 (--deep) — 列出可访问容器中的 blob 和 可访问共享中的文件,仅名称且受上限限制。 dataplane.py
  • 非 Graph GUID 解析 — --update-manifest 会为凭据被分配到的每个资源 API 缓存 appRoles,而不仅仅是 Graph。 graph.py / manifest.py
  • 并发 (--workers N) 用于 ARM 范围查找和数据平面探测, 具备逐项错误隔离。 util.py