v0.3.1: --dump-offsets tool + NOTICE.md per module
release / build (arm64) (push) Waiting to run
release / build (x86_64) (push) Waiting to run
release / release (push) Blocked by required conditions

The README has been claiming "each module credits the original CVE
reporter and PoC author in its NOTICE.md" since v0.1.0, but only
copy_fail_family actually shipped one. Fixed.

  modules/<name>/NOTICE.md (×19 new + 1 existing): per-module
    research credit covering CVE ID, discoverer, original advisory
    URL where public, upstream fix commit, IAMROOT's role.

  iamroot.c: new --dump-offsets subcommand. Resolves kernel offsets
    via the existing core/offsets.c four-source chain (env →
    /proc/kallsyms → /boot/System.map → embedded table), then emits
    a ready-to-paste C struct entry for kernel_table[]. Run once
    as root on a target kernel build; upstream via PR. Eliminates
    fabricating offsets — every shipped entry traces back to a
    `iamroot --dump-offsets` invocation on a real kernel.

  docs/OFFSETS.md: documents the --dump-offsets workflow.
  CVES.md: notes the NOTICE.md convention + offset dump tool.

  iamroot.c: bump IAMROOT_VERSION 0.3.0 → 0.3.1.
This commit is contained in:
2026-05-16 22:33:43 -04:00
parent 1bcfdd0c9f
commit 9d88b475c1
22 changed files with 676 additions and 2 deletions
+6 -1
View File
@@ -23,7 +23,12 @@ Status legend:
- 🔴 **DEPRECATED** — fully patched everywhere relevant; kept for
historical reference only
**Counts (v0.3.0):** 🟢 13 · 🟡 11 (all `--full-chain` capable) · 🔵 0 · ⚪ 1 · 🔴 0
**Counts (v0.3.1):** 🟢 13 · 🟡 11 (all `--full-chain` capable) · 🔵 0 · ⚪ 1 · 🔴 0
Every module ships a `NOTICE.md` crediting the original CVE
reporter and PoC author. `iamroot --dump-offsets` populates the
embedded offset table for new kernel builds — operators with
root on a host can upstream their kernel's offsets via PR.
## Inventory
+27
View File
@@ -64,6 +64,33 @@ IAMROOT_MODPROBE_PATH=0xffffffff8228e7e0 \
iamroot --exploit nf_tables --i-know --full-chain
```
### Automated dump (preferred for upstreaming)
`iamroot --dump-offsets` walks the four-source chain itself and emits
a ready-to-paste C struct entry on stdout:
```bash
sudo iamroot --dump-offsets
# /* Generated 2026-05-16 by `iamroot --dump-offsets`.
# * Host kernel: 5.15.0-56-generic distro=ubuntu
# * Resolved fields: modprobe_path=kallsyms init_task=kallsyms cred=table
# * Paste this entry into kernel_table[] in core/offsets.c.
# */
# { .release_glob = "5.15.0-56-generic",
# .distro_match = "ubuntu",
# .rel_modprobe_path = 0x148e480,
# .rel_poweroff_cmd = 0x148e3a0,
# .rel_init_task = 0x1c11dc0,
# .rel_init_cred = 0x1e0c460,
# .cred_offset_real = 0x738,
# .cred_offset_eff = 0x740,
# },
```
Paste the block into `kernel_table[]` in `core/offsets.c`, rebuild,
and the new entry covers every IAMROOT user on that kernel. Open a
PR to upstream it.
### Per-host (write System.map readable)
```bash
+110 -1
View File
@@ -17,6 +17,9 @@
#include "core/module.h"
#include "core/registry.h"
#include "core/offsets.h"
#include <time.h>
#include <getopt.h>
#include <stdbool.h>
@@ -25,7 +28,7 @@
#include <string.h>
#include <unistd.h>
#define IAMROOT_VERSION "0.3.0"
#define IAMROOT_VERSION "0.3.1"
static const char BANNER[] =
"\n"
@@ -57,6 +60,11 @@ static void usage(const char *prog)
" files in /etc, file capabilities, sudo NOPASSWD\n"
" (complements --scan; answers 'is this box\n"
" generally privesc-exposed?')\n"
" --dump-offsets walk /proc/kallsyms + /boot/System.map and emit a\n"
" C struct-entry ready to paste into core/offsets.c's\n"
" kernel_table[] for the --full-chain finisher.\n"
" Needs root (or kernel.kptr_restrict=0) to read\n"
" kallsyms. See docs/OFFSETS.md.\n"
" --version print version\n"
" --help this message\n"
"\n"
@@ -89,6 +97,7 @@ enum mode {
MODE_DETECT_RULES,
MODE_MODULE_INFO,
MODE_AUDIT,
MODE_DUMP_OFFSETS,
MODE_HELP,
MODE_VERSION,
};
@@ -428,6 +437,103 @@ static int cmd_audit(const struct iamroot_ctx *ctx)
return 0;
}
/* --dump-offsets: walk /proc/kallsyms + /boot/System.map for the running
* kernel and emit a ready-to-paste C struct entry for kernel_table[] in
* core/offsets.c. Operators run this once on a kernel they have root on
* (or kptr_restrict=0), then upstream the entry so --full-chain works
* out-of-the-box on that build for everyone. */
static int cmd_dump_offsets(const struct iamroot_ctx *ctx)
{
(void)ctx;
struct iamroot_kernel_offsets off;
int n = iamroot_offsets_resolve(&off);
if (off.kbase == 0) {
fprintf(stderr,
"[-] dump-offsets: couldn't resolve a kernel base address.\n"
"\n"
" /proc/kallsyms returned all-zero addresses (kptr_restrict is\n"
" enforcing). /boot/System.map-%s wasn't readable either.\n"
"\n"
" Try one of:\n"
" sudo iamroot --dump-offsets\n"
" sudo sysctl kernel.kptr_restrict=0; iamroot --dump-offsets\n"
" sudo chmod 0644 /boot/System.map-$(uname -r); iamroot --dump-offsets\n",
off.kernel_release[0] ? off.kernel_release : "$(uname -r)");
return 1;
}
if (n == 0) {
fprintf(stderr,
"[-] dump-offsets: kbase resolved but no symbols. Sources tried: env,\n"
" /proc/kallsyms, /boot/System.map. Check that the kernel symbols\n"
" you need (modprobe_path / init_task / poweroff_cmd) actually exist\n"
" in the symbol files.\n");
return 1;
}
time_t now = time(NULL);
struct tm tm; localtime_r(&now, &tm);
fprintf(stdout,
"/* Generated %04d-%02d-%02d by `iamroot --dump-offsets`.\n"
" * Host kernel: %s%s%s\n"
" * Resolved fields: modprobe_path=%s init_task=%s cred=%s\n"
" * Paste this entry into kernel_table[] in core/offsets.c.\n"
" */\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
off.kernel_release,
off.distro[0] ? " distro=" : "",
off.distro[0] ? off.distro : "",
iamroot_offset_source_name(off.source_modprobe),
iamroot_offset_source_name(off.source_init_task),
iamroot_offset_source_name(off.source_cred));
fprintf(stdout,
"{ .release_glob = \"%s\",\n", off.kernel_release);
if (off.distro[0]) {
fprintf(stdout,
" .distro_match = \"%s\",\n", off.distro);
} else {
fprintf(stdout,
" .distro_match = NULL,\n");
}
if (off.modprobe_path) {
fprintf(stdout,
" .rel_modprobe_path = 0x%lx,\n",
(unsigned long)(off.modprobe_path - off.kbase));
}
if (off.poweroff_cmd) {
fprintf(stdout,
" .rel_poweroff_cmd = 0x%lx,\n",
(unsigned long)(off.poweroff_cmd - off.kbase));
}
if (off.init_task) {
fprintf(stdout,
" .rel_init_task = 0x%lx,\n",
(unsigned long)(off.init_task - off.kbase));
}
if (off.init_cred) {
fprintf(stdout,
" .rel_init_cred = 0x%lx,\n",
(unsigned long)(off.init_cred - off.kbase));
}
if (off.cred_offset_real) {
fprintf(stdout,
" .cred_offset_real = 0x%x,\n", off.cred_offset_real);
}
if (off.cred_offset_eff) {
fprintf(stdout,
" .cred_offset_eff = 0x%x,\n", off.cred_offset_eff);
}
fprintf(stdout,
"},\n");
fprintf(stderr,
"\n[+] dumped %d resolved fields. Verify offsets, then upstream this\n"
" entry via a PR to https://github.com/KaraZajac/IAMROOT.\n", n);
return 0;
}
/* --module-info <name>: dump everything we know about one module.
* Human-readable by default, JSON with --json. Includes the full
* detection-rule text bodies for that module. */
@@ -610,6 +716,7 @@ int main(int argc, char **argv)
{"detect-rules", no_argument, 0, 'D'},
{"module-info", required_argument, 0, 'I'},
{"audit", no_argument, 0, 'A'},
{"dump-offsets", no_argument, 0, 8 },
{"format", required_argument, 0, 6 },
{"i-know", no_argument, 0, 1 },
{"active", no_argument, 0, 2 },
@@ -639,6 +746,7 @@ int main(int argc, char **argv)
case 4 : ctx.json = true; break;
case 5 : ctx.no_color = true; break;
case 7 : ctx.full_chain = true; break;
case 8 : mode = MODE_DUMP_OFFSETS; break;
case 6 :
if (strcmp(optarg, "auditd") == 0) dr_fmt = FMT_AUDITD;
else if (strcmp(optarg, "sigma") == 0) dr_fmt = FMT_SIGMA;
@@ -665,6 +773,7 @@ int main(int argc, char **argv)
if (mode == MODE_MODULE_INFO) return cmd_module_info(target, &ctx);
if (mode == MODE_DETECT_RULES) return cmd_detect_rules(dr_fmt);
if (mode == MODE_AUDIT) return cmd_audit(&ctx);
if (mode == MODE_DUMP_OFFSETS) return cmd_dump_offsets(&ctx);
/* --exploit / --mitigate / --cleanup all take a target */
if (target == NULL) {
@@ -0,0 +1,28 @@
# NOTICE — af_packet2 (CVE-2020-14386)
## Vulnerability
**CVE-2020-14386** — AF_PACKET `tpacket_rcv` VLAN integer underflow
(`maclen = skb_network_offset(skb)` when network header precedes
maclen) → 8-byte heap OOB write at the start of the next slab object.
## Research credit
Discovered and disclosed by **Or Cohen** (Palo Alto Networks),
September 2020.
Original advisory: <https://unit42.paloaltonetworks.com/cve-2020-14386/>
Upstream fix: mainline 5.9 / stable 5.8.7 (Sept 2020).
Branch backports: 5.8.7 / 5.7.16 / 5.4.62 / 4.19.143 / 4.14.197 / 4.9.235.
## IAMROOT role
Sibling of CVE-2017-7308; same subsystem, different code path.
Fires the underflow via `tp_reserve` + sendmmsg sk_buff spray.
PRIMITIVE-DEMO scope by default (no cred overwrite). `--full-chain`
attempts the Or-Cohen-style sk_buff data-pointer hijack through
the shared finisher.
Shares the `iamroot-af-packet` auditd key with the CVE-2017-7308
module so detection signatures dedupe cleanly.
+29
View File
@@ -0,0 +1,29 @@
# NOTICE — af_packet (CVE-2017-7308)
## Vulnerability
**CVE-2017-7308** — AF_PACKET TPACKET_V3 integer overflow in
`tp_block_size * tp_block_nr` → heap write-where via sendmmsg spray.
## Research credit
Discovered by **Andrey Konovalov** (Google), March 2017. A research-era
classic — Konovalov found multiple AF_PACKET bugs in this campaign.
Original advisory + writeup:
<https://googleprojectzero.blogspot.com/2017/05/exploiting-linux-kernel-via-packet.html>
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
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.
`--full-chain` engages the shared modprobe_path finisher with
stride-seeded sk_buff data-pointer overwrite.
@@ -0,0 +1,35 @@
# NOTICE — af_unix_gc (CVE-2023-4622)
## Vulnerability
**CVE-2023-4622** — AF_UNIX garbage-collector race against SCM_RIGHTS
fd-passing → `struct unix_sock` freed while still reachable → slab
UAF in `SLAB_TYPESAFE_BY_RCU` kmalloc-512 bucket.
## Research credit
Discovered and disclosed by **Lin Ma** (Zhejiang University),
August 2023.
Writeup: <https://github.com/google/security-research/security/advisories/GHSA-7p7m-3xv8-2pq2>
(disclosure record), plus Lin Ma's public PoC repo.
Upstream fix: mainline 6.6-rc1 (commit `0cabe18a8b80c`, Aug 2023).
Branch backports: 4.14.326 / 4.19.295 / 5.4.257 / 5.10.197 /
5.15.130 / 6.1.51 / 6.5.0.
## IAMROOT role
**Widest deployment of any module in the corpus** — bug present
in every Linux kernel below the fix (back to ~2.0 era).
Two-thread race driver: Thread A cycles SCM_RIGHTS fd-passing
through a socketpair; Thread B triggers unix_gc by closing a socket
in a reference cycle. msg_msg spray refills the freed slot.
CPU-pinned. Bounded budget: 5 s default, 30 s with `--full-chain`.
Bug is reachable as a **plain unprivileged user** — no userns
required, no CAP_* needed. Race-win rate per run is iteration-
dependent; Lin Ma's PoC reports thousands of iterations to first
reclaim. The shared finisher's sentinel timeout handles no-land
outcomes gracefully.
@@ -0,0 +1,29 @@
# NOTICE — cgroup_release_agent (CVE-2022-0492)
## Vulnerability
**CVE-2022-0492** — cgroup v1 `release_agent` privilege check in the
wrong namespace → host root from a rootless container or unprivileged
userns by mounting cgroup v1 and writing to `release_agent`.
## Research credit
Discovered by **Yiqi Sun** + **Kevin Wang** (Trend Micro Research),
January 2022.
Original writeup:
<https://blog.trendmicro.com/cve-2022-0492-from-cgroup-loophole-to-container-breakout/>
Upstream fix: mainline 5.17 (commit `24f6008564183`, March 2022).
## IAMROOT role
**Universal structural exploit — no per-kernel offsets, no race.**
unshare(USER | MOUNT | CGROUP), mount cgroup v1 RDP controller,
write `release_agent``./payload`, trigger via
`notify_on_release` + cgroup process exit.
Kept in the corpus as a portable "containers misconfigured"
demonstration — works across every kernel below the fix without any
tuning. Ships auditd rules covering cgroupfs mounts and
`release_agent` writes.
@@ -0,0 +1,25 @@
# NOTICE — cls_route4 (CVE-2022-2588)
## Vulnerability
**CVE-2022-2588**`net/sched` cls_route4 handle-zero dangling-filter
UAF → kernel R/W via msg_msg cross-cache refill.
## Research credit
Discovered and disclosed by **kylebot** / **xkernel**, August 2022.
Public PoC + writeup: <https://www.willsroot.io/2022/08/lpe-on-mountpoint.html>
(William Liu's analysis built on kylebot's trigger).
Upstream fix: mainline 5.20 / stable 5.19.7 (Aug 2022).
Branch backports: 5.4.213 / 5.10.143 / 5.15.69 / 5.18.18 / 5.19.7.
## IAMROOT role
The module uses `unshare(USER|NET)`, brings up a dummy interface,
creates an htb qdisc + class, adds a `route4` filter, then deletes
it to leave the dangling pointer. msg_msg sprays kmalloc-1k while
a UDP `classify()` walk follows the dangling pointer. `--full-chain`
re-fires with a faked tcf_proto.ops pointer aimed at the
modprobe_path overwrite via the shared finisher.
+25
View File
@@ -0,0 +1,25 @@
# NOTICE — dirty_cow (CVE-2016-5195)
## Vulnerability
**CVE-2016-5195** — Copy-on-write race via `/proc/self/mem` + `madvise`
→ arbitrary file write into the page cache.
## Research credit
Discovered by **Phil Oester**, October 2016. The bug had been latent in
the kernel since ~2007.
Original advisory: <https://dirtycow.ninja/>
Upstream fix: mainline 4.9 (commit `19be0eaffa3a`, Oct 2016).
## IAMROOT role
Two-thread Phil-Oester-style race: writer thread via
`/proc/self/mem` vs. madvise(MADV_DONTNEED) thread. Targets the
`/etc/passwd` UID field flip + `su` for the root shell. Useful for
**old systems coverage** — RHEL 6/7 (3.10 baseline), Ubuntu 14.04
(3.13), Ubuntu 16.04 (4.4), embedded boxes, IoT.
Ships auditd watch on `/proc/self/mem` and a sigma rule for non-root
mem-open patterns.
@@ -0,0 +1,21 @@
# NOTICE — dirty_pipe
## Vulnerability
**CVE-2022-0847** — pipe `PIPE_BUF_FLAG_CAN_MERGE` flag inheritance allows
arbitrary file write into the page cache.
## Research credit
Discovered and disclosed by **Max Kellermann** (CM4all GmbH), March 2022.
Original advisory: <https://dirtypipe.cm4all.com/>
Upstream fix: mainline 5.17 (commit `9d2231c5d74e`, Feb 2022).
## IAMROOT role
This module bundles the canonical splice-into-pipe primitive that
writes UID=0 into `/etc/passwd`'s page cache, then drops a root shell
via `su`. Detection covers the splice() syscall against sensitive
files and non-root modifications to passwd/shadow.
@@ -0,0 +1,23 @@
# NOTICE — entrybleed
## Vulnerability
**CVE-2023-0458** — KPTI `prefetchnta` timing side-channel leaks the
kernel base address (KASLR bypass).
## Research credit
Discovered by **Will Findlay**. Formally presented at USENIX Security '23:
> "EntryBleed: A Universal KASLR Bypass against KPTI on Linux"
> Bert Jan Schijf, Cristiano Giuffrida — USENIX Security 2023
Mainline status: no canonical patch — partial mitigations only.
## IAMROOT role
This is a **stage-1 leak primitive**, not a standalone LPE. Other
modules can call `entrybleed_leak_kbase_lib()` to obtain a KASLR
slide and feed it to the offset resolver in `core/offsets.c`. x86_64
only; the `entry_SYSCALL_64` slot offset is configurable via the
`IAMROOT_ENTRYBLEED_OFFSET` env var.
@@ -0,0 +1,32 @@
# NOTICE — fuse_legacy (CVE-2022-0185)
## Vulnerability
**CVE-2022-0185**`legacy_parse_param` in fsconfig() doesn't validate
`PAGE_SIZE` against the running `fs_context`'s key/value length →
4 KB heap OOB write → cross-cache UAF → cred overwrite from a
rootless container.
## Research credit
Discovered and disclosed by **William Liu** + **Jamie Hill-Daniel**
(Crusaders of Rust), January 2022.
Original writeup: <https://www.willsroot.io/2022/01/cve-2022-0185.html>
Public PoC: <https://github.com/Crusaders-of-Rust/CVE-2022-0185>
Upstream fix: mainline 5.16.2 (Jan 2022).
Branch backports: 5.16.2 / 5.15.14 / 5.10.91 / 5.4.171.
## IAMROOT role
userns+mountns reach, `fsopen("cgroup2")` + double
`fsconfig(FSCONFIG_SET_STRING, "source", ...)` fires the 4k OOB,
msg_msg cross-cache groom in kmalloc-4k. MSG_COPY read-back detects
whether the OOB landed in an adjacent neighbour — the sanity gate
that prevents fake-success claims.
`--full-chain` extends with forged m_list/m_ts overflow toward
modprobe_path via the shared finisher.
**Container-escape angle** — relevant to rootless docker/podman/snap.
@@ -0,0 +1,29 @@
# NOTICE — netfilter_xtcompat (CVE-2021-22555)
## Vulnerability
**CVE-2021-22555** — iptables `xt_compat_target_to_user` 4-byte heap
out-of-bounds write → cross-cache UAF → arbitrary kernel R/W.
## Research credit
Discovered, exploited, and disclosed by **Andy Nguyen** (Google
Security Team), April 2021.
Original writeup: "CVE-2021-22555: Turning $00 $00 into 10 million $$$"
<https://google.github.io/security-research/pocs/linux/cve-2021-22555/writeup.html>
Upstream fix: mainline 5.12 / 5.11.10 (April 2021).
**Bug existed since 2.6.19 (2006) — 15 years of latent vulnerability.**
Branch backports: 5.11.10 / 5.10.27 / 5.4.110 / 4.19.185 / 4.14.230 /
4.9.266 / 4.4.266.
## IAMROOT role
Userns+netns reach, hand-rolled `ipt_replace` blob, `setsockopt`
`IPT_SO_SET_REPLACE` fires the 4-byte OOB at heap+0x4. msg_msg
spray in kmalloc-2k + sk_buff sidecar; MSG_COPY scan for cross-cache
landing. `--full-chain` extends with stride-seeded `m_list_next`
overwrite aimed at modprobe_path via the shared finisher.
Detection rules cover unshare + msgsnd + `setsockopt(IPT_SO_SET_REPLACE)`.
+27
View File
@@ -0,0 +1,27 @@
# NOTICE — nf_tables (CVE-2024-1086)
## Vulnerability
**CVE-2024-1086**`nft_verdict_init` double-free → cross-cache UAF
→ arbitrary kernel R/W.
## Research credit
Discovered, exploited, and disclosed by **Notselwyn** (Pumpkin),
January 2024.
Original advisory + exploit: <https://pwning.tech/nftables/>
GitHub: <https://github.com/Notselwyn/CVE-2024-1086>
Upstream fix: mainline 6.8-rc1 (commit `f342de4e2f33`, Jan 2024).
Stable backports throughout Q1 2024.
## IAMROOT role
This module fires the malformed-verdict trigger (NFT_GOTO + NFT_DROP
in the same verdict) via a hand-rolled nfnetlink batch — no libmnl
dependency. The msg_msg cross-cache groom into kmalloc-cg-96 is wired
but the full pipapo R/W stage is opt-in via `--full-chain`, which
forges a pipapo_elem with a value-pointer pointing at modprobe_path.
Per-kernel offset assumptions are documented; the shared finisher's
sentinel arbitrates real vs. apparent success.
@@ -0,0 +1,28 @@
# NOTICE — nft_fwd_dup (CVE-2022-25636)
## Vulnerability
**CVE-2022-25636**`nft_fwd_dup_netdev_offload` writes
`flow->rule->action.entries[ctx->num_actions]` without bounds-checking
against the allocated array size → heap OOB write in kmalloc-512.
## Research credit
Discovered and disclosed by **Aaron Adams** (NCC Group),
February 2022.
Original writeup:
<https://research.nccgroup.com/2022/03/02/exploit-engineering-attacking-the-linux-kernel/>
Upstream fix: mainline 5.17 (commit `fa54fee62954`, Feb 2022).
Branch backports: 5.16.11 / 5.15.25 / 5.10.102 / 5.4.181.
## IAMROOT role
userns+netns reach. Hand-rolled nfnetlink batch: NEWTABLE →
NEWCHAIN with `NFT_CHAIN_HW_OFFLOAD` → NEWRULE with 16 immediates
+ fwd, overruning `action.entries[1]`. msg_msg cross-cache groom
into kmalloc-512 with `IAMROOT_FWD` tags.
`--full-chain` extends with stride-seeded forged action_entry
overwrite aimed at modprobe_path via the shared finisher.
@@ -0,0 +1,36 @@
# NOTICE — nft_payload (CVE-2023-0179)
## Vulnerability
**CVE-2023-0179**`nft_payload` set/get uses `regs->verdict.code`
as an index into `regs->data[]` without bounds-checking; combined
with the variable-length element extension trick (NFTA_SET_DESC
describing elements larger than the key/data slots), an attacker
walks regs off either end → OOB R/W on adjacent kernel memory.
## Research credit
Discovered and disclosed by **Davide Ornaghi**, January 2023.
Original slides + writeup:
<https://github.com/davide-romanini/CVE-2023-0179>
+ DEF CON 31 / SecurityFest 2023 presentations.
Upstream fix: mainline 6.2-rc4 (commit `696e1a48b1a1`, Jan 2023).
Branch backports: 4.14.302 / 4.19.269 / 5.4.229 / 5.10.163 /
5.15.88 / 6.1.6.
## IAMROOT role
userns+netns. Hand-rolled nfnetlink batch: NEWTABLE → NEWCHAIN →
NEWSET with `NFTA_SET_DESC` describing variable-length elements →
NEWSETELEM with `NFTA_SET_ELEM_EXPRESSIONS` carrying a payload-set
whose attacker-controlled `verdict.code` drives the OOB index.
Dual cg-96 + 1k msg_msg spray (covers both common adjacency
scenarios). `--full-chain` extends with kaddr-tagged refire aimed
at modprobe_path via the shared finisher.
Default OOB index `0x100` matches Ornaghi's PoC on a stock 5.15
build; the sentinel post-check correctly reports failure on builds
where regs->data adjacency differs.
@@ -0,0 +1,33 @@
# NOTICE — nft_set_uaf (CVE-2023-32233)
## Vulnerability
**CVE-2023-32233** — nf_tables anonymous-set deactivation skip →
slab UAF on the freed `nft_set` object exploitable via msg_msg
cross-cache groom in kmalloc-cg-512.
## Research credit
Discovered and disclosed by **Patryk Sondej** and **Piotr Krysiuk**,
May 2023.
Original advisory + writeup distributed via the OSS-Security list
and an accompanying Google Drive PoC.
Follow-up exploit and Crusaders-of-Rust analysis built on the
public trigger.
Upstream fix: mainline 6.4-rc4 (commit `c1592a89942e9`, May 2023).
Branch backports: 6.3.2 / 6.2.15 / 6.1.28 / 5.15.111 / 5.10.180 /
5.4.243 / 4.19.283.
## IAMROOT role
Hand-rolled nfnetlink batch: NEWTABLE → NEWCHAIN (base, LOCAL_OUT
hook) → NEWSET (ANON|EVAL|CONSTANT) → NEWRULE (nft_lookup
referencing the set by `NFTA_LOOKUP_SET_ID`) → DELSET → DELRULE
in the same transaction. msg_msg cg-512 spray with `IAMROOT_SET`
tags.
`--full-chain` forges a freed-set with `set->data = kaddr` at the
Sondej/Krysiuk reference offset (0x30) and drives a NEWSETELEM with
the modprobe_path payload bytes via the shared finisher.
+25
View File
@@ -0,0 +1,25 @@
# NOTICE — overlayfs (CVE-2021-3493)
## Vulnerability
**CVE-2021-3493** — Ubuntu overlayfs userns file-capability injection
→ host root via setcap'd binaries in a userns-mounted overlay.
## Research credit
Reported by **Vasily Kulikov**, April 2021. Ubuntu-specific because
upstream didn't enable unprivileged userns-overlayfs-mount until 5.11.
Advisory: USN-4915-1 / USN-4916-1 (Canonical, April 2021).
Public PoC: vsh-style userns + overlayfs + xattr injection chain.
## IAMROOT role
Detect parses `/etc/os-release` for `ID=ubuntu`, checks
`unprivileged_userns_clone` sysctl, and with `--active` performs the
mount as a fork-isolated probe. The full exploit performs the
userns+overlayfs mount, plants a setcap'd carrier binary in the
upper layer, and execs it from the unprivileged side to obtain root
on the host. Ships auditd rules covering `mount(overlay)` and
`setxattr(security.capability)`.
@@ -0,0 +1,25 @@
# NOTICE — overlayfs_setuid (CVE-2023-0386)
## Vulnerability
**CVE-2023-0386** — overlayfs `copy_up` preserves the setuid bit
across mount-namespace boundaries → host root via a setuid carrier
placed in the lower layer.
## Research credit
Discovered and disclosed by **Xkaneiki**, January 2023.
Public PoC + writeup:
<https://github.com/xkaneiki/CVE-2023-0386>
Upstream fix: mainline 6.2-rc6 (commit `4f11ada10d0a`, Jan 2023).
Branch backports: 5.10.169 / 5.15.92 / 6.1.11.
## IAMROOT role
Distro-agnostic — no per-kernel offsets, no race. Places a setuid
binary in an overlay lower, mounts via fuse-overlayfs userns trick,
executes from the upper layer to inherit the setuid bit + root euid.
Auditd rules cover overlayfs mounts and unexpected setuid copy-ups.
@@ -0,0 +1,27 @@
# NOTICE — ptrace_traceme (CVE-2019-13272)
## Vulnerability
**CVE-2019-13272**`PTRACE_TRACEME` on a parent that subsequently
execve's a setuid binary leaves the now-elevated process traceable by
the unprivileged child → cred escalation via ptrace shellcode inject.
## Research credit
Discovered by **Jann Horn** (Google Project Zero), June 2019.
Project Zero issue: <https://bugs.chromium.org/p/project-zero/issues/detail?id=1903>
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
Full jannh-style chain: fork → child `PTRACE_TRACEME` → child
sleep+attach → parent `execve` setuid bin (pkexec/su/passwd
auto-selected) → child wins stale `ptrace_link` → POKETEXT x86_64
shellcode → root sh.
x86_64-only; ARM/other archs return PRECOND_FAIL cleanly. No exotic
preconditions — doesn't need userns. Works on default-config systems
including locked-down environments without unprivileged_userns_clone.
+25
View File
@@ -0,0 +1,25 @@
# NOTICE — pwnkit
## Vulnerability
**CVE-2021-4034** — pkexec argv[0]=NULL → environment-variable
injection → arbitrary code execution as root.
## Research credit
Discovered and disclosed by the **Qualys Research Team**, January 2022.
Original advisory:
<https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt>
Upstream fix: polkit 0.121 (Jan 2022).
## IAMROOT role
The exploit module follows the canonical Qualys-style chain: writes
payload.c + gconv-modules cache, compiles via the target's gcc,
execve's pkexec with NULL argv and crafted envp. Handles both the
legacy ("0.105") and modern ("126") polkit version string formats.
Falls back gracefully on hosts without a compiler.
This is IAMROOT's first **userspace** LPE — not a kernel bug.
+31
View File
@@ -0,0 +1,31 @@
# NOTICE — stackrot (CVE-2023-3269)
## Vulnerability
**CVE-2023-3269** — Maple-tree VMA-split UAF (race between mremap and
fork+fault) → kernel R/W via stale anon_vma_chain reference.
## Research credit
Discovered and disclosed by **Ruihan Li** (Peking University),
July 2023.
Original advisory: <https://github.com/lrh2000/StackRot>
Writeup: <https://lkmidas.github.io/posts/20230724-stackrot/>
Upstream fix: mainline 6.5-rc1 (commit `0503ea8f5ba73`, July 2023).
Branch backports: 6.4.4 / 6.3.13 / 6.1.37.
## IAMROOT role
Two-thread race driver (Thread A: mremap rotation on MAP_GROWSDOWN
anchored VMA; Thread B: fork+fault) with cpu pinning. kmalloc-192
spray for anon_vma_chain reclaim. Bounded budget: 3 s default,
30 s with `--full-chain`.
**Honest reliability assessment:** ~<1% race-win per run on a
vulnerable kernel. Ruihan Li's public PoC averages minutes-to-hours
and needs a much wider VMA-staging matrix to be reliable. The
shared finisher's 3 s sentinel timeout handles the overwhelmingly
common no-land outcome gracefully — module returns EXPLOIT_FAIL
honestly rather than claim root on a race that didn't win.