Skip to content

Latest commit

 

History

History
438 lines (360 loc) · 26.4 KB

File metadata and controls

438 lines (360 loc) · 26.4 KB

Angband Agent Instructions

This document provides high-signal context for OpenCode agents working in the angband repository. It focuses on non-obvious setup requirements, expected workflows, and critical safety rules.

Documentation Map

The docs/ directory contains detailed reference material. Start with docs/index.md for the complete knowledge map, or consult individual docs directly:

Document Description
docs/index.md START HERE — Complete knowledge map organized by pipeline stage
docs/bug-class-taxonomy.md 11 bug classes, PaX attack paradigms, SLUBStick, technique selection matrix
docs/heap-exploitation.md SLUB internals, 6 spray methods, 5 escalation patterns, cross-cache mitigations
docs/novel-techniques.md 13 cutting-edge techniques (LL_ATK, Kernel One Gadget, SLUBStick, CARDSHARK, etc.)
docs/mitigations-defense.md VED/LKRG/AUTOSLAB mitigation taxonomy (consolidated in vkb.md)
docs/manual_build.md Step-by-step guest VM exploitation walkthrough
docs/vkb.md Ring 0 exploitation reference index — all external sources (papers, tools, CVEs) with URLs
KERNEL_MITIGATIONS.md Verified kernel addresses, struct offsets, CVE patch status, sysctl requirements
ARCHITECTURE.md Full architecture with data flow diagrams, strategy map, template docs
TESTING.md End-to-end testing guide: prerequisites, demo/CVE test steps, success criteria, troubleshooting

When to consult which doc

Task Start with
Analyzing a new CVE docs/index.mddocs/bug-class-taxonomy.md
Choosing a spray/groom method docs/index.mddocs/heap-exploitation.md → Spray Selection Guide
Selecting a technique for a blocker docs/index.mddocs/novel-techniques.md → Technique Selection Matrix
Understanding a specific CVE docs/CVE-*-analysis.md for that CVE
Getting kernel addresses for a target KERNEL_MITIGATIONS.md → Verified Kernel Addresses
Understanding the template codegen ARCHITECTURE.md → Jinja2 Templates section
Looking up an external paper/tool/CVE reference docs/vkb.md → Quick Lookup
Understanding mitigations docs/vkb.md → Defense & Mitigation Research
Running end-to-end tests TESTING.md → Step-by-step instructions

Core Architecture and Entrypoints

  • Purpose: Angband is an automated kernel exploit generation framework. Its goal is to produce full-chain kernel exploits from CVE identifiers to accelerate severity analysis. Currently, it generates staged demo payloads (simulation-only), runs them in an isolated QEMU guest, and verifies kernel-side stage evidence through the synthetic vuln_drill module. Real exploit generation is the next milestone.
  • Entrypoint: The main CLI tool is the installed angband command. Do not invoke repo-local scripts directly when the package entrypoint is available; install in editable mode and use angband.
  • Structure:
    • Python package logic: angband/.
    • C exploit reference primitives: primitives/.
    • Generated runtime output: mordor_run/current/exploit.yaml, mordor_run/current/exploit.c, mordor_run/current/exploit.
    • Synthetic testing module: module/vuln_drill/.

Environment Setup

Agents should establish a clean Python environment from scratch to ensure predictable behavior, rather than assuming external dependencies exist.

  1. Create and activate a virtual environment:
    python3 -m venv venv
    source venv/bin/activate
  2. Install the project in editable mode:
    pip install -e .
    This creates the angband entrypoint which correctly resolves module paths (e.g., angband.core.engine).

Test Execution & Safety Conventions

CRITICAL: The generated payload is currently non-operational (simulation-only), but the project goal is full-chain exploit generation. Always treat mordor_run/current/exploit as guest-only output. Never run it on the host machine.

Kernel Mitigations

When testing exploits in the QEMU VM, certain kernel mitigations must be disabled. See KERNEL_MITIGATIONS.md for the complete list and commands.

Key sysctls to disable before exploit testing:

