fold/bench/corpora/ctf-challenges
trvon 9161ed2b98
eval: CTF binary scan — 3.7% binary detection vs 66.7% source
- Binary scan: 1/27 findings (only gets() import detected)
- Source scan: 18/27 findings (66.7% TP rate)
- Fuzz harnesses: generated but cov:2 (Swift ABI issue)
- Binary backend needs significant improvement
2026-05-29 20:03:07 -04:00
..
libvuln_demo.dylib.dSYM/Contents eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
src eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
.gitignore eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
ANALYSIS.md eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
fetch.sh eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
fold-results.json eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libbof_overflow.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libcmd_injection.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libdiv_by_zero.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libformat_string.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libFuzzMeSwift.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libint_overflow.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libnull_deref.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libtest_fuzz.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libuaf_doublefree.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
libvuln_demo.dylib eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00
README.md eval: CTF binary scan — 3.7% binary detection vs 66.7% source 2026-05-29 20:03:07 -04:00

CTF Challenge Binaries for Fold Binary Validation

Binary-analysis validation corpus for fold scan --mode binary. Contains hand-authored vulnerable C programs and a fetcher for public picoCTF challenge source. Each binary targets x86_64 ELF (Linux) and/or ARM64 Mach-O (macOS) so both r2 backend paths are exercised.


Quick Start

# 1. Fetch picoCTF sources + compile all binaries
./fetch.sh

# 2. List what was built
./fetch.sh --list

# 3. Run fold binary scan on one binary
fold scan --mode binary --binary bin/vuln-demo-arm64-macho \
  --detectors binary-null-deref,binary-security,security \
  --format json --output /tmp/ctf-results.json

# 4. Clean all artifacts (keeps src/) 
./fetch.sh --clean

Binary Inventory

1. vuln-demo (src/vuln_demo.c) — Custom C Test Harness

Hand-authored C program with three intentional vulnerability classes. Designed to be compiled as a small, non-stripped binary so fold's r2 backend can extract strings, symbols, calls, and simple heuristics.

Architecture Binary Path Status
ARM64 Mach-O bin/vuln-demo-arm64-macho Native (macOS)
x86_64 Mach-O bin/vuln-demo-x86_64-macho Cross-compiled (macOS)
x86_64 ELF bin/vuln-demo-x86_64-elf Docker (Linux musl)

Vulnerabilities

# CWE Trigger What Fold Should Detect
1 CWE-121 ./vuln-demo bo AAAA... Stack buffer overflow via strcpy into 16-byte array without bounds check. Fold binary backend should flag the strcpy call with a binary-security finding.
2 CWE-134 ./vuln-demo fmt "%x %x %x" User-controlled format string passed directly to printf. Fold binary backend should flag printf with a format-string heuristic.
3 CWE-416 ./vuln-demo uaf free(p) followed by dereference of p. Fold binary backend should detect the free→load pattern as use-after-free via binary-null-deref or binary-security.

Expected file output

bin/vuln-demo-arm64-macho:   Mach-O 64-bit executable arm64
bin/vuln-demo-x86_64-macho:  Mach-O 64-bit executable x86_64
bin/vuln-demo-x86_64-elf:    ELF 64-bit LSB executable, x86-64, statically linked

2. pico2022-buffer-overflow-0 (src/pico2022-buffer-overflow-0.c)

Source: picoCTF 2022 — Binary Exploitation / buffer overflow 0 CWE: CWE-121 (Stack-based buffer overflow) Original: LeonGurin/picoCTF-2022 GitHub mirror

Architecture Binary Path Status
ARM64 Mach-O bin/pico2022-buffer-overflow-0-arm64-macho Native (macOS)
x86_64 Mach-O bin/pico2022-buffer-overflow-0-x86_64-macho Cross-compiled (macOS)
x86_64 ELF bin/pico2022-buffer-overflow-0-x86_64-elf Docker (Linux musl)

What Fold Should Detect

  • A gets or unbounded read into a small stack buffer triggers a SIGSEGV on large input.
  • Fold's binary backend should extract the gets/strcpy symbol, note the small stack allocation, and emit binary-security.

3. pico2023-vne-arm64 (src/pico2023-vne-arm64.c)

Source: picoCTF 2023 — Reverse Engineering / VNE Architecture: ARM64 (originally distributed as an ARM64 binary) Original: Dvd848/CTFs GitHub mirror

Architecture Binary Path Status
ARM64 Mach-O bin/pico2023-vne-arm64-arm64-macho Native (macOS)
x86_64 ELF bin/pico2023-vne-arm64-x86_64-elf Docker (Linux musl)

