attack_technique: T1218.004
display_name: 'Signed Binary Proxy Execution: InstallUtil'
atomic_tests:
- name: CheckIfInstallable method call
  auto_generated_guid: ffd9c807-d402-47d2-879d-f915cf2a3a94
  description: |
    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
  input_arguments:
    test_harness:
      description: location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly
      type: Path
      default: PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
    assembly_dir:
      description: directory to drop the compiled installer assembly
      type: Path
      default: $Env:TEMP\
    invocation_method:
      description: the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable
      type: String
      default: CheckIfInstallable
    assembly_filename:
      description: filename of the compiled installer assembly
      type: String
      default: T1218.004.dll
  dependencies:
  - description: |
      InstallUtil test harness script must be installed at specified location (#{test_harness})
    prereq_command: |
      if (Test-Path "#{test_harness}") {exit 0} else {exit 1}
    get_prereq_command: |
      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}"
  executor:
    command: |
      # 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_command: |
      $InstallerAssemblyDir = "#{assembly_dir}"
      $InstallerAssemblyFileName = "#{assembly_filename}"
      $InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
      Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore
    name: powershell
- name: InstallHelper method call
  auto_generated_guid: d43a5bde-ae28-4c55-a850-3f4c80573503
  description: |
    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
  input_arguments:
    test_harness:
      description: location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly
      type: Path
      default: PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
    assembly_dir:
      description: directory to drop the compiled installer assembly
      type: Path
      default: $Env:TEMP\
    invocation_method:
      description: the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable
      type: String
      default: InstallHelper
    assembly_filename:
      description: filename of the compiled installer assembly
      type: String
      default: T1218.004.dll
  dependencies:
  - description: |
      InstallUtil test harness script must be installed at specified location (#{test_harness})
    prereq_command: |
      if (Test-Path "#{test_harness}") {exit 0} else {exit 1}
    get_prereq_command: |
      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}"
  executor:
    command: |
      # 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_command: |
      $InstallerAssemblyDir = "#{assembly_dir}"
      $InstallerAssemblyFileName = "#{assembly_filename}"
      $InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
      Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore
    name: powershell
- name: InstallUtil class constructor method call
  auto_generated_guid: 9b7a7cfc-dd2e-43f5-a885-c0a3c270dd93
  description: |
    Executes the installer assembly class constructor. Upon execution, version information will be displayed the .NET framework install utility.
  supported_platforms:
  - windows
  input_arguments:
    test_harness:
      description: location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly
      type: Path
      default: PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
    assembly_dir:
      description: directory to drop the compiled installer assembly
      type: Path
      default: $Env:TEMP\
    invocation_method:
      description: the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable
      type: String
      default: Executable
    assembly_filename:
      description: filename of the compiled installer assembly
      type: String
      default: T1218.004.dll
  dependencies:
  - description: |
      InstallUtil test harness script must be installed at specified location (#{test_harness})
    prereq_command: |
      if (Test-Path "#{test_harness}") {exit 0} else {exit 1}
    get_prereq_command: |
      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}"
  executor:
    command: |
      # 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_command: |
      $InstallerAssemblyDir = "#{assembly_dir}"
      $InstallerAssemblyFileName = "#{assembly_filename}"
      $InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
      Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore
    name: powershell
- name: InstallUtil Install method call
  auto_generated_guid: 9f9968a6-601a-46ca-b7b7-6d4fe0f98f0b
  description: |
    Executes the Install Method. Upon execution, version information will be displayed the .NET framework install utility.
  supported_platforms:
  - windows
  input_arguments:
    test_harness:
      description: location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly
      type: Path
      default: PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
    assembly_dir:
      description: directory to drop the compiled installer assembly
      type: Path
      default: $Env:TEMP\
    invocation_method:
      description: the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable
      type: String
      default: Executable
    assembly_filename:
      description: filename of the compiled installer assembly
      type: String
      default: T1218.004.dll
  dependencies:
  - description: |
      InstallUtil test harness script must be installed at specified location (#{test_harness})
    prereq_command: |
      if (Test-Path "#{test_harness}") {exit 0} else {exit 1}
    get_prereq_command: |
      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}"
  executor:
    command: |
      # 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_command: |
      $InstallerAssemblyDir = "#{assembly_dir}"
      $InstallerAssemblyFileName = "#{assembly_filename}"
      $InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
      Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore
    name: powershell
