一个 PowerShell 扫描器,用于梳理 MicroBurst
Get-AzDomainInfo 的输出,查找明文密码、密钥、连接字符串以及其他绝不应以未加密形式存在于 Azure 环境中的机密。
专为 只读审计工作流 而构建:你可以使用 MicroBurst 收集域转储(对于 Get-AzDomainInfo,Reader 权限就足够了),然后将此工具指向输出文件夹。它不会接触 Azure 本身——它只读取你已经导出的文件。机密值在所有报告中都被脱敏,因此输出可以安全地附加到发现项中。
# Clone / copy this folder, then from a PowerShell prompt:
.\Scan-MicroBurst.ps1 -Path .\MicroBurst-2026 -Verbose
或者导入模块并直接使用 cmdlet:
Import-Module .\MicroBurstSecretsHunter.psd1 -Force
Invoke-MBSecretScan -Path .\MicroBurst-2026
报告会写入当前目录下带时间戳的文件夹(MBSecretScan-<timestamp>),除非你传递 -OutputDirectory。
默认情况下,每个值都会被脱敏,因此报告可以安全共享。披露的字符量按值长度的四分之一计算(最多 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)。
每次运行都会产生三样东西:
| 输出 | 说明 |
|---|---|
| 控制台摘要 | 按严重级别/类别显示颜色编码的计数,以及最关键的 Critical/High 发现项。 |
findings.csv | 每个发现项占一行(严重级别、规则、文件、行号、脱敏值、上下文),便于在 Excel 中进行分类处理。包含扫描内容的字段已针对电子表格公式注入进行转义。 |
report.html | 自包含的 HTML 报告(无外部资源),带有严重级别卡片、实时文本过滤器和严重级别开关——可与客户共享。 |
该 cmdlet 还会将发现对象输出到管道中,因此你可以进行后续处理:
$f = Invoke-MBSecretScan -Path .\dump -Quiet
$f | Where-Object Severity -eq 'Critical' | Format-Table File,Line,RuleName
完整且可编辑的规则集位于 Private/Get-MBSignature.ps1 中。每条规则都是一个 [PSCustomObject],包含以下字段:
Get-AzDomainInfo 将自动化帐户变量和应用设置导出为 Name,Value[,Encrypted] 行。机密位于 Value 列中,而标识它的关键字(例如 ServiceAccountPwd、dbConnectionString)位于 Name 列中——因此普通正则表达式永远不会在同一“行”中同时看到它们,并且该关键字被埋在复合令牌中,没有单词边界。
对于 .csv / .tsv 文件,扫描器还会执行结构化列配对(Private/Get-MBCsvFinding.ps1):
Encrypted=True 的行会被跳过(该值不是明文)。Password 或 StorageKey 列),则报告每个非占位符单元格。已被高置信度规则覆盖的值(连接字符串、存储密钥、SAS)会推迟到原始行传递中进行更严格的脱敏,并且发现项按类别去重,因此同一机密绝不会被报告两次。如果文件无法解析为 CSV,扫描器会自动回退到正常的原始行扫描。
-ScanValues)上述配对以设置的名称(Name)为键。为了也捕获存储在无意义名称下的机密(例如 Config1 = P@ssw0rd2026!),请传递 -ScanValues。它会使用两种保守的 Low 严重级别启发式规则检查值单元格的内容(content):
!@#$%^&* …)以及字母和另一类别。标识符风格的值(如 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 时,它们会包含完整明文凭据——请安全存储并在处理后删除。| 规则 | 严重级别 | 转储中的示例来源 |
|---|
| SQL/数据库连接字符串(含嵌入密码) | Critical | 应用服务设置、web.config 导出 |
| Azure 存储帐户连接字符串 / 88 字符密钥 | Critical | 应用设置、存储导出 |
Service Bus / Event Hub SharedAccessKey | Critical | 消息传递资源配置 |
| Cosmos DB 帐户密钥 | Critical | 应用设置 |
| PEM 私钥块 | Critical | Key Vault / 证书导出 |
| Azure Redis 缓存密码 | High | 缓存连接字符串 |
Azure AD 客户端机密(2021 年后的 …Q~… 格式) | High | ARM 模板、应用设置 |
SAS 令牌 / sig= 参数 | High | 存储 SAS URL |
| JWT / 持有者令牌 | High | 缓存的令牌、配置 |
存在证书 / 密钥文件(.pfx、.pem、.key 等) | High | 转储中的任意位置 |
通用 password / pwd 赋值 | High | 自动化变量、应用设置、ARM 参数 |
通用 secret / client_secret 赋值 | High | 应用设置、模板 |
| AWS 访问密钥 / GitHub / Slack 令牌 | High/Med | 存储在 Azure 应用中的外部凭据 |
通用 api_key / access_key / connectionstring | Medium | 应用设置 |
| 高熵字符串(启发式) | Low | 未知密钥格式的兜底——通过 -IncludeEntropy 选择启用 |
| 字段 | 是否必需 | 用途 |
|---|
Id, Name, Category, Severity | 是 | 身份标识,以及发现项如何被报告和排序。 |
Pattern | 是 | 正则表达式。每次扫描只编译一次。 |
ValueGroup | 是 | 哪个捕获组包含机密(0 = 整个匹配)。驱动脱敏。 |
MultiLine | 否 | 针对整个文件文本评估,而不是逐行评估(PEM 块)。每个匹配都会报告,而不仅仅是第一个。 |
CaseSensitive | 否 | 选择退出默认的 IgnoreCase 编译。对于以区分大小写方式定义的格式(AKIA、ghp_、eyJ、Q~)设置此选项——否则,任意大小写的相似内容也会匹配。 |
Redact | 否 | 当捕获的值是标签而非机密(PEM 头行、证书文件名)时,设置为 $false,以便其原样显示,而不是被掩码遮盖得无法阅读。默认为脱敏。 |
ForceChangePasswordNextSignInLastPasswordChangeDateTimePasswordExpirationDateTimeInheritedOwners.csvInheritedContributors.csvPasswordPermissionsToSecretsStrPermissionsToKeysStrGet, List, Set, Delete代码与模板表达式——当 password/secret/等是指向表达式而非字面值的变量或属性名时,捕获到的值会被跳过:PowerShell cmdlet 调用(Get-RandomPassword 8、Get-AzKeyVaultSecret ...)、包括作用域引用在内的变量引用($result、$kv.Secrets、$global:clientSecret、$env:KEY)、子表达式((-join $x)),以及 ARM / Logic App 引用(@{body(...)}、@body(...)、[parameters('...')])。这在自动化 runbook 和 Logic App 定义中很常见。
这里的模糊形态——$var、(expr)、Verb-Noun——只在实际包含代码的文件(.ps1、.json、.tf、.yaml 等)中被排除。密码通常是一个合法的变量引用($ummer2026、$ecretPass1),因此将该过滤器应用于 CSV 值单元格会丢弃真实机密。明确的模板标记(@{、@body(、[parameters()在任何地方都会被过滤。
列标题邻接——通用的 keyword = value 规则只将 : 和 = 视为分隔符(而不是 ,),因此像 ...,AdminPassword,Secrets,... 这样的 CSV 标题不再将下一个列名捕获为密码。逗号分隔的 Name,Value 对仍由结构化 CSV 配对覆盖。
资源 ID 路径被拆分为短段,而不是作为一个高熵令牌处理。
区分大小写的凭据格式(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 | 关 | 抑制控制台摘要(对象仍会返回)。 |