What Fold Should Detect

  • The VNE challenge involves reading an environment variable (SECRET_DIR) and performing file-system operations with insufficient path sanitization.
  • Fold's binary backend should extract getenv, open, read symbols, flagging them under binary-security as environment-influenced file access.

Fold Binary Scan Recipes

Basic binary scan

fold scan --mode binary --binary bin/vuln-demo-arm64-macho \
  --detectors binary-security,binary-null-deref,security \
  --format json | python3 -m json.tool

Hybrid scan (if source compile DB is available)

fold scan --mode hybrid \
  --compile-db compile_commands.json \
  --binary bin/vuln-demo-arm64-macho \
  --detectors binary-security,binary-null-deref,security,dead,equiv \
  --format json --output /tmp/hybrid-results.json

Batch scan all CTF binaries

for bin in bin/*-arm64-macho; do
  echo "=== $bin ==="
  fold scan --mode binary --binary "$bin" \
    --detectors binary-security --format markdown
done

Build Requirements

Environment Requirement
macOS (native) Xcode CLT / clang supporting -arch arm64 and -arch x86_64
Docker (ELF) docker daemon running; alpine:latest pulled automatically

Manual compilation (no fetch.sh)

# ARM64 Mach-O (macOS)
clang -O0 -g -fno-stack-protector -arch arm64 src/vuln_demo.c -o bin/vuln-demo-arm64-macho

# x86_64 Mach-O (macOS, cross)
clang -O0 -g -fno-stack-protector -arch x86_64 src/vuln_demo.c -o bin/vuln-demo-x86_64-macho

# x86_64 ELF (Linux, via Docker)
docker run --rm --platform linux/amd64 \
  -v "$PWD/src/vuln_demo.c:/src/vuln_demo.c:ro" \
  -v "$PWD/bin:/out" \
  alpine:latest \
  sh -c 'apk add --no-cache gcc musl-dev && gcc -O0 -g -fno-stack-protector -no-pie -static /src/vuln_demo.c -o /out/vuln-demo-x86_64-elf'

File Layout

bench/corpora/ctf-challenges/
├── README.md          # This file
├── fetch.sh           # Download + compile script
├── src/
│   ├── vuln_demo.c    # Custom C binary with CWE-121, CWE-134, CWE-416
│   ├── pico2022-buffer-overflow-0.c  # (fetched)
│   └── pico2023-vne-arm64.c          # (fetched)
└── bin/               # Compiled binaries (gitignored)
    ├── vuln-demo-arm64-macho
    ├── vuln-demo-x86_64-macho
    ├── vuln-demo-x86_64-elf
    ├── pico2022-buffer-overflow-0-arm64-macho
    ├── pico2022-buffer-overflow-0-x86_64-macho
    ├── pico2022-buffer-overflow-0-x86_64-elf
    ├── pico2023-vne-arm64-arm64-macho
    └── pico2023-vne-arm64-x86_64-elf

Confidence Expectations

Because these are binary-mode scans (no source IR, no Z3 path predicate), all findings carry heuristic or syntactic confidence. Do not expect proved.

Detector Typical Confidence Notes
binary-security heuristic String/symbol/call patterns match known-dangerous APIs
binary-null-deref heuristic Null-check absence near allocation or free sites
security heuristic Aggregated binary security heuristics

For proved confidence on the same vulnerabilities, run the source C files through fold scan --mode source --compile-db ... with the source detectors.

Known Limitation: Mach-O Stub Sections

The fold binary backend skips symbols in ELF .plt / Mach-O __stubs sections (see R2Backend::runDetectors in src/binary/r2_backend.cpp). On macOS, all external library calls (gets, strcpy, printf, etc.) are routed through __TEXT.__stubs, which means binary-security will produce 0 findings for dynamically-linked Mach-O binaries.

Workarounds:

  • Use x86_64 ELF binaries built via Docker (./fetch.sh on Linux or Docker-enabled macOS). ELF .plt.got entries are handled differently.
  • Staticaly link on macOS: clang -static src/vuln-demo.c -o bin/vuln-demo-static (requires a static libc; not standard on macOS).
  • Use source mode instead: fold scan --mode source --compile-db ... for proved confidence on the same vulnerabilities.

Observed Scan Results (ARM64 Mach-O, 2026-05-29)

$ fold scan --mode binary --binary bin/vuln-demo-arm64-macho \
    --detectors binary-security,binary-null-deref,security --format json

emitted 0 findings total

$ fold scan --mode binary --binary bin/pico2022-buffer-overflow-0-arm64-macho \
    --detectors binary-security,binary-null-deref,security --format json

emitted 0 findings total

These binaries are valid test vectors even with 0 findings: they exercise the r2 session setup, JSON command dispatch, symbol/import extraction, and section filtering paths. When the stub-section filtering is relaxed or ELF builds are added, they will start producing findings.


References