Skip to content

Commit 43f6a2f

Browse files
committed
extra: add README indexing the helper scripts + their workflows
A one-page index of the extra/ tools — an at-a-glance table (purpose, root, deeper-doc link) and the cross-tool workflows: hardening posture-diff, collect/validate-bundle capture-and-verify, live check-results, fleet/CI, and ksymoff. GitHub auto-renders it when browsing the directory.
1 parent 996cb66 commit 43f6a2f

1 file changed

Lines changed: 165 additions & 0 deletions

File tree

extra/README.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Extra tools
2+
3+
The `extra/` directory ships standalone helpers built around `kasld`: capture and
4+
replay, soundness validation, security-posture comparison, symbol resolution, and
5+
test setup. Each is a self-contained script with a `--help` / header comment — this
6+
page indexes them and shows how they combine into workflows. (`kasld` itself is in
7+
[usage.md](../docs/usage.md).)
8+
9+
## Table of Contents
10+
11+
- [The tools at a glance](#the-tools-at-a-glance)
12+
- [Workflows](#workflows)
13+
- [Measure what hardening buys](#measure-what-hardening-buys)
14+
- [Capture here, verify anywhere](#capture-here-verify-anywhere)
15+
- [Validate a live run against ground truth](#validate-a-live-run-against-ground-truth)
16+
- [Watch a fleet, gate CI](#watch-a-fleet-gate-ci)
17+
- [Turn a recovered base into an exploit](#turn-a-recovered-base-into-an-exploit)
18+
- [Standalone helpers](#standalone-helpers)
19+
20+
## The tools at a glance
21+
22+
| Tool | Purpose | Root? | Deeper reference |
23+
|------|---------|-------|------------------|
24+
| [`collect`](collect) | Capture a portable, self-identifying bundle of this host's KASLD-relevant state (meta, `kasld -v`, dmesg, a path-preserving `sysroot/` mirror) | no ¹ | [reproducibility.md](../docs/reproducibility.md#1-on-the-local-kernel) |
25+
| [`validate-bundle`](validate-bundle) | Offline soundness check over a `collect` bundle — asserts the resolved ranges contain the captured truth | no | [reproducibility.md](../docs/reproducibility.md#1-on-the-local-kernel) |
26+
| [`check-results`](check-results) | Live per-leak validator — compares a `kasld` run against `/proc/kallsyms` · `/proc/iomem` · `/proc/kcore` ground truth | **yes** | [testing.md](../docs/testing.md#validating-captured-bundles) |
27+
| [`posture-diff`](posture-diff) | Compare two `kasld -j` snapshots; exit non-zero if the KASLR **posture** regressed | no | [usage.md](../docs/usage.md#regression-gate-extraposture-diff) |
28+
| [`posture-summary`](posture-summary) | Roll up many `kasld -j` snapshots into one table (text / markdown / csv / json), one row per host | no | [usage.md](../docs/usage.md#fleet-summary-extraposture-summary) |
29+
| [`ksymoff`](ksymoff) | Apply the KASLR slide to kernel symbols; translate physical ↔ virtual and physical → `struct page` | no | [exploitation.md](../docs/exploitation.md#from-a-base-to-runtime-addresses) |
30+
| [`weaken-kernel-hardening`](weaken-kernel-hardening) | Temporarily relax the hardening sysctls for testing; restores the originals on exit | **yes** | below |
31+
| [`sudo-proc-kallsyms`](sudo-proc-kallsyms) | Briefly lower `kptr_restrict`, read the base symbols from `/proc/kallsyms`, restore | sudo | below |
32+
| [`check-hardware-vulnerabilities`](check-hardware-vulnerabilities) | Report the CPU hardware vulnerabilities (Meltdown / MDS / …) that can disclose kernel memory to an unprivileged process | no | [bypass-techniques.md](../docs/bypass-techniques.md#side-channels) |
33+
| [`anonymize-fdt`](anonymize-fdt) | Strip board serial / MAC from a captured device tree before sharing it as a replay fixture | no ² | [testing.md](../docs/testing.md) |
34+
35+
¹ `collect --kallsyms` records ground truth only where `kptr_restrict` is readable
36+
(root, or `kptr_restrict=0`); without it the bundle carries no truth.
37+
² Maintainer / dev-host tool; needs `dtc`.
38+
39+
## Workflows
40+
41+
### Measure what hardening buys
42+
43+
`kasld` recovers less on a hardened host and more on a relaxed one; `posture-diff`
44+
puts a number on the gap. Capture the posture in each state, then diff them.
45+
46+
```sh
47+
# 1. Baseline: the host as it boots (whatever hardening is in effect).
48+
./build/*/kasld -j > hardened.json
49+
50+
# 2. Relax the hardening sysctls. weaken-kernel-hardening holds until Ctrl+C and
51+
# restores the originals on exit; run kasld from a second terminal meanwhile.
52+
sudo extra/weaken-kernel-hardening # terminal A — leave it running
53+
./build/*/kasld -j > weakened.json # terminal B
54+
# ... then Ctrl+C in terminal A to restore the original sysctls.
55+
56+
# 3. What did the hardening hide? Diff hardened (baseline) -> weakened (current):
57+
extra/posture-diff hardened.json weakened.json
58+
# REGRESSION: posture is weaker than baseline
59+
# - guaranteed entropy dropped: 9 -> 0 bits (virtual)
60+
# - defense turned off: kptr_restrict
61+
# - defense turned off: perf_event_paranoid
62+
```
63+
64+
The regression findings are exactly what the hardening was buying: the residual
65+
entropy it preserved and the defenses it kept on. `posture-diff` is **directional**
66+
(baseline first) — flip the arguments (`posture-diff weakened.json hardened.json`)
67+
and the same change reads as an improvement (`OK: no posture regression`).
68+
69+
`weaken-kernel-hardening` relaxes `kptr_restrict`, `dmesg_restrict`,
70+
`perf_event_paranoid`, and `unprivileged_bpf_disabled` — a **testing** convenience,
71+
never for production. It restores the saved values on `Ctrl+C`, `SIGTERM`, or normal
72+
exit, so the weakened state never outlives the process.
73+
74+
`posture-diff` compares only the **boot-stable** posture — guaranteed entropy
75+
(virtual and physical), KASLR state, unpatched CVE-class leaks, and disabled
76+
defenses. It never reads the per-boot base address or slide, which re-randomize
77+
every boot, so the same command doubles as a reboot-safe config-drift gate.
78+
79+
### Capture here, verify anywhere
80+
81+
`collect` freezes a host's KASLD-relevant state into a portable bundle that
82+
replays offline on another machine — useful for a bug report, an air-gapped
83+
target, or an architecture the analysis host can only emulate.
84+
85+
```sh
86+
# On the target: capture (add --kallsyms to record ground truth for validation).
87+
extra/collect --kallsyms # -> kasld-bundle-<host>-<date>/
88+
89+
# Anywhere: replay the exact same facts through kasld, no target needed.
90+
KASLD_SYSROOT=kasld-bundle-*/sysroot ./build/*/kasld -v
91+
92+
# And check the engine stayed sound over that capture (truth ∈ every range):
93+
extra/validate-bundle kasld-bundle-*
94+
```
95+
96+
`validate-bundle` needs no root — the truth comes from the bundle's captured files,
97+
not the host's `/proc`. It exits `0` (every quantity PASS or N/A), `1` (a soundness
98+
violation — the resolved window excluded the truth, a bug), or `2` (malformed
99+
bundle). See [reproducibility.md](../docs/reproducibility.md#1-on-the-local-kernel).
100+
101+
### Validate a live run against ground truth
102+
103+
On a system where you have root, `check-results` compares a live `kasld` run
104+
against the kernel's real addresses (`/proc/kallsyms`, `/proc/iomem`, …):
105+
106+
```sh
107+
sudo extra/check-results # runs kasld itself
108+
./build/*/kasld -v 2>&1 | sudo extra/check-results # or validate a piped run
109+
sudo extra/check-results results.txt # or a saved report
110+
```
111+
112+
It reports PASS / FAIL / SKIP per result and asserts the resolved window contains
113+
the truth. A `sudo-proc-kallsyms` one-liner is the minimal version — it just
114+
lowers `kptr_restrict`, prints the base symbols from `/proc/kallsyms`, and restores.
115+
116+
### Watch a fleet, gate CI
117+
118+
The two `posture-*` tools scale the single-host view to an estate and to CI. They
119+
do no collection or transport themselves — your own fan-out supplies the snapshots
120+
(the file's basename is the host label, since `kasld -j` carries no hostname):
121+
122+
```sh
123+
# One kasld -j per host, then summarise the whole fleet at a glance.
124+
for h in $(cat hosts); do ssh "$h" 'kasld -j' > "snap/$h.json"; done
125+
extra/posture-summary --markdown snap/*.json
126+
127+
# In CI: fail the build if a target's posture regressed against a saved baseline.
128+
kasld -j > current.json
129+
extra/posture-diff baseline.json current.json || echo "KASLR posture regressed"
130+
```
131+
132+
Both read `kasld -j` snapshots (live, or replayed from a `collect` bundle via
133+
`KASLD_SYSROOT`). Full detail — the entropy-threshold and CVE-leak gates they pair
134+
with — is in [usage.md → Continuous integration](../docs/usage.md#continuous-integration).
135+
136+
### Turn a recovered base into an exploit
137+
138+
`ksymoff` consumes `kasld`'s output to resolve runtime symbol addresses (forward
139+
`base → symbols`, inverse `known symbol → base`) and to translate physical
140+
addresses for data-only pivots (`--phys2virt` / `--virt2phys` / `--phys2page`):
141+
142+
```sh
143+
./build/*/kasld -1 2>/dev/null | extra/ksymoff -s System.map commit_creds
144+
```
145+
146+
The full exploit workflow — control-flow reuse vs data-only, the pwntools
147+
template, and every `ksymoff` mode — is in
148+
[exploitation.md](../docs/exploitation.md#from-a-base-to-runtime-addresses).
149+
150+
## Standalone helpers
151+
152+
These two stand alone rather than chaining into a workflow above:
153+
154+
- **[`check-hardware-vulnerabilities`](check-hardware-vulnerabilities)** *(target
155+
reconnaissance)* — reports which memory-disclosure CPU bugs (Meltdown, MDS, …)
156+
the running kernel still exposes, i.e. whether a hardware leak of kernel data
157+
(and with it a pointer that defeats KASLR) is applicable here at all. These
158+
differ in power: Meltdown reads arbitrary kernel addresses, while MDS/L1TF-class
159+
flaws leak only opportunistic in-flight or cache-resident data. Background in
160+
[bypass-techniques.md](../docs/bypass-techniques.md#side-channels).
161+
- **[`anonymize-fdt`](anonymize-fdt)** *(maintainer / fixtures)* — a dev-host tool: strips
162+
board-identifying serial / MAC properties from a captured flattened device tree
163+
(`sysroot/sys/firmware/fdt`) before it is committed as a shared replay fixture. It
164+
deliberately keeps `chosen/kaslr-seed` (KASLD reads it to infer the KASLR state).
165+
Needs `dtc`; edits in place with a `.orig` backup.

0 commit comments

Comments
 (0)