sudo sysctl -w kernel.perf_event_paranoid=-1
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
sudo sysctl -w kernel.kptr_restrict=0
  1. Demo Execution Workflow:
    • The standard flow is to use run_and_verify.sh, which handles generation, QEMU interaction via SSH, and log extraction.
    • In angband init demo mode, it also builds and loads module/vuln_drill/vuln_drill.ko in the guest.
    • In angband init <CVE> mode, the CVE is metadata only and run_and_verify.sh skips guest kernel-module setup.
    # Assuming venv is active and QEMU harness is running in background
    ./run_and_verify.sh
  2. QEMU Harness Execution:
    • The harness is located in harness/setup.sh, harness/launch.sh, and harness/stop.sh. It requires qemu-system-x86 and cloud-image-utils (sudo apt install qemu-system-x86 cloud-image-utils).
    • Initialize the VM: cd harness && ./setup.sh
    • Launch the VM: ./launch.sh
    • Connect to the Serial Console: ./console.sh (useful if kernel panics and SSH drops)
    • Stop the VM: ./stop.sh
    • The harness creates a 9p mount point, making the host's angband directory available inside the VM at /mnt/angband.

Common Workflows & Commands

  • Generating a Demo Configuration:
    angband init <cve_or_commit> --target <target-name>
    Examples:
    • angband init demo --target ubuntu-24.04-x86_64
    • angband init CVE-2024-1086 --target ubuntu-24.04-x86_64
  • Generating the C Payload:
    angband generate
    Note: This reads mordor_run/current/exploit.yaml, generates mordor_run/current/exploit.c using Jinja2 templates, and compiles mordor_run/current/exploit.

