Add PowerShell scripts for collecting forensic artifacts: - USB/storage devices, mounted drives, portable devices - Network history and hotspot connections - Recent documents (OpenSavePidlMRU with PIDL parsing) - System info and user enumeration with multiple output modes Includes TODO.md for planned artifacts and updated README.
142 lines
5.1 KiB
PowerShell
142 lines
5.1 KiB
PowerShell
# Get-RecentDocs.ps1
|
|
# Lists recently opened documents from OpenSavePidlMRU registry key
|
|
|
|
param(
|
|
[int]$MaxPerType = 10,
|
|
[switch]$ShowAll
|
|
)
|
|
|
|
Write-Host "=== Recently Opened Documents ===" -ForegroundColor Cyan
|
|
Write-Host "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU"
|
|
|
|
if ($ShowAll) {
|
|
$MaxPerType = [int]::MaxValue
|
|
Write-Host "Showing all entries`n" -ForegroundColor Yellow
|
|
} else {
|
|
Write-Host "Showing top $MaxPerType per type (use -ShowAll or -MaxPerType N to see more)`n" -ForegroundColor Yellow
|
|
}
|
|
|
|
function Convert-PidlMRU {
|
|
param([byte[]]$data)
|
|
|
|
if (-not $data -or $data.Length -lt 10) {
|
|
return ""
|
|
}
|
|
|
|
try {
|
|
# Convert to Unicode string
|
|
$unicodeText = [System.Text.Encoding]::Unicode.GetString($data)
|
|
|
|
# Remove null characters
|
|
$cleaned = $unicodeText -replace '\x00', ''
|
|
|
|
# Try to extract valid file path (Windows path pattern)
|
|
if ($cleaned -match '([A-Z]:\\(?:[^<>:"|?*\x00-\x1F]+\\)*[^<>:"|?*\x00-\x1F\\]+)') {
|
|
return $matches[1]
|
|
}
|
|
|
|
# Extract filename - match only valid filename characters
|
|
# This regex looks for a sequence that starts with alphanumeric and includes a file extension
|
|
if ($cleaned -match '([a-zA-Z0-9][a-zA-Z0-9._\- ]{0,200}\.[a-zA-Z0-9]{1,10})') {
|
|
return $matches[1]
|
|
}
|
|
|
|
# Fallback: filter to printable ASCII only and look for pattern
|
|
$printable = -join ($cleaned.ToCharArray() | Where-Object {
|
|
($_ -ge 32 -and $_ -le 126)
|
|
})
|
|
|
|
# Try again with printable string
|
|
if ($printable -match '([a-zA-Z0-9][a-zA-Z0-9._\- ]{0,200}\.[a-zA-Z0-9]{1,10})') {
|
|
return $matches[1]
|
|
}
|
|
|
|
return ""
|
|
} catch {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
try {
|
|
$mruPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU"
|
|
|
|
if (Test-Path $mruPath) {
|
|
# Get all extension subkeys
|
|
$subKeys = Get-ChildItem -Path $mruPath -ErrorAction SilentlyContinue |
|
|
Sort-Object PSChildName
|
|
|
|
if ($subKeys) {
|
|
$totalFiles = 0
|
|
$totalStored = 0
|
|
|
|
foreach ($subKey in $subKeys) {
|
|
$extension = $subKey.PSChildName
|
|
|
|
$props = Get-ItemProperty -Path $subKey.PSPath -ErrorAction SilentlyContinue
|
|
|
|
# Get MRUListEx for ordering
|
|
if ($props.MRUListEx) {
|
|
$files = @()
|
|
|
|
for ($i = 0; $i -lt $props.MRUListEx.Length - 4; $i += 4) {
|
|
$index = [BitConverter]::ToInt32($props.MRUListEx, $i)
|
|
if ($index -eq -1) { break }
|
|
|
|
$propName = "$index"
|
|
if ($props.$propName) {
|
|
$fileName = Convert-PidlMRU -data $props.$propName
|
|
if ($fileName) {
|
|
$files += $fileName
|
|
}
|
|
}
|
|
}
|
|
|
|
$totalStored += $files.Count
|
|
|
|
# Only show if we found files
|
|
if ($files.Count -gt 0) {
|
|
if ($extension -eq "*") {
|
|
Write-Host "`n--- All File Types ($($files.Count) total) ---" -ForegroundColor Yellow
|
|
} else {
|
|
Write-Host "`n--- .$extension Files ($($files.Count) total) ---" -ForegroundColor Yellow
|
|
}
|
|
|
|
$count = 0
|
|
$displayFiles = $files | Select-Object -First $MaxPerType
|
|
|
|
foreach ($file in $displayFiles) {
|
|
$count++
|
|
$totalFiles++
|
|
Write-Host " $count. $file" -ForegroundColor Green
|
|
}
|
|
|
|
if ($files.Count -gt $MaxPerType) {
|
|
$remaining = $files.Count - $MaxPerType
|
|
Write-Host " ... and $remaining more" -ForegroundColor Gray
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Write-Host "`n=== Summary ===" -ForegroundColor Cyan
|
|
Write-Host "Total stored: $totalStored files" -ForegroundColor Green
|
|
Write-Host "Displayed: $totalFiles files" -ForegroundColor Green
|
|
|
|
if ($totalFiles -eq 0) {
|
|
Write-Host "`nNo readable file paths found in MRU data" -ForegroundColor Gray
|
|
Write-Host "The PIDL binary format may require more advanced parsing" -ForegroundColor Gray
|
|
}
|
|
} else {
|
|
Write-Host "`nNo recent file history found" -ForegroundColor Gray
|
|
}
|
|
|
|
} else {
|
|
Write-Host "`nOpenSavePidlMRU registry key not found" -ForegroundColor Gray
|
|
}
|
|
|
|
} catch {
|
|
Write-Host "Error: $_" -ForegroundColor Red
|
|
}
|
|
|
|
Write-Host "`nNote: PIDL data parsing is limited. For complete analysis, use forensic tools like Registry Explorer" -ForegroundColor Cyan
|