Automated vulnerability discovery for C/C++ targets via LLM-driven harness synthesis, coverage-guided fuzzing (AFL++/libFuzzer), and crash triage.
| Runtime | Python 3.11+ |
| License | MIT |
| Fuzzers | AFL++, libFuzzer |
| Sanitizers | ASan, UBSan |
| Orchestration | Temporal |
| Status | Pre-alpha |
crashwise run https://github.com/madler/zlibClone → Build (ASan+UBSan+source-cov) → Harness Synthesis → Fuzz → Triage → Report
↑ │
└── Self-Correction Loop ──┘
- Scans public headers, resolves typedefs, scores entry points by attack surface
- LLM generates a
LLVMFuzzerTestOneInputharness; validates compilation + 5s sanity gate - On failure: GDB backtrace → LLM diagnosis → fix → retry (max 3 attempts)
- Executes AFL++/libFuzzer in sandboxed Docker containers with coverage feedback
- On plateau: identifies blocker (magic value, length check, checksum, state machine), rewrites harness
- Classifies crashes by type, deduplicates by stack hash, scores exploitability
git clone https://github.com/yahyatoubali/Crashwise.git && cd Crashwise
pip install -e .
docker compose up -d# .env (minimum)
CRASHWISE_LLM_MODEL=claude-sonnet-4-5
ANTHROPIC_API_KEY=sk-ant-...crashwise run --timeout 600 https://github.com/madler/zlibSee docs/INSTALL.md for full setup.
| Command | Description |
|---|---|
crashwise init |
Detect build system, generate crashwise.yaml manifest |
crashwise run <repo-url> |
Submit fuzzing campaign (blocking) |
crashwise run --detach <url> |
Submit and return immediately |
crashwise doctor |
Validate system prerequisites |
crashwise setup |
Install missing build dependencies |
crashwise dashboard |
Launch Streamlit UI on localhost:8501 |
crashwise signal <id> pause_hunt |
Pause a running campaign |
crashwise signal <id> force_pivot |
Force MAB strategy switch |
| Variable | Description |
|---|---|
CRASHWISE_LLM_MODEL |
Model identifier for harness synthesis |
ANTHROPIC_API_KEY |
API key (or equivalent for chosen provider) |
| Variable | Default | Description |
|---|---|---|
AI_PROVIDER |
(disabled) | Crash triage backend: ollama, venice, openai_compatible |
AI_MODEL |
— | Model for triage (e.g., llama3.1:8b) |
OLLAMA_URL |
http://localhost:11434 |
Ollama endpoint |
DATABASE_URL |
sqlite+aiosqlite:///./crashwise.db |
Async SQLAlchemy URL |
REDIS_URL |
redis://localhost:6379/0 |
Redis for distributed state |
TEMPORAL_HOST |
localhost:7233 |
Temporal server address |
Supported LLM providers: Anthropic, OpenAI, NVIDIA NIM, Together AI, Groq, Ollama, vLLM, any OpenAI-compatible endpoint.
┌──────────────────────────────────────────────────────────────┐
│ CLI / API / Dashboard │
├──────────────────────────────────────────────────────────────┤
│ Temporal Workflows (durable, retryable) │
│ └─ MainFuzzingWorkflow → 23 Activities │
├──────────────────────────────────────────────────────────────┤
│ AI Agents (LangGraph) │
│ ├─ Harness Synthesis (analyze → generate → validate → retry)│
│ ├─ Coverage Analysis (blocker identification + dict gen) │
│ ├─ Crash Triage (ASAN/GDB → severity → dedup) │
│ └─ Exploit Generation (PoC synthesis) │
├──────────────────────────────────────────────────────────────┤
│ Execution (Docker sandbox) │
│ ├─ AFL++ (multi-strategy, Thompson Sampling MAB) │
│ ├─ libFuzzer (in-process, coverage-guided) │
│ └─ QEMU/KVM (kernel targets) │
├──────────────────────────────────────────────────────────────┤
│ Storage: PostgreSQL │ Redis │ R2/S3 │ SQLite (dev) │
└──────────────────────────────────────────────────────────────┘
- Regex-based static analysis of
.hfiles identifies function declarations - Typedef resolution maps library-specific types to canonical C types (
Bytef→unsigned char) - Entry points scored by argument shape:
(const uint8_t*, size_t)= 1.0,(const char*)= 0.7 - LangGraph state machine:
analyze_code → generate_harness → validate_harness → [retry|end] - Struct definitions extracted from headers and injected into LLM context
- Usage examples mined from
test/andexamples/directories
- Source-based coverage via
-fprofile-instr-generate -fcoverage-mapping llvm-cov exportproduces line-level hit/miss data (lcov format)- Coverage analyzer identifies blockers: magic values, length checks, checksums, state machines, null guards
- Dictionary generator extracts comparison literals into
custom.dictfor token-aware mutation - MAB strategist (Thompson Sampling) pivots between 5 fuzzer configurations on plateau
Every fuzzer container runs with:
| Constraint | Value |
|---|---|
| Network | --network none |
| Filesystem | --read-only |
| Capabilities | --cap-drop ALL |
| PIDs | --pids-limit 1024 |
| Scratch | Size-capped tmpfs on /tmp and /dev/shm |
| Disk quota | --storage-opt size=5G (overlay2+xfs+pquota) |
AFL++ containers additionally receive
--cap-add SYS_PTRACEfor forkserver operation.
Built on Temporal:
- Campaigns survive worker crashes; activities resume from last heartbeat
- Exponential backoff retry with non-retryable error classification
- Horizontal scaling via additional worker processes
- God-Mode signals:
pause_hunt,force_pivot,inject_seedfor live operator control
See docs/architecture.md for the full technical reference.
| Compatible | Requires Manual Tuning | Unsupported |
|---|---|---|
| C/C++ libraries with CMake/Make/Meson | Bazel builds, complex monorepos | Closed-source binaries |
| Parser libraries (image, archive, crypto, font) | Custom toolchains, autotools edge cases | Windows-only (MSVC) |
| Projects with existing fuzz harnesses | Deeply nested struct-init APIs | Managed languages |
Standard (buf, size) entry points |
Callback-driven APIs (SAX parsers) | Network daemons (stateful protocols) |
Validated targets: zlib, libpng, libjpeg-turbo, freetype, openssl, libxml2, harfbuzz, libarchive, pcre2.
| Class | Sanitizer |
|---|---|
| Heap/stack buffer overflow | ASan |
| Use-after-free, double-free | ASan |
| Null pointer dereference | ASan (SIGSEGV) |
| Integer overflow | UBSan |
| Uninitialized reads | ASan (partial) |
| Class | Reason |
|---|---|
| Race conditions / TOCTOU | Single-threaded harnesses; no TSan |
| Deadlocks, livelock | No thread scheduling manipulation |
| Logic bugs in async code | Incompatible with byte-mutation model |
| Timing side-channels | Requires statistical analysis, not fuzzing |
CrashWise generates single-threaded
LLVMFuzzerTestOneInputharnesses instrumented with ASan+UBSan only. Concurrency bugs require ThreadSanitizer or rr.
git clone https://github.com/yahyatoubali/Crashwise.git && cd Crashwise
uv sync # or: pip install -e ".[dev]"
uv run pytest tests/ -v # test
uv run ruff check crashwise/ # lint
uv run mypy crashwise/ # type checkMIT — see LICENSE.
Built by Yahya Toubali.