67 lines
3.4 KiB
PowerShell
67 lines
3.4 KiB
PowerShell
# GreySec PHI Scanner - Targeted WinServer Scan
|
|
$ErrorActionPreference = 'SilentlyContinue'
|
|
$results = @{
|
|
hostname = $env:COMPUTERNAME
|
|
timestamp = (Get-Date).ToString("o")
|
|
total_files_scanned = 0
|
|
findings = @()
|
|
}
|
|
$searchPaths = @('C:\phi_test')
|
|
$exts = @('*.txt','*.csv','*.log','*.json','*.xml','*.sql','*.cfg','*.ini','*.dat')
|
|
$ssnRx = [regex]'\b\d{3}[-\s]\d{2}[-\s]\d{4}\b'
|
|
$mrnRx = [regex]'\b(MRN|Medical Record|EHR|Patient ID)[:\s#]*\d{6,10}\b', [regex]'\b\d{6,10}\b'
|
|
$phoneRx = [regex]'\b(\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b'
|
|
$emailRx = [regex]'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b'
|
|
$dobRx = [regex]'\b(0[1-9]|1[0-2])[/.-](0[1-9]|[12]\d|3[01])[/.-](19|20)\d{2}\b'
|
|
$zip4Rx = [regex]'\b\d{5}[-\s]\d{4}\b'
|
|
$ipRx = [regex]'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b'
|
|
$maxSize = 52428800
|
|
$count = 0
|
|
foreach ($sp in $searchPaths) {
|
|
if (Test-Path $sp) {
|
|
Get-ChildItem -Path $sp -File -Recurse | Where-Object { $_.Length -le $maxSize } | ForEach-Object {
|
|
$content = $_ | Get-Content -Raw -Encoding UTF8
|
|
if ($null -eq $content) { return }
|
|
$fn = $_.FullName
|
|
$count++
|
|
# SSN
|
|
$ssnRx.Matches($content) | ForEach-Object {
|
|
$val = $_.Value
|
|
$ctx = $content.Substring([Math]::Max(0,$_.Index-$30),[Math]::Min(80,$content.Length-$_.Index+$_.Length+30)).Replace("`n"," ").Replace("`r","")
|
|
$results.findings += @{type='SSN';value=$val;file=$fn;context=$ctx}
|
|
}
|
|
# MRN
|
|
$mrnRx | ForEach-Object {
|
|
$_.Matches($content) | Where-Object { $_.Value -notmatch '^\d{10}$' } | ForEach-Object {
|
|
$val = $_.Value
|
|
$ctx = $content.Substring([Math]::Max(0,$_.Index-$30),[Math]::Min(80,$content.Length-$_.Index+$_.Length+30)).Replace("`n"," ").Replace("`r","")
|
|
$results.findings += @{type='MRN';value=$val;file=$fn;context=$ctx}
|
|
}
|
|
}
|
|
# Phone
|
|
$phoneRx.Matches($content) | Where-Object { $_.Value.Length -ge 10 } | ForEach-Object {
|
|
$val = $_.Value
|
|
$ctx = $content.Substring([Math]::Max(0,$_.Index-$30),[Math]::Min(80,$content.Length-$_.Index+$_.Length+30)).Replace("`n"," ").Replace("`r","")
|
|
$results.findings += @{type='Phone';value=$val;file=$fn;context=$ctx}
|
|
}
|
|
# Email
|
|
$emailRx.Matches($content) | ForEach-Object {
|
|
$val = $_.Value
|
|
$ctx = $content.Substring([Math]::Max(0,$_.Index-$30),[Math]::Min(80,$content.Length-$_.Index+$_.Length+30)).Replace("`n"," ").Replace("`r","")
|
|
$results.findings += @{type='Email';value=$val;file=$fn;context=$ctx}
|
|
}
|
|
# DOB
|
|
$dobRx.Matches($content) | ForEach-Object {
|
|
$val = $_.Value
|
|
$ctx = $content.Substring([Math]::Max(0,$_.Index-$30),[Math]::Min(80,$content.Length-$_.Index+$_.Length+30)).Replace("`n"," ").Replace("`r","")
|
|
$results.findings += @{type='DOB';value=$val;file=$fn;context=$ctx}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$results.total_files_scanned = $count
|
|
$json = $results | ConvertTo-Json -Depth 6
|
|
$json | Set-Content -Path 'C:\phi_test\phi_scan_results.json' -Encoding UTF8
|
|
$ssnCount = ($results.findings | Where-Object {$_.type -eq 'SSN'}).Count
|
|
"FINISHED:$count`:$ssnCount"
|