As a penetration tester or security researcher, discovering sensitive artifacts like DPAPI keys is an essential part of post-exploitation or system analysis. To streamline this process, I’ve developed a PowerShell script that automates the discovery of DPAPI-related paths across user profiles on a Windows machine. This script handles permission issues gracefully and ensures clean, actionable output.
In this post, I’ll share the script, explain its key features, and guide you on how to use it effectively.
C:\Users
and checks for default DPAPI-related paths.Here is the PowerShell script in its entirety:
# Function to check if a directory exists and handle access errors silently
function Check-Directory {
param ([string]$Path)
try {
if (Test-Path -Path $Path -ErrorAction SilentlyContinue) {
return $true
}
} catch {
return $false
}
return $false
}
# Function to scan for DPAPI-related paths
function Scan-DPAPI {
$basePath = "C:\Users"
# Check if base path exists
if (!(Test-Path $basePath -ErrorAction SilentlyContinue)) {
Write-Error "Base path $basePath does not exist!"
return
}
# Get all user directories
$userDirs = Get-ChildItem -Path $basePath -Directory -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
# List of DPAPI-related paths to check for each user
$pathsToCheck = @(
"\AppData\Roaming\Microsoft\Protect", # User-specific DPAPI Master Keys
"\AppData\Local\Microsoft\Credentials", # Windows Credential Manager
"\AppData\Roaming\Microsoft\Vault", # Credential Vault
"\AppData\Local\Microsoft\Edge\User Data", # Microsoft Edge Data
"\AppData\Roaming\Microsoft\Internet Explorer" # Internet Explorer Data
)
# Scan each user directory
foreach ($userDir in $userDirs) {
Write-Host "Scanning user directory: $userDir" -ForegroundColor Cyan
try {
# Ensure we can access the user directory
if (!(Test-Path $userDir -ErrorAction SilentlyContinue)) {
Write-Warning "No permissions on directory of user: $userDir"
continue
}
foreach ($subPath in $pathsToCheck) {
$fullPath = Join-Path -Path $userDir -ChildPath $subPath
if (Check-Directory -Path $fullPath) {
Write-Host "Found DPAPI-related path: $fullPath" -ForegroundColor Green
}
}
} catch {
Write-Warning "No permissions on directory of user: $userDir"
}
}
# Check system-wide DPAPI paths
$systemPaths = @(
"C:\Windows\System32\Microsoft\Protect" # System-Wide DPAPI Keys
)
Write-Host "Scanning system-wide paths..." -ForegroundColor Yellow
foreach ($sysPath in $systemPaths) {
if (Check-Directory -Path $sysPath) {
Write-Host "Found DPAPI-related path: $sysPath" -ForegroundColor Green
} else {
Write-Warning "No permissions or path not accessible: $sysPath"
}
}
}
# Run the DPAPI scan
Scan-DPAPI
C:\Users
directory for all user profiles.Microsoft\Protect
and Microsoft\Vault
).C:\Windows\System32\Microsoft\Protect
..ps1
file (e.g., ScanDPAPI.ps1
)..\ScanDPAPI.ps1
Scanning user directory: C:\Users\Administrator
Scanning user directory: C:\Users\C.Neri
Found DPAPI-related path: C:\Users\C.Neri\AppData\Roaming\Microsoft\Protect
Found DPAPI-related path: C:\Users\C.Neri\AppData\Local\Microsoft\Credentials
Found DPAPI-related path: C:\Users\C.Neri\AppData\Roaming\Microsoft\Vault
Found DPAPI-related path: C:\Users\C.Neri\AppData\Local\Microsoft\Edge\User Data
Found DPAPI-related path: C:\Users\C.Neri\AppData\Roaming\Microsoft\Internet Explorer
Scanning user directory: C:\Users\c.neri_adm
Scanning user directory: C:\Users\Public
Scanning system-wide paths...
Found DPAPI-related path: C:\Windows\System32\Microsoft\Protect