Skip to content

Instantly share code, notes, and snippets.

@Qazeer
Created September 15, 2024 18:49
Show Gist options
  • Save Qazeer/2b90b93dfc21e0987e73302703e4b9e0 to your computer and use it in GitHub Desktop.
Save Qazeer/2b90b93dfc21e0987e73302703e4b9e0 to your computer and use it in GitHub Desktop.
Process the specified input folder to find and execute usnjrnl_rewind.exe on MFT and UsnJrnl CSVs found
<#
.SYNOPSIS
Process the specified input folder to find and execute usnjrnl_rewind.exe on MFT and UsnJrnl CSVs found.
The MFT and UsnJrnl must have been parsed with Eric Zimmerman's MFTEcmd. The specified input folder must contain one (and only one) parsed MFT CSV and one (and only one) parsed UsnJrnl CSV.
Rewinding the UsnJrnl is a technique introduced by CyberCX-DFIR (https://cybercx.com.au/blog/ntfs-usnjrnl-rewind/).
usnjrnl_rewind is a Python tool from CyberCX-DFIR (https://github.com/CyberCX-DFIR/usnjrnl_rewind).
.PARAMETER UsnJrnlRewindBinary
Specify the usnjrnl_rewind.exe binary full path. Can be found on GitHub, with instruction to compile from source using PyInstaller: https://github.com/Qazeer/usnjrnl_rewind_compiled
.PARAMETER InputDir
Specify the folder which contains the parsed MFT and UsnJrnl CSV.
.PARAMETER OutputDir
Specify the folder where the output will be placed.
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true,
Position = 1,
HelpMessage = 'Specify the usnjrnl_rewind binary full path.')]
[String]$UsnJrnlRewindBinary,
[Parameter(Mandatory = $true,
Position = 2,
HelpMessage = 'Specify the folder which contains the parsed MFT and UsnJrnl CSVs.')]
[String]$InputDir,
[Parameter(Mandatory = $true,
Position = 3,
HelpMessage = 'Specify the folder where the output will be placed.')]
[String]$OutputDir
)
try {
# Check if $UsnJrnlRewindBinary exists.
if (-not (Test-Path -Path $UsnJrnlRewindBinary -PathType Leaf)) {
throw "The $UsnJrnlRewindBinary binary does not exist."
}
# Check if $InputDir exists.
if (-not (Test-Path -Path $InputDir -PathType Container)) {
throw "The directory $InputDir does not exist."
}
# Create the $OutputDir path if it does not exist.
if (-not (Test-Path -Path $OutputDir -PathType Container)) {
# Create the directory, but do not prompt for confirmation (-Confirm:$false).
[void] (New-Item -ItemType Directory -Path $OutputDir -Confirm:$false)
}
# Look for the parsed MFT in $InputDir.
$MFTParsed = Get-ChildItem -Path $InputDir -ErrorAction Stop | Where-Object { $_.name -match '.*MFTECmd_\$MFT_Output.*' }
$UsnJrnlParsed = Get-ChildItem -Path $InputDir -ErrorAction Stop | Where-Object { $_.name -match '.*MFTECmd_\$J_Output.*' }
if ($null -eq $MFTParsed -or $MFTParsed.Count -ne 1) {
throw "No or multiple parsed MFT file(s) found in $InputDir. The folder must contain only one parsed MFT CSV."
}
else {
$MFTParsed = $MFTParsed.FullName
}
if ($null -eq $UsnJrnlParsed -or $UsnJrnlParsed.Count -ne 1) {
throw "No or multiple parsed UsnJrnl file(s) found in $InputDir. The folder must contain only one parsed UsnJrnl CSV."
}
else {
$UsnJrnlParsed = $UsnJrnlParsed.FullName
}
$arguments = "-m", "`"$MFTParsed`"", "-u", "`"$UsnJrnlParsed`"", "`"$($OutputDir.Replace('\', '\\'))`""
Write-Host "Command: $UsnJrnlRewindBinary $arguments"
Start-Process -NoNewWindow -Wait $UsnJrnlRewindBinary -ArgumentList $arguments -RedirectStandardOutput "$(Join-Path $OutputDir "usnjrnl_rewind_stdout.log")"
}
catch [System.Exception] {
# If an error occurred, print error details
Write-Error "An error occurred while running this script"
Write-Error "Exception type: $($_.Exception.GetType().FullName)"
Write-Error "Exception message: $($_.Exception.Message)"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment