
エクスポートされたAzureドメインダンプをスキャンして、平文パスワード、接続文字列、ストレージキー、その他のシークレットを検出します。読み取り専用の監査ワークフロー向けに、マスク処理されたCSV/HTMLレポートを生成します。
Azure 環境で暗号化されずに放置されるべきではない平文パスワード、キー、接続文字列、その他のシークレットを、MicroBurst の Get-AzDomainInfo 出力から探し出す PowerShell スキャナです。
読み取り専用の監査ワークフロー向けに作られています: MicroBurst でドメインダンプを収集し(Get-AzDomainInfo には Reader アクセスで十分です)、このツールを出力フォルダに向けます。Azure 自体には一切触れません — 既にエクスポート済みのファイルを読むだけです。シークレットの値はすべてのレポートでマスク処理され、そのため出力は検出結果に添付しても安全です。
# Clone / copy this folder, then from a PowerShell prompt:
.\Scan-MicroBurst.ps1 -Path .\MicroBurst-2026 -Verbose
またはモジュールをインポートしてコマンドレットを直接使用:
Import-Module .\MicroBurstSecretsHunter.psd1 -Force
Invoke-MBSecretScan -Path .\MicroBurst-2026
レポートは、-OutputDirectory を指定しない限り、カレントディレクトリのタイムスタンプ付きフォルダ(MBSecretScan-<timestamp>)に書き出されます。
既定ではすべての値がマスクされるため、レポートを共有しても安全です。表示される文字は値の長さの4分の1(先頭4文字+末尾2文字が上限)に抑えられ、8文字以下の値は固定幅マスクに置き換えられます — 典型的なパスワードは ******** と表示され、88文字のストレージキーは AAAA**********AA のように識別可能な形で残ります。コンテキスト文字列はトランケートされる前にマスクされ、ある行で見つかったすべてのシークレットは、その行にあるすべての検出結果のコンテキストからマスクされるため、レポートに平文は残りません。誤検知をトリアージする際には、完全な値を確認した方が速いことがよくあります — -ShowSecrets を渡すと、すべての出力(コンソール、CSV、HTML)でマスクされない値が出力されます。その場合、コンソールと HTML には明確な警告バナーが表示され、レポートは生の資格情報として扱う必要があります:
Invoke-MBSecretScan -Path .\dump -ShowSecrets # raw values, for local triage
Windows PowerShell 5.1 および PowerShell 7+(Windows、Linux、macOS)で動作します。
実行ごとに3つの成果物が生成されます:
| 出力 | 説明 |
|---|---|
| コンソールサマリー | 重要度/カテゴリ別の色分けされた件数と、上位の Critical/High 検出結果。 |
findings.csv | 検出結果ごとに1行(重要度、ルール、ファイル、行、マスク済みの値、コンテキスト)で、Excel でのトリアージ用。スキャンされたコンテンツを含むフィールドは、スプレッドシートの数式インジェクションに対してエスケープされます。 |
report.html |
コマンドレットは検出結果オブジェクトをパイプラインにも出力するため、後処理が可能です:
$f = Invoke-MBSecretScan -Path .\dump -Quiet
$f | Where-Object Severity -eq 'Critical' | Format-Table File,Line,RuleName
完全で編集可能なルールセットは Private/Get-MBSignature.ps1 にあります。各ルールは以下のフィールドを持つ [PSCustomObject] です:
Get-AzDomainInfo は、automation アカウント変数とアプリ設定を Name,Value[,Encrypted] 行としてエクスポートします。シークレットは Value 列にあり、それを識別するキーワード(例: ServiceAccountPwd、dbConnectionString)は Name 列にあるため、単純な正規表現では同じ「行」で両方を認識できず、キーワードはワード境界のない複合トークンに埋もれてしまいます。
.csv / .tsv ファイルの場合、スキャナは追加で構造化列ペアリング(Private/Get-MBCsvFinding.ps1)を実行します:
Encrypted=True とマークされた行はスキップされます(値は平文ではありません)。Password や StorageKey 列など)の場合、プレースホルダー以外のすべてのセルが報告されます。信頼度の高いルールで既にカバーされている値(接続文字列、ストレージキー、SAS)は、より厳密なマスク処理のために生の行パスに委ねられ、検出結果はカテゴリごとに重複排除されるため、同じシークレットが2回報告されることはありません。ファイルを CSV として解析できない場合は、通常の生の行スキャンに自動的にフォールバックします。
-ScanValues)上記のペアリングは設定の名前をキーとしています。無意味な名前の下に保存されたシークレット(例: Config1 = P@ssw0rd2026!)も検出するには、-ScanValues を渡します。値セルのコンテンツを2つの保守的なLow 重要度ヒューリスティックで検査します:
!@#$%^&* など)に加えて文字と別の文字クラスを含む。Standard_D2s_v3 のような識別子スタイルの値(記号が _ - . のみ)は無視されます。-MinEntropy 以上。パス/URL/リソース ID(/ または \ を含むもの)は、リソース ID を誤検知しないようにスキップされます。Name/Value テーブルでは Value 列をスキャンし、自由形式のテーブルではすべてのセルをスキャンします。これは、より高い再現率と引き換えに誤検知が増えるため、既定ではオフです — より深いスイープのためにオンにして、Low の検出結果をトリアージしてください。
Azure のダンプには、シークレットではない長いランダム風の文字列がたくさん含まれています。スキャナはこれらをフィルタリングします:
GUID(サブスクリプション / テナント / リソース / オブジェクト ID)は決してフラグ付けされません。
プレースホルダー & 非シークレットの値形状 — ********、null、<provide-at-deploy>、true/false、繰り返し文字、テンプレートトークン(${var}、%VAR%)、JSON オブジェクト/配列({...}、[...]、複数行を含む)、日付/タイムスタンプ、シリアライズされた .NET 型/コレクション名(例: VM スケールセットの Secrets 列が System.Collections.Generic.List1[...VaultSecretGroup]と表示される)— はスキップされます。これは形状ベースであることに注意してください: 実際の平文値を保持するSecrets` 列は依然としてフラグ付けされます。
良性のパスワードメタデータフィールド — 名前にキーワードを含むが、パスワードのポリシー/状態のみを説明し、シークレット自体は含まないディレクトリ列(PasswordProfile、PasswordPolicies、、、 など)。これらは / のような RBAC エクスポートで一般的であり、フラグ付けされませんが、実際に という名前の列は依然としてフラグ付けされます。Key Vault のアクセスポリシー権限列(、 など)— のような権限動詞を保持 — も同様に無視されます。
MicroBurstSecretsHunter.psd1 Module manifest
MicroBurstSecretsHunter.psm1 Module loader
Scan-MicroBurst.ps1 Convenience wrapper script
Public/
Invoke-MBSecretScan.ps1 Main cmdlet (file walk, matching, reporting)
Private/
Get-MBSignature.ps1 Detection rule set (edit to extend)
Get-MBCsvFinding.ps1 Structured CSV Name/Value column pairing
MBHelpers.ps1 Entropy, redaction, context rendering,
CSV field escaping, line windowing,
placeholder/GUID filters
Write-MBConsoleSummary.ps1 Console output
New-MBHtmlReport.ps1 HTML report generator
tests/
sample-dump/ Example Get-AzDomainInfo-style fixture
同梱のサンプルで試す場合:
.\Scan-MicroBurst.ps1 -Path .\tests\sample-dump
スキャナが読み取れなかったものはすべて盲点であり、沈黙した盲点は「ここには何もない」と読めてしまいます。そのため、スキャナはそれらを明示します:
-MaxFileSizeMB を超えるファイルは、ファイル名を示す Write-Warning、コンソールサマリーの NOT scanned 行、HTML レポートのバナーを生成します。-Verbose で実行すると表示されます。AdminPassword を簡単に隠せます。そのため、行は重複する8000文字ウィンドウでスキャンされます。オーバーラップによる重複ヒットは重複排除でまとめられます。-ShowSecrets を使用すると、完全な平文の資格情報が含まれるため、安全に保管し、トリアージ後に削除してください。| 自己完結型の HTML レポート(外部アセットなし)。重要度カード、ライブテキストフィルター、重要度トグル付き — クライアントと共有可能。 |
| ルール | 重要度 | ダンプ内の例 |
|---|
| 埋め込みパスワード付き SQL/DB 接続文字列 | Critical | App Service 設定、web.config エクスポート |
| Azure Storage アカウントの接続文字列 / 88文字キー | Critical | アプリ設定、Storage エクスポート |
Service Bus / Event Hub の SharedAccessKey | Critical | メッセージングリソース設定 |
| Cosmos DB アカウントキー | Critical | アプリ設定 |
| PEM 秘密鍵ブロック | Critical | Key Vault / 証明書エクスポート |
| Azure Redis Cache パスワード | High | キャッシュ接続文字列 |
Azure AD クライアントシークレット(2021年以降の …Q~… 形式) | High | ARM テンプレート、アプリ設定 |
SAS トークン / sig= パラメータ | High | Storage SAS URL |
| JWT / ベアラートークン | High | キャッシュされたトークン、設定 |
証明書 / キーファイルの存在(.pfx、.pem、.key など) | High | ダンプ内の任意の場所 |
一般的な password / pwd 代入 | High | Automation 変数、アプリ設定、ARM パラメータ |
一般的な secret / client_secret 代入 | High | アプリ設定、テンプレート |
| AWS アクセスキー / GitHub / Slack トークン | High/Med | Azure アプリに保存された外部資格情報 |
一般的な api_key / access_key / connectionstring | Medium | アプリ設定 |
| 高エントロピー文字列(ヒューリスティック) | Low | 未知のキー形式向けの最終手段 — -IncludeEntropy でオプトイン |
| フィールド | 必須 | 目的 |
|---|
Id、Name、Category、Severity | はい | 検出結果の識別、報告、並べ替えに使用。 |
Pattern | はい | 正規表現。スキャンごとに1回コンパイルされます。 |
ValueGroup | はい | シークレットを保持するキャプチャグループ(0 = マッチ全体)。マスク処理に使用。 |
MultiLine | いいえ | 行単位ではなくファイル全体のテキストに対して評価(PEM ブロック)。最初のマッチだけでなく、すべてのマッチが報告されます。 |
CaseSensitive | いいえ | 既定の IgnoreCase コンパイルを無効化。大文字小文字が定義されている形式(AKIA、ghp_、eyJ、Q~)に設定します — 設定しないと、任意の大文字小文字の類似文字列がマッチします。 |
Redact | いいえ | キャプチャされた値がシークレットではなくラベル(PEM ヘッダー行、証明書ファイル名など)の場合に $false を設定すると、マスクされて読めなくなる代わりにそのまま表示されます。既定ではマスクされます。 |
ForceChangePasswordNextSignInLastPasswordChangeDateTimePasswordExpirationDateTimeInheritedOwners.csvInheritedContributors.csvPasswordPermissionsToSecretsStrPermissionsToKeysStrGet, List, Set, Deleteコード & テンプレート式 — password/secret/などがリテラルではなく式を指す変数またはプロパティ名の場合、キャプチャされた値はスキップされます: PowerShell コマンドレット呼び出し(Get-RandomPassword 8、Get-AzKeyVaultSecret ...)、スコープ付きを含む変数参照($result、$kv.Secrets、$global:clientSecret、$env:KEY)、サブ式((-join $x))、ARM / Logic App 参照(@{body(...)}、@body(...)、[parameters('...')])。automation ランブックや Logic App 定義で一般的です。
ここでの曖昧な形状 — $var、(expr)、Verb-Noun — は、実際にコードを含むファイル(.ps1、.json、.tf、.yaml など)でのみ破棄されます。パスワードは有効な変数参照($ummer2026、$ecretPass1)であることが非常に多いため、このフィルタを CSV 値セルに適用すると実際のシークレットが破棄されていました。曖昧さのないテンプレートマーカー(@{、@body(、[parameters()はどこでもフィルタリングされます。
列ヘッダー隣接 — 一般的な keyword = value ルールはセパレータとして : と = のみを扱う(, は扱わない)ため、...,AdminPassword,Secrets,... のような CSV ヘッダーが次の列名をパスワードとしてキャプチャすることはなくなりました。カンマ区切りの Name,Value ペアは、構造化 CSV ペアリングで引き続きカバーされます。
リソース ID パスは、1つの高エントロピートークンとして扱うのではなく、短いセグメントに分割されます。
大文字小文字を区別する資格情報形式(AWS AKIA…、GitHub ghp_…、JWT eyJ…、Azure AD …Q~…)は大文字小文字を区別してマッチするため、akiaijklmnopqrstuvwx のような任意の大文字小文字の類似文字列は報告されません。キーワードルール(password=、AccountKey=)は大文字小文字を区別しないままです。
エントロピーヒューリスティックは既定ではオフ — ノイズの多い Low 重要度の検出結果を生成するため、より深いスイープには -IncludeEntropy でオプトインします。それでも、キー素材のように見えるトークン(文字+数字の混在または base64 マーカー)に対してのみ発火するため、networkSecurityGroups のようなキャメルケース識別子は無視されます。-MinEntropy 4.5 で基準をさらに引き上げることもできます。
| パラメータ | 既定値 | 目的 |
|---|
-Path | (必須) | MicroBurst 出力のルートフォルダ。 |
-OutputDirectory | タイムスタンプ付きフォルダ | レポートの書き出し先(スキャン対象外)。スキャンルート自体にすることはできません。その中のネストされたフォルダは警告されます。 |
-IncludeEntropy | オフ | 高エントロピーヒューリスティックパスにオプトインします(Low 重要度の検出結果が追加されます)。 |
-MinEntropy | 4.0 | ヒューリスティックのシャノンエントロピーしきい値(ビット/文字)。 |
-ScanValues | オフ | 無害な名前の下にあるシークレットについて、CSV の値セルのコンテンツも検査します(Low 重要度、再現率向上)。 |
-ShowSecrets | オフ | 誤検知のトリアージを高速化するため、すべての出力でマスクされていない値を出力します。レポートは生の資格情報になります。 |
-MaxFileSizeMB | 50 | これより大きいファイルはスキップされます。スキップされたファイルは警告され、サマリーと HTML レポートでカウントされます。 |
-IncludeExtension | 一般的なテキスト型 | スキャンするファイルタイプを上書きします(先頭のドットは省略可能)。 |
-NoCsv / -NoHtml | オフ | レポート形式をスキップします。 |
-Quiet | オフ | コンソールサマリーを抑制します(オブジェクトは引き続き返されます)。 |