Last active
April 6, 2023 22:17
-
-
Save Purp1eW0lf/6bbb2c1e22fe64a151d7ab97be8e83bb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
Meta | |
Date: 2023 January 7th | |
Authors: Harlan Carvey (Twitter @keydet89) and Dray Agha (Twitter @purp1ew0lf) | |
Company: Huntress Labs | |
Purpose: Automate collecting Windows Registry hives, including related .DATs for all users. | |
Notes: | |
Will trigger AV as it's technically credential dumping. | |
Also relies on having internet access, to wget TSCopy | |
Kudos for TrustedSec's TScopy.exe tool, which this script leverages: https://github.com/trustedsec/tscopy | |
#> | |
# check admin | |
function admin_check{ | |
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` | |
[Security.Principal.WindowsBuiltInRole] "Administrator")) { | |
Write-Warning "Insufficient permissions. Run this Powershell script as Admin please" | |
Break | |
} | |
# if we're all good, let's fire it off | |
else {Collect_via_Reg} | |
} | |
# Collect basic hives | |
function Collect_via_Reg{ | |
#print to re-assure user things are happening until ZIP | |
write-host "`n`nHuntress "-NoNewline -ForegroundColor green ; write-host "Registry collection script is running...`n`n"; | |
#Ensure errors don't ruin anything for us | |
$ErrorActionPreference = "SilentlyContinue" | |
$progressPreference = 'silentlyContinue' | |
# Make the various directories, to be neat and tidy | |
mkdir c:\ir, C:\ir\Collected_ntuser_files, C:\ir\Collected_UsrClass_files, C:\ir\amcache | |
# save the registry files | |
reg save HKLM\Software c:\ir\Software | |
reg save HKLM\System c:\ir\System | |
reg save HKLM\SECURITY c:\ir\SECURITY | |
reg save HKLM\SAM C:\ir\SAM | |
#Next Stage | |
Collect_via_TSCopy | |
} | |
## TSCopy for further registry hives | |
function Collect_via_TSCopy{ | |
# pull TScropy exe this way, because invoke-webrequests progress bar is slow and I am a bad scripter | |
(New-Object Net.WebClient).DownloadFile("https://github.com/trustedsec/tscopy/raw/master/dist/TScopy_x64.exe", "C:\ir\TScopy_x64.exe"); | |
# each user's ntuser.dat | |
C:\ir\TScopy_x64.exe -f c:\users\*\ntuser.dat* -o C:\ir\Collected_ntuser_files | |
# each user's usrclass.dat | |
C:\ir\TScopy_x64.exe -f C:\Users\*\AppData\Local\Microsoft\Windows\UsrClass.dat* -o C:\ir\Collected_UsrClass_files | |
# collect amcache hive | |
C:\ir\TScopy_x64.exe -f C:\Windows\AppCompat\Programs\Amcache.hve -o C:\ir\amcache | |
# Next stage | |
Zip_Collected | |
} | |
# zip it all up | |
function Zip_Collected{ | |
#Delete excess files | |
rm C:\IR\TScopy_x64.exe | |
#Tree for a directory map | |
tree C:\IR /f >> C:\IR\tree_output.txt | |
# Get current user's desktop to save zip to. | |
$DesktopPath = [Environment]::GetFolderPath("Desktop") | |
Get-ChildItem -Path C:\ir | Compress-Archive -DestinationPath $DesktopPath\Registry_Collection_$(Get-Date -UFormat "%Y_%b_%d_%a_UTC%Z").zip | |
write-host "`n`nYour ZIP is waiting at: "-NoNewline; write-host "$DesktopPath\Registry_Collection_$(Get-Date -UFormat "%Y_%b_%d_%a_UTC%Z").zip`n`n" -ForegroundColor green ; | |
# Clean up C:\IR on host after ZIP | |
Remove-Item "C:\IR" -Recurse -force | |
# Open up dir | |
sleep 2; ii "$DesktopPath\Registry_Collection_$(Get-Date -UFormat "%Y_%b_%d_%a_UTC%Z").zip" | |
} | |
#Execute main function in silence | |
Admin_Check | out-null |
Per SC-72825, here is a revision of this script, with just small quality-of-life improvements.
You can remove the need for the Administrator check with the #Requires -RunAsAdministrator
tag in modern versions of PowerShell. I've added the traditional "command-line help" docstrings, added some extra color and verbose output (default, but it can be silenced) alongside customizable parameters, so if a support member is helping a partner, they could be suggested to run with other locations or registry hives to pull. This does still download TSCopyx64.exe
. I'm also thinking what else we could do to avoid that (embed the file? It's 4 MB... rewrite TSCopy in PowerShell..?) but I figure these enhancements are worth sharing in the interim.
<#
.SYNOPSIS
Rapid incident response collection script.
.DESCRIPTION
Automate collecting Windows Registry hives, including related .DATs for all users.
.EXAMPLE
./Registry_Collect.ps1
.EXAMPLE
./Registry_Collect.ps1 -CollectionDir "C:\CollectedData" -ExportRegHives @("HKLM\SAM", "HKLM\SYSTEM") -$CollectionGlobs @("C:\Windows\AppCompat\Programs\Amcache.hve") -Quiet
.NOTES
File Name: Registry_Collect.ps1
Author: Huntress Labs, Harlan Carvey (@keydet89), Dray Agha (@purp1ew0lf)
Date: 2023 January 7th
Requires: PowerShell 4.0+
This script requires administrator privileges to run. Execution will likely trigger antivirus
as this code does perform credential dumping techniques.
#>
#Requires -RunAsAdministrator
param (
[string[]]$ExportRegHives = @(
"HKLM\SOFTWARE",
"HKLM\System",
"HKLM\SECURITY",
"HKLM\SAM"
),
[string[]]$CollectionGlobs = @(
"C:\Users\*\NTUser.dat*",
"C:\Users\*\AppData\Local\Microsoft\Windows\UsrClass.dat*",
"C:\Windows\AppCompat\Programs\Amcache.hve"
),
[string]$CollectionDir="$env:SystemDrive\IR",
[switch]$Quiet
)
function Status-Update([string] $message, [switch]$NoNewLine){
if ($Quiet) {
return
}
Write-Host "[*] "-NoNewline -ForegroundColor Blue;
$color_index=0;
$message -Split "'" | ForEach {
if ($color_index % 2 -ne 0){
Write-Host "`'$_`'" -NoNewline -ForegroundColor Yellow
}else{
Write-Host $_ -NoNewline
}
$color_index++
}
Write-Host ""
}
Write-Host "Huntress "-NoNewline -ForegroundColor Cyan
Write-Host "IR collection script v0.1.0"
New-Item $CollectionDir -ItemType Directory -Force | Out-Null
# Collect registry hives
ForEach ($regHive in $ExportRegHives ){
$HiveName=$($regHive -Split "\\")[-1]
Status-Update "exporting registry hive '$regHive'"
& $env:SystemRoot\System32\reg.exe save $regHive ${CollectionDir}\$HiveName /Y | Out-Null
}
# Download TSCopy
$TSCopyx64URL = "https://github.com/trustedsec/tscopy/raw/master/dist/TScopy_x64.exe"
$TSCopyx64Localfile= [System.IO.Path]::GetTempPath() + "TScopy_x64.exe"
Status-Update "downloading TSCopy to '$TSCopyx64Localfile'... " -NoNewLine
$Global:ProgressPreference = 'silentlyContinue'
Invoke-WebRequest $TSCopyx64URL -OutFile $TSCopyx64Localfile
# Collect given files
ForEach ($collectPath in $CollectionGlobs ){
$folderName=($collectPath).Split("\\")[-1].Split(".")[0].Replace("*","")
$outputDir="${CollectionDir}\Collected_${folderName}_Files"
New-Item $outputDir -ItemType Directory -Force | Out-Null
Status-Update "collecting '$collectPath'"
& $TSCopyx64Localfile -f $collectPath -o $outputDir | Out-Null
}
& $env:SystemRoot\System32\tree.com $CollectionDir /f | Out-File "$CollectionDir\tree_output.txt"
$DesktopPath = [Environment]::GetFolderPath("Desktop")
$ZIPLocation = "$DesktopPath\Registry_Collection_$(Get-Date -UFormat "%Y_%b_%d_%a_UTC%Z").zip"
Status-Update "zipping up all collected files..."
Get-ChildItem -Path $CollectionDir | Compress-Archive -DestinationPath $ZIPLocation -Force
# Clean up the collection directory.
Remove-Item $CollectionDir -Recurse -force
Status-Update "removing '$TSCopyx64Localfile'"
Remove-Item $TSCopyx64Localfile
Write-Host "[+] success! collection saved at: `n$ZIPLocation" -ForegroundColor Green
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Download and run: