Windows/TestHarnesses/T1055_ProcessInjection/ProcessHerpderp.Tests.ps1
Set-StrictMode -Version Latest $TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent $ModuleRoot = Resolve-Path "$TestScriptRoot\..\..\..\" $ModuleManifest = "$ModuleRoot\AtomicTestHarnesses.psd1" Remove-Module [A]tomicTestHarnesses Import-Module $ModuleManifest -Force -ErrorAction Stop if (([IntPtr]::Size -eq 8)) { Describe 'Start-ATHProcessHerpaderp' { BeforeAll { $Help = Get-Help -Name Start-ATHProcessHerpaderp -Full $ExpectedTechniqueID = $null if ($Help.Synopsis.Split("`r`n")[-1] -match '^(?-i:Technique ID: )(?<TechniqueID>\S+) (?<TechniqueDescription>\(.+\))$') { $ExpectedTechniqueID = $Matches['TechniqueID'] } } Context 'Validating error conditions' -Tag 'Unit', 'T1055' { It 'should fail to process a non-existent source file' -Tag 'Unit', 'T1055' { { Start-ATHProcessHerpaderp -SourceFilePath "$env:SystemDrive\IDONOTEXIST.exe" -ErrorAction Stop } | Should -Throw } It 'should fail to process a non-existent replacement file' -Tag 'Unit', 'T1055' { { Start-ATHProcessHerpaderp -ReplacementFilePath "$env:SystemDrive\IDONOTEXIST.exe" -ErrorAction Stop } | Should -Throw } It 'should not process a source file that is not a portable executable (PE) file' -Tag 'Unit', 'T1055' { { Start-ATHProcessHerpaderp -SourceFilePath $MyInvocation.MyCommand.Path -ErrorAction Stop } | Should -Throw } It 'should not process a replacement file that is not a portable executable (PE) file' -Tag 'Unit', 'T1055' { { Start-ATHProcessHerpaderp -ReplacementFilePath $MyInvocation.MyCommand.Path -ErrorAction Stop } | Should -Throw } It 'should not process a source file that is larger than the replacement file' -Tag 'Unit', 'T1055' { { Start-ATHProcessHerpaderp -SourceFilePath "$Env:windir\System32\SnippingTool.exe" -ReplacementFilePath "$Env:windir\System32\cmd.exe" -ErrorAction Stop } | Should -Throw } It 'should not process a 32-bit source file' -Tag 'Unit', 'T1055' { { Start-ATHProcessHerpaderp -SourceFilePath "$Env:windir\SysWOW64\cmd.exe" -ErrorAction Stop } | Should -Throw } It 'should not process a 32-bit replacement file' -Tag 'Unit', 'T1055' { { Start-ATHProcessHerpaderp -ReplacementFilePath "$Env:windir\SysWOW64\cmd.exe" -ErrorAction Stop } | Should -Throw } } Context 'Expected artifacts and behaviors when exercising the attack technique' -Tag 'Technique', 'T1055' { BeforeAll { $Script:FixedTestGuid = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' } It 'should execute without any arguments' -Tag 'Technique', 'T1055' { $Result = Start-ATHProcessHerpaderp -TestGuid $FixedTestGuid $Result | Should -Not -BeNullOrEmpty $Result.TechniqueID | Should -BeExactly $ExpectedTechniqueID $Result.TestSuccess | Should -BeTrue $Result.TestGuid | Should -BeExactly $FixedTestGuid $Result.ExecutionType | Should -BeExactly 'File' $Result.SourceExecutableFilePath | Should -BeExactly "$PWD\test_executable.exe" $Result.SourceExecutableFileHash | Should -Not -BeNullOrEmpty $Result.ReplacementExecutableFilePath | Should -BeExactly "$Env:windir\System32\SnippingTool.exe" $Result.ReplacementExecutableFileHash | Should -Not -BeNullOrEmpty $Result.TargetExecutablePath | Should -BeExactly "$PWD\target.exe" $Result.ProcessId | Should -Not -BeNullOrEmpty $Result.ProcessPath | Should -BeExactly 'target.exe' $Result.ProcessCommandLine | Should -BeExactly '"target.exe"' $Result.ProcessModule | Should -Not -BeNullOrEmpty $Result.ProcessMainThread | Should -Not -BeNullOrEmpty $Result.ParentProcessId | Should -Be $PID $Result.ParentProcessPath | Should -Not -BeNullOrEmpty $Result.ParentProcessCommandLine | Should -Not -BeNullOrEmpty $Result.ChildProcessId | Should -Not -BeNullOrEmpty $Result.ChildProcessCommandLine | Should -Match $FixedTestGuid } It 'should execute from the current PowerShell process specifying source and replacement executables on disk' -Tag 'Technique', 'T1055' { $Result = Start-ATHProcessHerpaderp -SourceFilePath "$Env:windir\System32\cmd.exe" -ReplacementFilePath "$Env:windir\System32\SnippingTool.exe" -TargetFilePath herp.exe -CommandLine 'User-supplied cmdline' -TestGuid $FixedTestGuid $Result | Should -Not -BeNullOrEmpty $Result.TechniqueID | Should -BeExactly $ExpectedTechniqueID $Result.TestSuccess | Should -BeNullOrEmpty $Result.TestGuid | Should -BeExactly $FixedTestGuid $Result.ExecutionType | Should -BeExactly 'File' $Result.SourceExecutableFilePath | Should -BeExactly "$Env:windir\System32\cmd.exe" $Result.SourceExecutableFileHash | Should -Not -BeNullOrEmpty $Result.ReplacementExecutableFilePath | Should -BeExactly "$Env:windir\System32\SnippingTool.exe" $Result.ReplacementExecutableFileHash | Should -Not -BeNullOrEmpty $Result.TargetExecutablePath | Should -BeExactly "$PWD\herp.exe" $Result.ProcessId | Should -Not -BeNullOrEmpty $Result.ProcessPath | Should -BeExactly 'herp.exe' $Result.ProcessCommandLine | Should -BeExactly 'User-supplied cmdline' $Result.ProcessModule | Should -Not -BeNullOrEmpty $Result.ProcessMainThread | Should -Not -BeNullOrEmpty $Result.ParentProcessId | Should -Be $PID $Result.ParentProcessPath | Should -Not -BeNullOrEmpty $Result.ParentProcessCommandLine | Should -Not -BeNullOrEmpty $Result.ChildProcessId | Should -BeNullOrEmpty $Result.ChildProcessCommandLine | Should -BeNullOrEmpty # Kill the spawned cmd.exe process Stop-Process -Id $Result.ProcessId -ErrorAction SilentlyContinue } It 'should execute as a child of the explorer.exe process specifying source and replacement executables on disk' -Tag 'Technique', 'T1055' { $ExplorerProcess = Get-Process -Name explorer | Select-Object -First 1 $ExplorerProcess | Should -Not -BeNullOrEmpty $Result = $ExplorerProcess | Start-ATHProcessHerpaderp -SourceFilePath "$Env:windir\System32\cmd.exe" -ReplacementFilePath "$Env:windir\System32\SnippingTool.exe" -TargetFilePath herp.exe -CommandLine 'User-supplied cmdline' -TestGuid $FixedTestGuid $Result | Should -Not -BeNullOrEmpty $Result.TechniqueID | Should -BeExactly $ExpectedTechniqueID $Result.TestSuccess | Should -BeNullOrEmpty $Result.TestGuid | Should -BeExactly $FixedTestGuid $Result.ExecutionType | Should -BeExactly 'File' $Result.SourceExecutableFilePath | Should -BeExactly "$Env:windir\System32\cmd.exe" $Result.SourceExecutableFileHash | Should -Not -BeNullOrEmpty $Result.ReplacementExecutableFilePath | Should -BeExactly "$Env:windir\System32\SnippingTool.exe" $Result.ReplacementExecutableFileHash | Should -Not -BeNullOrEmpty $Result.TargetExecutablePath | Should -BeExactly "$PWD\herp.exe" $Result.ProcessId | Should -Not -BeNullOrEmpty $Result.ProcessPath | Should -BeExactly 'herp.exe' $Result.ProcessCommandLine | Should -BeExactly 'User-supplied cmdline' $Result.ProcessModule | Should -Not -BeNullOrEmpty $Result.ProcessMainThread | Should -Not -BeNullOrEmpty $Result.ParentProcessId | Should -Be $ExplorerProcess.Id $Result.ParentProcessPath | Should -Not -BeNullOrEmpty $Result.ParentProcessCommandLine | Should -Not -BeNullOrEmpty $Result.ChildProcessId | Should -BeNullOrEmpty $Result.ChildProcessCommandLine | Should -BeNullOrEmpty # Kill the spawned cmd.exe process Stop-Process -Id $Result.ProcessId -ErrorAction SilentlyContinue } It 'should execute from the current PowerShell process specifying source and replacement executables as byte arrays' -Tag 'Technique', 'T1055' { $SourceBytes = [IO.File]::ReadAllBytes("$Env:windir\System32\cmd.exe") $ReplacementBytes = [IO.File]::ReadAllBytes("$Env:windir\System32\SnippingTool.exe") $Result = Start-ATHProcessHerpaderp -SourceFileBytes $SourceBytes -ReplacementFileBytes $ReplacementBytes -TargetFilePath herp.exe -CommandLine 'User-supplied cmdline' -TestGuid $FixedTestGuid $Result | Should -Not -BeNullOrEmpty $Result.TechniqueID | Should -BeExactly $ExpectedTechniqueID $Result.TestSuccess | Should -BeNullOrEmpty $Result.TestGuid | Should -BeExactly $FixedTestGuid $Result.ExecutionType | Should -BeExactly 'Memory' $Result.SourceExecutableFilePath | Should -BeNullOrEmpty $Result.SourceExecutableFileHash | Should -Not -BeNullOrEmpty $Result.ReplacementExecutableFilePath | Should -BeNullOrEmpty $Result.ReplacementExecutableFileHash | Should -Not -BeNullOrEmpty $Result.TargetExecutablePath | Should -BeExactly "$PWD\herp.exe" $Result.ProcessId | Should -Not -BeNullOrEmpty $Result.ProcessPath | Should -BeExactly 'herp.exe' $Result.ProcessCommandLine | Should -BeExactly 'User-supplied cmdline' $Result.ProcessModule | Should -Not -BeNullOrEmpty $Result.ProcessMainThread | Should -Not -BeNullOrEmpty $Result.ParentProcessId | Should -Be $PID $Result.ParentProcessPath | Should -Not -BeNullOrEmpty $Result.ParentProcessCommandLine | Should -Not -BeNullOrEmpty $Result.ChildProcessId | Should -BeNullOrEmpty $Result.ChildProcessCommandLine | Should -BeNullOrEmpty # Kill the spawned cmd.exe process Stop-Process -Id $Result.ProcessId -Force -ErrorAction SilentlyContinue } It 'should execute as a child of the explorer.exe process specifying source and replacement executables as byte arrays' -Tag 'Technique', 'T1055' { $ExplorerProcess = Get-Process -Name explorer | Select-Object -First 1 $ExplorerProcess | Should -Not -BeNullOrEmpty $SourceBytes = [IO.File]::ReadAllBytes("$Env:windir\System32\cmd.exe") $ReplacementBytes = [IO.File]::ReadAllBytes("$Env:windir\System32\SnippingTool.exe") $Result = $ExplorerProcess | Start-ATHProcessHerpaderp -SourceFileBytes $SourceBytes -ReplacementFileBytes $ReplacementBytes -TargetFilePath herp.exe -CommandLine 'User-supplied cmdline' -TestGuid $FixedTestGuid $Result | Should -Not -BeNullOrEmpty $Result.TechniqueID | Should -BeExactly $ExpectedTechniqueID $Result.TestSuccess | Should -BeNullOrEmpty $Result.TestGuid | Should -BeExactly $FixedTestGuid $Result.ExecutionType | Should -BeExactly 'Memory' $Result.SourceExecutableFilePath | Should -BeNullOrEmpty $Result.SourceExecutableFileHash | Should -Not -BeNullOrEmpty $Result.ReplacementExecutableFilePath | Should -BeNullOrEmpty $Result.ReplacementExecutableFileHash | Should -Not -BeNullOrEmpty $Result.TargetExecutablePath | Should -BeExactly "$PWD\herp.exe" $Result.ProcessId | Should -Not -BeNullOrEmpty $Result.ProcessPath | Should -BeExactly 'herp.exe' $Result.ProcessCommandLine | Should -BeExactly 'User-supplied cmdline' $Result.ProcessModule | Should -Not -BeNullOrEmpty $Result.ProcessMainThread | Should -Not -BeNullOrEmpty $Result.ParentProcessId | Should -Be $ExplorerProcess.Id $Result.ParentProcessPath | Should -Not -BeNullOrEmpty $Result.ParentProcessCommandLine | Should -Not -BeNullOrEmpty $Result.ChildProcessId | Should -BeNullOrEmpty $Result.ChildProcessCommandLine | Should -BeNullOrEmpty # Kill the spawned cmd.exe process Stop-Process -Id $Result.ProcessId -Force -ErrorAction SilentlyContinue } } } } else { Write-Warning "Start-ATHProcessHerpaderp is not designed to operate in a 32-bit environment" Describe 'Start-ATHProcessHerpaderp' { Context 'Validating error conditions' -Tag 'Unit', 'T1055' { It 'should fail to execute in a 32-bit environment' -Tag 'Unit', 'T1055' { { Start-ATHProcessHerpaderp -ErrorAction Stop } | Should -Throw } } } } |