Modifying the Codebase

  • When editing Python code, test changes by regenerating the payload with angband generate.
  • When modifying C primitives (primitives/*.c), ensure the angband generate compilation step succeeds.
  • Demo verification artifacts are written under mordor_run/current/:
    • exploit_run.log
    • dmesg_tail.log
    • vuln_drill_status.log in demo mode

Step 5: Exploitation Assessment Matrix

Factor Score Assessment
Write reaches function pointer ★★★ Direct code execution
Write reaches arbitrary address ★★ Needs 2-step (corrupt pointer → exec)
Write to fixed offset + controllable value May be chainable
Write to fixed offset + fixed value Not exploitable alone

Additional Reference Documentation

Document Purpose
docs/bug-class-taxonomy.md Bug class classification, exploitation approaches, capability requirements, chain potential
docs/heap-exploitation.md SLUB internals, 6 spray methods, 5 escalation patterns, naive vs SLUBStick cross-cache
docs/novel-techniques.md 13 techniques: LL_ATK, Kernel One Gadget, SLUBStick, CARDSHARK, ExpRace, signalfd, etc.

Common Exploitation Pattern (All UAF CVEs)

Freed object → msg_msg reclaim (mtext@48) → controlled func ptr → kernel calls func(rdi=our_data)
                                                                          │
                                                              ┌───────────┴───────────┐
                                                      commit_creds (ROP chain)    modprobe_path (write + trigger)

For advanced technique alternatives (LL_ATK, Kernel One Gadget, signalfd credential overwrite), see docs/novel-techniques.md. For spray method selection and slab internals, see docs/heap-exploitation.md.

Exploitation Technique Reference

msg_msg Spray (Primary Angband Primitive)

The most versatile heap spray in Linux kernel exploitation. Used by ALL angband CVEs. Controllable size (48 to PAGE_SIZE), mtext overlays freed objects, corruptible fields (m_ts/next/security) enable arbitrary read/free. See docs/bug-class-taxonomy.md for the full PaX attack paradigm classification and SLUB allocator internals.

Key Techniques Implemented in angband

Technique Where Used CVE
msg_msg reclaim → func ptr hijack primitive stage 35555, 44269, 33289
wake_up_locked_poll exec timerfd trigger 35555
pcpu_stats → modprobe_path write macvlan primitive 23209
dirty_pagetable page reclaim macvlan full 23209
commit_creds ROP chain escalate stage (commit_creds path) All
modprobe_path trigger escalate stage (modprobe_path path) All
KASLR side-channel bypass leak stage All

Modern Mitigations to Consider

Mitigation Effect on angband Exploits
CONFIG_RANDOM_KMALLOC_CACHES (v6.6) Must slab drain + pattern spray (as done in macvlan)
Separate accounted caches (v5.14) msg_msg and target object must match cache type
PaX AUTOSLAB Same-type spray only; prefer dirty_pagetable for cross-cache
VED msg_msg integrity Match object sizes exactly to bypass OOB check
kCFI/IBT Data-only attacks preferred over ROP
CPU pinning restriction Reduces spray reliability ~20-30%

Exploit Writer: Read Source Code First — Non-Negotiable Rule

Before writing any exploit code, the exploit writer MUST read the actual kernel source of the vulnerable subsystem. This rule exists because every iteration of CVE-2026-31533 that skipped this step wasted days of effort on assumptions that were wrong:

  • Wrong trigger condition (flood never reached the -EBUSY threshold)
  • Wrong struct offsets (estimated rather than verified)
  • Wrong UAF write target (callback only wrote to data fields, not function pointers)
  • Wrong slab cache size (used kmalloc-256 spray when tls_rec is kmalloc-512+)

All of these were answerable from the kernel source in under 30 minutes.

The six questions to answer from source before writing exploit.c

# Question Where to find the answer
1 Exact function and file where the bug triggers Fix commit diff, CVE description
2 Exact syscall sequence to reach the vulnerable path Source of the vulnerable function
3 Exact kernel state that causes the bug (threshold, race window, etc.) Source + fix diff
4 Exact field(s) written during UAF/OOB — offset >= 48 for msg_msg exploit? struct definition + pahole
5 Exact struct size → which kmalloc cache sizeof() from struct definition
6 Which runtime code path is active in this kernel build ethtool/sysctl/lsmod in VM

How to get the source

# Fetch the exact file for kernel v6.8:
curl -s https://raw.githubusercontent.com/torvalds/linux/v6.8/<path/to/file.c>

# Read the fix commit diff (shows exactly what invariant was violated):
curl -s https://github.com/torvalds/linux/commit/<hash>.patch | head -300

# Get struct offsets from the loaded kernel module in the VM:
ssh -i mordor_run/ssh/id_ed25519 -p 2222 ubuntu@localhost \
  "unzstd /lib/modules/\$(uname -r)/kernel/<path>.ko.zst -o /tmp/m.ko && \
   pahole -C <struct_name> /tmp/m.ko 2>/dev/null || echo 'no DWARF — use source'"

Verify trigger reachability before full implementation

After reading source, write a minimal Python/C reproducer that puts the kernel in the pre-trigger state. Run it in the VM and check the serial log and dmesg for any evidence the right code path was hit (KASAN report, Oops, unexpected errno, stat counter change). Only proceed to full exploit implementation once the trigger is confirmed reachable with the expected behavior.

If the trigger cannot be confirmed in the VM, the exploit is unverified regardless of how well the code compiles.

Exploit Loop Pipeline — Verified Workflow

The following ASCII diagram shows the complete, verified exploit loop pipeline with all actors, data flows, handoffs, and feedback loops. This is the authoritative reference for how the loop runs.

╔══════════════════════════════════════════════════════════════════════════════╗
║                        ANGBAND EXPLOIT LOOP PIPELINE                        ║
║                  (Bug CVE → Serial-log Crash / uid=0 Shell)                 ║
╠══════════════════════════════════════════════════════════════════════════════╣
║                                                                              ║
║  ┌────────────┐                                                              ║
║  │ BOOKKEEPER │  Reads cve-list.md, picks next pending CVE,                 ║
║  │  (Agent)   │  sets row to in_progress, opens iteration-log/CVE-X/        ║
║  └─────┬──────┘                                                              ║
║        │  CVE-ID + metadata                                                  ║
║        ▼                                                                     ║
║  ┌─────────────────────────────────────────────────────────────────────┐    ║
║  │                    EXPLOIT WRITER  (Agent)                          │    ║
║  │                                                                     │    ║
║  │  Step 1:  Read source (fix diff + vulnerable function + structs)    │    ║
║  │  Step 1b: Answer 6 source questions before touching exploit.c       │    ║
║  │  Step 1c: Study existing exploits; label bad-code patterns          │    ║
║  │  Step 1d: Plan escalation path from bug class + trigger evidence    │    ║
║  │  Step 2:  Feasibility assessment (config, hardware, privilege)      │    ║
║  │  Step 3:  7-stage chain design (prep/groom/trigger/…/escalate)     │    ║
║  │  Step 4:  Write docs/cve-analysis/CVE-X-analysis.md                │    ║
║  │  Step 5:  angband init + generate → fill placeholders → compile     │    ║
║  │  Step 5d: Iterate in VM (verify-cve.sh) until serial log fires     │    ║
║  │  Step 1d: Post-trigger: push escalation (OOPS→panic→uid=0)         │    ║
║  │  Step 6:  Write exploit-loop/iteration-log/CVE-X/writer_summary.md │    ║
║  └─────┬───────────────────────────────────────────────────────────────┘    ║
║        │  exploit binary + writer_summary.md + CVE analysis doc             ║
║        ▼                                                                     ║
║  ┌──────────────────────────────────────────────────────────────────┐       ║
║  │                    VERIFY-CVE.SH  (Script)                       │       ║
║  │                                                                  │       ║
║  │  1. Copy exploit → CVE-named binary (cve-XXXX-XXXXX)            │       ║
║  │  2. Check VM state; launch harness if down                       │       ║
║  │  3. Apply sysctls: kptr_restrict=0, userns=0, perf_paranoid=-1   │       ║
║  │  4. Mount 9p host dir at /mnt/angband inside VM                  │       ║
║  │  5. Run binary as ubuntu (no sudo) inside VM                     │       ║
║  │  6. Health check: SSH alive after exploit?  → PANIC if dead      │       ║
║  │  7. Read serial.log delta → classify UBSAN/KASAN/Call Trace/RIP  │       ║
║  │  8. Classify outcome:                                             │       ║
║  │       exit 0  → ESCALATED   (uid=0 confirmed)                   │       ║
║  │       exit 1  → PANIC       (VM SSH dead / "Kernel panic" line)  │       ║
║  │       exit 2  → OOPS        (Call Trace/BUG/UBSAN in serial)     │       ║
║  │       exit 3  → UNVERIFIED  (no kernel output captured)          │       ║
║  └─────┬────────────────────────────────────────────────────────────┘       ║
║        │  exit code + exploit_run.log + serial_snippet.log                  ║
║        ▼                                                                     ║
║  ┌─────────────────────────────────────────────────────────────────────┐    ║
║  │                    REVIEWER  (Agent)                                │    ║
║  │                                                                     │    ║
║  │  Reads: writer_summary.md + exploit_run.log + serial_snippet.log   │    ║
║  │  Checks: all 6 source questions answered? YAML consistent?         │    ║
║  │          trigger actually ran (not simulation_only)?               │    ║
║  │          serial log checked (not just dmesg)?                      │    ║
║  │          post-trigger escalation push attempted?                   │    ║
║  │                                                                     │    ║
║  │  Verdict:                                                           │    ║
║  │    PASS      → Bookkeeper marks CVE finished / dos-oops / escalated│    ║
║  │    ISSUES    → Writer gets rerun with specific feedback appended   │    ║
║  └─────┬───────────────────────────────────────────────────────────────┘    ║
║        │                                                                     ║
║        ├──── PASS ──────────────────────────────────────────────────────►   ║
║        │                                                           BOOKKEEPER║
║        │                                                           updates   ║
║        │                                                           cve-list  ║
║        │                                                           status    ║
║        │                                                                     ║
║        └──── ISSUES ──────────────────────────────────────────────────────► ║
║                                                               feedback appended
║                                                               to EXPLOIT_WRITER_PROMPT
║                                                               → next rerun  ║
╠══════════════════════════════════════════════════════════════════════════════╣
║  INFRASTRUCTURE                                                              ║
║                                                                              ║
║   Host filesystem ──9p──► /mnt/angband (inside QEMU VM)                     ║
║   harness/launch.sh  ──►  QEMU VM  (KVM, -smep,-smap, 2 vCPU, 4 GB RAM)    ║
║   serial.log  ◄────────── ttyS0 (kernel panic / Oops / UBSAN output here)  ║
║   SSH :2222  ◄──────────  VM (health check + exploit execution)             ║
╚══════════════════════════════════════════════════════════════════════════════╝

Known Pipeline Bugs Fixed

The following pipeline defects have been identified, fixed, and must not recur:

Bug Symptom Fix Applied
Serial log not checked "0 new lines" but kernel crashed verify-cve.sh reads serial_snippet.log; UBSAN/KASAN patterns now match OOPS
UBSAN suppresses duplicates 2nd verify run shows 0 lines even though bug fires Restart VM between verify runs; UBSAN only reports each location once
verify-cve.sh OOPS pattern too narrow "UBSAN:" in serial not matched Added UBSAN:|KASAN:|slab-out-of-bounds|use-after-free to grep pattern
Placeholders not filled trigger prints "simulation_only" Step 5b mandatory: fill every placeholder before verify
Wrong stage ordering leak AFTER trigger; addresses stale KASLR resolve BEFORE trigger (CVE-2026-31533 lesson)
Spray queues full on re-spray 0 objects sprayed in rounds 2+ Drain queues (msgrcv IPC_NOWAIT) before each re-fill
NLM_F_ACK missing nl.recv() blocks forever Always set NLM_F_ACK on RTM_NEWROUTE netlink messages
Wrong enum constants -ERANGE on every attribute size Read kernel uapi header; enumerate constants, don't assume values

Pipeline Health Checks (run before each verify-cve.sh)

# 1. VM is alive and SSH works
ssh -i mordor_run/ssh/id_ed25519 -p 2222 -o ConnectTimeout=3 ubuntu@localhost whoami

# 2. Serial log is being written (size > 0)
wc -c mordor_run/harness/serial.log

# 3. Exploit binary exists and is not a demo placeholder
ls -la mordor_run/current/exploit
grep -c 'simulation_only\|implementation pending' mordor_run/current/exploit.c || echo 'no placeholders'

# 4. YAML is consistent (escalate.method != dirty_pagetable unless you have the primitive)
cat mordor_run/current/exploit.yaml | grep -E 'escalate|groom.*cache|trigger.*method'

Exploit Chaining / Vulnerability Pipelining

  • CVE-A provides a capability (e.g., info leak, CAP_SYS_TIME, KASLR bypass)
  • CVE-B provides a primitive (e.g., limited write, heap control)
  • CVE-C converts the primitive to privilege escalation

Capability Model

Each exploit stage provides and requires capabilities:

Capability Provider Consumer
kaslr_bypass CVE-A leak stage All CVEs that need kernel addresses
cap_net_admin Namespace creation macvlan netlink operations
kernel_write_primitive CVE with pcpu_stats/msg_msg corruption escalate stage
kernel_read_primitive CVE with info leak KASLR bypass, heap address leak
heap_address Info leak from UAF residual data Groom stage (precise reclaim)
kallsyms_access kptr_restrict=0 or namespace bypass Symbol resolution
arbitrary_free Double-free CVE Heap massage / reclaim

Pipeline Architecture (Proposed)

┌─────────────────────────────────────────────────────────────┐
│                    exploit_chain.yaml                        │
│  chain:                                                      │
│    - cve: CVE-2026-XXXX  # capability provider              │
│      provides: [cap_sys_time]                                │
│      output: { settime_capability: true }                    │
│    - cve: CVE-2026-YYYY  # escalation (or built-in)         │
│      requires: [kernel_write_primitive]                      │
│      escalate: modprobe_path                                  │
└─────────────────────────────────────────────────────────────┘

Data Flow Between Chained Exploits

  Stage(output) ──data──→ NextStage(input)
  
  Example: CVE-A leak → CVE-B primitive → CVE-C escalate
  
  kaslr_bypass output:  { kernel_base, modprobe_path_addr }
                         ↓
  primitive input:       { kernel_base, modprobe_path_addr }
  primitive output:      { corrupted_object_offset, write_value }
                         ↓
  escalate input:        { modprobe_path_addr, write_value }
  escalate output:       { root_shell }

How to Add Chaining to the Framework

Step 1: Extend YAML Config

Add requires and provides to the exploit.yaml stages:

Step 2: Add Capability Checker

Step 3: Add Pipeline Orchestrator

Step 4: Template Fragmentation

The generator composes: groom(timerfd) + trigger(timerfd) + leak(kallsyms) + primitive(timerfd) + escalate(modprobe)

Chaining Decision Tree

Can the exploit achieve escalation alone?
  ├── YES → Single CVE exploit (e.g., CVE-2026-23209)
  └── NO  → What is missing?
       ├── Missing capability (e.g., CAP_SYS_TIME)?
       │   └── Find CVE that provides it → CHAIN
       ├── Missing write primitive?
       │   └── Find CVE with OOB/UAF write → CHAIN  
       ├── Missing info leak?
       │   └── Find CVE with infoleak → CHAIN
       └── Fixed-offset/fixed-value writes only?
           └── Can we corrupt something that later yields exec?
               ├── YES → Deferred exploitation (complex chain)
               └── NO  → NOT exploitable with current CVEs

Implementation Priority

Priority Item Effort
P0 Add requires/provides to YAML schema Low
P0 Capability checker module Medium
P1 Pipeline orchestrator for multi-CVE chains High
P1 Template fragmentation into per-stage files High
P2 Shared context data passing between CVEs Medium
P2 Fallback/retry logic for failed stages Medium
P3 Automated CVE pairing (find complementary CVEs) Very High
P3 Chain verification in QEMU (multi-CVE execution) Very High