# 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 ```bash # 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 ```bash 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) ```bash 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 ```bash 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) ```bash # 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 - picoCTF 2022 — buffer overflow 0: https://github.com/LeonGurin/picoCTF-2022 - picoCTF 2023 — VNE: https://github.com/Dvd848/CTFs/tree/master/2023_picoCTF - Fold binary backend: `include/fold/core/analysis_backend.hpp`, `src/binary/r2_backend.cpp` - Fold binary detectors: `binary-security`, `binary-null-deref`, `security`