Phase 7: PTRACE_TRACEME (CVE-2019-13272) + xt_compat (CVE-2021-22555)
Two famous 2017-2020-era LPEs to broaden 'THE tool for folks' coverage. Both detect-only initially; exploit ports as follow-ups. ptrace_traceme (CVE-2019-13272 — jannh @ Google P0, Jun 2019): - Famous because works on default-config systems with no user_ns required — locked-down environments were still vulnerable. - kernel_range thresholds: 4.4.182 / 4.9.182 / 4.14.131 / 4.19.58 / 5.0.20 / 5.1.17 / mainline 5.2+ - Exploit shape (deferred): fork → child PTRACE_TRACEME → parent execve setuid binary → child ptrace-injects shellcode → root. - Auditd: flag PTRACE_TRACEME (request 0) — false positives via gdb/strace; tune by exclusion. netfilter_xtcompat (CVE-2021-22555 — Andy Nguyen @ Google P0): - Bug existed since 2.6.19 (2006) — 15 years of latent vuln. Famous for that age + default-config reachability via unprivileged_userns. - kernel_range thresholds: 4.4.266 / 4.9.266 / 4.14.230 / 4.19.185 / 5.4.110 / 5.10.27 / 5.11.10 / mainline 5.12+ - detect() probes user_ns+net_ns clone; locked-down → PRECOND_FAIL. - Exploit shape (deferred): heap massage via msg_msg + sk_buff cross- cache groom → kernel R/W → cred or modprobe_path overwrite. ~400 lines port from Andy's public exploit.c. - Auditd: unshare + iptables-style setsockopt + msgsnd — combined, the canonical exploit footprint. Both wired into iamroot.c, core/registry.h, Makefile. CVES.md rows added with detailed status. Coverage by year now: 2016: dirty_cow 🟢 2019: ptrace_traceme 🔵 2021: pwnkit, overlayfs, netfilter_xtcompat 🟢/🟢/🔵 2022: dirty_pipe, cls_route4 🟢/🔵 2023: entrybleed 🟢 2024: nf_tables 🔵 2026: copy_fail family (×5) 🟢 Module count: 14. Build clean (no warnings).
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* ptrace_traceme_cve_2019_13272 — IAMROOT module
|
||||
*
|
||||
* PTRACE_TRACEME on a parent that subsequently execve's a setuid
|
||||
* binary results in the kernel granting ptrace privileges over the
|
||||
* privileged process to the unprivileged child. Discovered by Jann
|
||||
* Horn (Google Project Zero, June 2019).
|
||||
*
|
||||
* STATUS: 🔵 DETECT-ONLY. Exploit follows jannh's public PoC: fork
|
||||
* a child that does PTRACE_TRACEME pointing at the parent, parent
|
||||
* execve's a chosen setuid binary (e.g., su, pkexec), child then
|
||||
* ptrace-injects shellcode into the now-elevated process.
|
||||
*
|
||||
* Affected: kernels < 5.1.17 mainline. Stable backports varied; the
|
||||
* fix landed in stable as:
|
||||
* 5.1.x : K >= 5.1.17
|
||||
* 5.0.x : K >= 5.0.20 (older LTS — many distros stayed on 4.x)
|
||||
* 4.19.x: K >= 4.19.58
|
||||
* 4.14.x: K >= 4.14.131
|
||||
* 4.9.x : K >= 4.9.182
|
||||
* 4.4.x : K >= 4.4.182
|
||||
*
|
||||
* No exotic preconditions. Doesn't need user_ns. Works on
|
||||
* default-config systems — that's part of why it's famous: even
|
||||
* locked-down environments without unprivileged_userns_clone were
|
||||
* vulnerable.
|
||||
*/
|
||||
|
||||
#include "iamroot_modules.h"
|
||||
#include "../../core/registry.h"
|
||||
#include "../../core/kernel_range.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static const struct kernel_patched_from ptrace_traceme_patched_branches[] = {
|
||||
{4, 4, 182},
|
||||
{4, 9, 182},
|
||||
{4, 14, 131},
|
||||
{4, 19, 58},
|
||||
{5, 0, 20},
|
||||
{5, 1, 17},
|
||||
{5, 2, 0}, /* mainline (5.2-rc) */
|
||||
};
|
||||
|
||||
static const struct kernel_range ptrace_traceme_range = {
|
||||
.patched_from = ptrace_traceme_patched_branches,
|
||||
.n_patched_from = sizeof(ptrace_traceme_patched_branches) /
|
||||
sizeof(ptrace_traceme_patched_branches[0]),
|
||||
};
|
||||
|
||||
static iamroot_result_t ptrace_traceme_detect(const struct iamroot_ctx *ctx)
|
||||
{
|
||||
struct kernel_version v;
|
||||
if (!kernel_version_current(&v)) {
|
||||
fprintf(stderr, "[!] ptrace_traceme: could not parse kernel version\n");
|
||||
return IAMROOT_TEST_ERROR;
|
||||
}
|
||||
|
||||
/* Bug existed since ptrace's inception (early 2.x); anything
|
||||
* pre-LTS-backport is vulnerable. Anything < 4.4 in our range
|
||||
* model defaults to vulnerable since no entry covers it. */
|
||||
if (v.major < 4 || (v.major == 4 && v.minor < 4)) {
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[!] ptrace_traceme: ancient kernel %s — assume VULNERABLE\n",
|
||||
v.release);
|
||||
}
|
||||
return IAMROOT_VULNERABLE;
|
||||
}
|
||||
|
||||
bool patched = kernel_range_is_patched(&ptrace_traceme_range, &v);
|
||||
if (patched) {
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[+] ptrace_traceme: kernel %s is patched\n", v.release);
|
||||
}
|
||||
return IAMROOT_OK;
|
||||
}
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[!] ptrace_traceme: kernel %s in vulnerable range\n", v.release);
|
||||
fprintf(stderr, "[i] ptrace_traceme: no exotic preconditions — works on default config "
|
||||
"(no user_ns required)\n");
|
||||
}
|
||||
return IAMROOT_VULNERABLE;
|
||||
}
|
||||
|
||||
static iamroot_result_t ptrace_traceme_exploit(const struct iamroot_ctx *ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
fprintf(stderr,
|
||||
"[-] ptrace_traceme: exploit not yet implemented in IAMROOT.\n"
|
||||
" Status: 🔵 DETECT-ONLY. Reference: jannh's PoC.\n"
|
||||
" Exploit shape: fork() → child calls PTRACE_TRACEME → parent\n"
|
||||
" execve's a setuid binary (su, pkexec, ping with cap_net_raw,\n"
|
||||
" etc.) → child becomes tracer of the now-privileged process\n"
|
||||
" → ptrace-inject shellcode → root.\n");
|
||||
return IAMROOT_PRECOND_FAIL;
|
||||
}
|
||||
|
||||
static const char ptrace_traceme_auditd[] =
|
||||
"# PTRACE_TRACEME LPE (CVE-2019-13272) — auditd detection rules\n"
|
||||
"# Flag PTRACE_TRACEME (request 0) followed by parent execve of\n"
|
||||
"# a setuid binary. False positives: gdb, strace, debuggers.\n"
|
||||
"-a always,exit -F arch=b64 -S ptrace -F a0=0 -k iamroot-ptrace-traceme\n"
|
||||
"-a always,exit -F arch=b32 -S ptrace -F a0=0 -k iamroot-ptrace-traceme\n";
|
||||
|
||||
const struct iamroot_module ptrace_traceme_module = {
|
||||
.name = "ptrace_traceme",
|
||||
.cve = "CVE-2019-13272",
|
||||
.summary = "PTRACE_TRACEME → setuid binary execve → cred-escalation via ptrace inject",
|
||||
.family = "ptrace_traceme",
|
||||
.kernel_range = "K < 5.1.17, backports: 5.0.20 / 4.19.58 / 4.14.131 / 4.9.182 / 4.4.182",
|
||||
.detect = ptrace_traceme_detect,
|
||||
.exploit = ptrace_traceme_exploit,
|
||||
.mitigate = NULL, /* mitigation: upgrade kernel; OR set ptrace_scope sysctl */
|
||||
.cleanup = NULL,
|
||||
.detect_auditd = ptrace_traceme_auditd,
|
||||
.detect_sigma = NULL,
|
||||
.detect_yara = NULL,
|
||||
.detect_falco = NULL,
|
||||
};
|
||||
|
||||
void iamroot_register_ptrace_traceme(void)
|
||||
{
|
||||
iamroot_register(&ptrace_traceme_module);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* ptrace_traceme_cve_2019_13272 — IAMROOT module registry hook
|
||||
*/
|
||||
|
||||
#ifndef PTRACE_TRACEME_IAMROOT_MODULES_H
|
||||
#define PTRACE_TRACEME_IAMROOT_MODULES_H
|
||||
|
||||
#include "../../core/module.h"
|
||||
|
||||
extern const struct iamroot_module ptrace_traceme_module;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user