Skip to content

Commit

Permalink
Adding Start-ATHProcessHerpaderp
Browse files Browse the repository at this point in the history
  • Loading branch information
mgraeber-rc committed Jan 18, 2021
1 parent 2f65db8 commit 22151e2
Show file tree
Hide file tree
Showing 4 changed files with 1,218 additions and 6 deletions.
8 changes: 7 additions & 1 deletion AtomicTestHarnesses.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
RootModule = 'AtomicTestHarnesses.psm1'

# Version number of this module.
ModuleVersion = '1.2.0.0'
ModuleVersion = '1.3.0.0'

# ID used to uniquely identify this module
GUID = '195a1637-d4a4-4cb3-8d80-5b5d4e3e930a'
Expand All @@ -29,6 +29,7 @@ FunctionsToExport = 'Invoke-ATHHTMLApplication',
'Invoke-ATHCompiledHelp',
'Invoke-ATHRemoteFXvGPUDisablementCommand',
'Out-ATHPowerShellCommandLineParameter',
'Start-ATHProcessHerpaderp',
'Start-ATHProcessUnderSpecificParent'

# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
Expand All @@ -47,6 +48,11 @@ PrivateData = @{

# ReleaseNotes of this module
ReleaseNotes = @'
1.3.0
-----
Added:
* Start-ATHProcessHerpaderp
1.2.0
-----
Added:
Expand Down
11 changes: 6 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,12 @@ Specific groups of tests can be run rather than running all available tests. The
1. `Module` - Module-wide tests designed to ensure consistency across all exported fcuntions.
2. `Unit` - Unit tests for exported functions
3. `Technique` - Tests that exercise specific attack technique functionality
4. `T1059.001` - [Command and Scripting Interpreter: PowerShell](https://attack.mitre.org/techniques/T1059/001/)
5. `T1134.004` - [Access Token Manipulation: Parent PID Spoofing](https://attack.mitre.org/techniques/T1134/004/)
6. `T1218.001` - [Signed Binary Proxy Execution: Compiled HTML File](https://attack.mitre.org/techniques/T1218/001/)
7. `T1218` - [Signed Binary Proxy Execution](https://attack.mitre.org/techniques/T1218/)
8. `T1218.005` - [Signed Binary Proxy Execution: Mshta](https://attack.mitre.org/techniques/T1218/005/)
4. `T1055` - [Process Injection](https://attack.mitre.org/techniques/T1055/)
5. `T1059.001` - [Command and Scripting Interpreter: PowerShell](https://attack.mitre.org/techniques/T1059/001/)
6. `T1134.004` - [Access Token Manipulation: Parent PID Spoofing](https://attack.mitre.org/techniques/T1134/004/)
7. `T1218.001` - [Signed Binary Proxy Execution: Compiled HTML File](https://attack.mitre.org/techniques/T1218/001/)
8. `T1218` - [Signed Binary Proxy Execution](https://attack.mitre.org/techniques/T1218/)
9. `T1218.005` - [Signed Binary Proxy Execution: Mshta](https://attack.mitre.org/techniques/T1218/005/)

## Running Tests

Expand Down
222 changes: 222 additions & 0 deletions TestHarnesses/T1055_ProcessInjection/ProcessHerpderp.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
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
}
}
}
}
Loading

0 comments on commit 22151e2

Please sign in to comment.