
내보낸 Azure 도메인 덤프에서 일반 텍스트 비밀번호, 연결 문자열, 스토리지 키 및 기타 비밀을 스캔하고, 읽기 전용 감사 워크플로우를 위해 마스킹된 CSV/HTML 보고서를 생성합니다.
Azure 환경에서 평문으로 저장되어서는 안 되는 비밀번호, 키, 연결 문자열 및 기타 비밀 정보를 찾기 위해 MicroBurst 의 Get-AzDomainInfo 출력을 샅샅이 훑어보는 PowerShell 스캐너입니다.
읽기 전용 감사 워크플로를 위해 설계되었습니다: MicroBurst로 도메인 덤프를 수집하고(Get-AzDomainInfo에는 Reader 권한이면 충분합니다), 이 도구를 출력 폴더에 지정하면 됩니다. 이 도구는 Azure 자체에는 접촉하지 않으며, 이미 내보낸 파일만 읽습니다. 모든 보고서에서 비밀 값은 마스킹(redacted) 처리되므로 결과물을 발견 사항에 첨부해도 안전합니다.
# Clone / copy this folder, then from a PowerShell prompt:
.\Scan-MicroBurst.ps1 -Path .\MicroBurst-2026 -Verbose
Or import the module and use the cmdlet directly:
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)에서 동작합니다.
실행할 때마다 세 가지 결과물이 생성됩니다:
| 출력물 | 설명 |
|---|---|
| 콘솔 요약 | 심각도/카테고리별 색상 구분 개수와 상위 Critical/High 발견 항목. |
findings.csv | 발견 항목별 한 행(심각도, 규칙, 파일, 줄, 마스킹된 값, 컨텍스트)으로 Excel에서 분류할 수 있습니다. 스캔된 콘텐츠를 담은 필드는 스프레드시트 수식 삽입에 대비해 이스케이프 처리됩니다. |
report.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는 Automation 계정 변수와 앱 설정을 Name,Value[,Encrypted] 행으로 내보냅니다. 비밀 값은 Value 열에 있고, 이를 식별하는 키워드(예: ServiceAccountPwd, dbConnectionString)는 Name 열에 있습니다. 따라서 단순한 정규식으로는 같은 "줄"에서 둘을 볼 수 없고, 키워드는 단어 경계가 없는 복합 토큰 속에 묻혀 있습니다.
.csv / .tsv 파일의 경우 스캐너는 추가로 구조화된 열 페어링(Private/Get-MBCsvFinding.ps1)을 수행합니다:
Encrypted=True로 표시된 행은 건너뜁니다(값이 평문이 아니기 때문).Password 또는 StorageKey 열), 플레이스홀더가 아닌 모든 셀을 보고합니다.이미 높은 신뢰도의 규칙이 적용되는 값(연결 문자열, 스토리지 키, SAS)은 더 정밀한 마스킹을 위해 원시 줄(raw-line) 검사로 넘어가며, 발견 항목은 카테고리별로 중복 제거되어 동일한 비밀이 두 번 보고되지 않습니다. 파일을 CSV로 파싱할 수 없으면 스캐너는 자동으로 일반 원시 줄 스캔으로 대체합니다.
-ScanValues)위 페어링은 설정의 이름을 기준으로 합니다. 의미 없는 이름으로 저장된 비밀(예: Config1 = P@ssw0rd2026!)도 찾으려면 **-ScanValues**를 전달하세요. 값 셀의 내용을 두 가지 보수적인 Low(낮음) 심각도 휴리스틱으로 검사합니다:
!@#$%^&* …)와 문자 및 다른 문자 클래스 포함. Standard_D2s_v3처럼 기호가 _ - .뿐인 식별자 스타일 값은 무시합니다.-MinEntropy. 리소스 ID를 오탐하지 않도록 경로 / URL / 리소스 ID(/ 또는 \를 포함하는 모든 것)는 건너뜁니다.Name/Value 테이블에서는 Value 열을, 자유 형식 테이블에서는 모든 셀을 스캔합니다. 이는 더 높은 재현율을 얻는 대신 오탐이 늘어날 수 있으므로 기본적으로 꺼져 있습니다. 더 깊이 있는 검색이 필요하면 켜고 Low 발견 항목을 분류하세요.
Azure 덤프에는 비밀이 아닌 길고 무작위로 보이는 문자열이 가득합니다. 스캐너는 이러한 항목을 걸러냅니다:
GUID(구독 / 테넌트 / 리소스 / 개체 ID)는 절대 플래그로 표시되지 않습니다.
플레이스홀더 및 비밀이 아닌 값 형태 — ********, null, <provide-at-deploy>, true/false, 반복 문자, 템플릿 토큰(${var}, %VAR%), JSON 객체/배열({...}, [...], 여러 줄 포함), 날짜/타임스탬프, 직렬화된 .NET 형식/컬렉션 이름(예: VM Scale Set의 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 / Bearer 토큰 | 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 | 예 | 정규식입니다. 스캔마다 한 번 컴파일됩니다. |
ValueGroup | 예 | 비밀 값을 담는 캡처 그룹(0 = 전체 일치)입니다. 마스킹을 결정합니다. |
MultiLine | 아니요 | 줄 단위 대신 파일 전체 텍스트에 대해 평가합니다(PEM 블록). 첫 번째 일치뿐만 아니라 모든 일치가 보고됩니다. |
CaseSensitive | 아니요 | 기본 IgnoreCase 컴파일을 사용하지 않으려면 설정합니다. 대소문자를 구분하는 형식(AKIA, ghp_, eyJ, Q~)에 대해 설정하세요. 설정하지 않으면 대소문자가 임의로 다른 유사 항목도 일치합니다. |
Redact | 아니요 | 캡처된 값이 비밀이 아닌 레이블(PEM 헤더 줄, 인증서 파일 이름)인 경우 $false로 설정하여 읽을 수 없게 마스킹하는 대신 원문 그대로 표시되게 합니다. 기본값은 마스킹입니다. |
ForceChangePasswordNextSignInLastPasswordChangeDateTimePasswordExpirationDateTimeInheritedOwners.csvInheritedContributors.csvPasswordGet, List, Set, DeletePermissionsToSecretsStrPermissionsToKeysStr코드 및 템플릿 표현식 — password/secret 등이 리터럴이 아닌 표현식을 가리키는 변수 또는 속성 이름인 경우 캡처된 값은 건너뜁니다: PowerShell cmdlet 호출(Get-RandomPassword 8, Get-AzKeyVaultSecret ...), 범위가 지정된 변수 참조를 포함한 변수 참조($result, $kv.Secrets, $global:clientSecret, $env:KEY), 하위 표현식((-join $x)), ARM / Logic App 참조(@{body(...)}, @body(...), [parameters('...')])입니다. Automation 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 | 꺼짐 | 콘솔 요약을 표시하지 않습니다(객체는 여전히 반환됨). |