- name: InstallUtil Uninstall method call - /U variant
  auto_generated_guid: 34428cfa-8e38-41e5-aff4-9e1f8f3a7b4b
  description: |
    Executes the Uninstall Method. Upon execution, version information will be displayed the .NET framework install utility.
  supported_platforms:
  - windows
  input_arguments:
    test_harness:
      description: location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly
      type: Path
      default: PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
    assembly_dir:
      description: directory to drop the compiled installer assembly
      type: Path
      default: $Env:TEMP\
    invocation_method:
      description: the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable
      type: String
      default: Executable
    assembly_filename:
      description: filename of the compiled installer assembly
      type: String
      default: T1218.004.dll
  dependencies:
  - description: |
      InstallUtil test harness script must be installed at specified location (#{test_harness})
    prereq_command: |
      if (Test-Path "#{test_harness}") {exit 0} else {exit 1}
    get_prereq_command: |
      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}"
  executor:
    command: |
      # 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_command: |
      $InstallerAssemblyDir = "#{assembly_dir}"
      $InstallerAssemblyFileName = "#{assembly_filename}"
      $InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
      Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore
    name: powershell
- name: InstallUtil Uninstall method call - '/installtype=notransaction /action=uninstall' variant
  auto_generated_guid: 06d9deba-f732-48a8-af8e-bdd6e4d98c1d
  description: |
    Executes the Uninstall Method. Upon execution, version information will be displayed the .NET framework install utility.
  supported_platforms:
  - windows
  input_arguments:
    test_harness:
      description: location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly
      type: Path
      default: PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
    assembly_dir:
      description: directory to drop the compiled installer assembly
      type: Path
      default: $Env:TEMP\
    invocation_method:
      description: the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable
      type: String
      default: Executable
    assembly_filename:
      description: filename of the compiled installer assembly
      type: String
      default: T1218.004.dll
  dependencies:
  - description: |
      InstallUtil test harness script must be installed at specified location (#{test_harness})
    prereq_command: |
      if (Test-Path "#{test_harness}") {exit 0} else {exit 1}
    get_prereq_command: |
      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}"
  executor:
    command: |
      # 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_command: |
      $InstallerAssemblyDir = "#{assembly_dir}"
      $InstallerAssemblyFileName = "#{assembly_filename}"
      $InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
      Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore
    name: powershell
- name: InstallUtil HelpText method call
  auto_generated_guid: 5a683850-1145-4326-a0e5-e91ced3c6022
  description: |
    Executes the Uninstall Method. Upon execution, help information will be displayed for InstallUtil.
  supported_platforms:
  - windows
  input_arguments:
    test_harness:
      description: location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly
      type: Path
      default: PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
    assembly_dir:
      description: directory to drop the compiled installer assembly
      type: Path
      default: $Env:TEMP\
    invocation_method:
      description: the type of InstallUtil invocation variant - Executable, InstallHelper, or CheckIfInstallable
      type: String
      default: Executable
    assembly_filename:
      description: filename of the compiled installer assembly
      type: String
      default: T1218.004.dll
  dependencies:
  - description: |
      InstallUtil test harness script must be installed at specified location (#{test_harness})
    prereq_command: |
      if (Test-Path "#{test_harness}") {exit 0} else {exit 1}
    get_prereq_command: |
      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}"
  executor:
    command: |
      # 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_command: |
      $InstallerAssemblyDir = "#{assembly_dir}"
      $InstallerAssemblyFileName = "#{assembly_filename}"
      $InstallerAssemblyFullPath = Join-Path -Path $InstallerAssemblyDir -ChildPath $InstallerAssemblyFileName
      Remove-Item -Path $InstallerAssemblyFullPath -ErrorAction Ignore
    name: powershell
- name: InstallUtil evasive invocation
  auto_generated_guid: 559e6d06-bb42-4307-bff7-3b95a8254bad
  description: |
    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
  input_arguments:
    test_harness:
      description: location of the test harness script - Invoke-BuildAndInvokeInstallUtilAssembly
      type: Path
      default: PathToAtomicsFolder\T1218.004\src\InstallUtilTestHarness.ps1
  dependencies:
  - description: |
      InstallUtil test harness script must be installed at specified location (#{test_harness})
    prereq_command: |
      if (Test-Path "#{test_harness}") {exit 0} else {exit 1}
    get_prereq_command: |
      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}"
  executor:
    command: |
      # 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_command: |
      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
    name: powershell

