Coverage-guided corpus fuzzer with real crash detection and two proof-of-concept targets
A Windows memory-corruption fuzzer in C demonstrating coverage-guided corpus fuzzing, real-world crash detection, and two contrasting targets:
- White-box BMP parser: Deliberately vulnerable target with hand-instrumented code-coverage probes, growing a real input queue based on edge coverage
- Black-box zlib 1.2.11: Unmodified production library pinned to CVE-2022-37434 (heap-buffer-overflow in gzip header parsing), demonstrating fuzzing against historical vulnerabilities
Features mutation-based fuzzing, crash deduplication by instruction pointer, exploitability heuristics, guard-zone allocator detection, and delta minimization. Built as a security research and portfolio project.
- Corpus-driven — maintains a real input queue that grows with edge coverage, not just a single mutating buffer
- Coverage-guided — hand-instrumented targets report which edges (instruction-ptr XOR'd pairs) they've reached; AFL-style bitmap tracks "ever seen" edges globally
- Mutation — bit flip, byte flip, byte set, insertion, deletion, chunk shuffle, interesting values, applied 1–4 times per input
- Structured exception handling — native Windows SEH wraps target execution, catching access violations, stack overflows, heap corruption, integer overflows inline
- Deduplication — crashes keyed by faulting instruction pointer (not just input hash), so the same bug reached via different mutations isn't re-reported
- Guard-zone allocator — redzone protection catches heap overflows that land inside a page and don't trigger hardware access violations (used by both targets)
- Exploitability scoring — heuristics rank crashes 0–100 based on address range (user-mode heap vs kernel), crash type, and input characteristics
- Crash minimization — delta debugging to reduce crash inputs to their minimal form
- Persistent crash corpus — minimized repros + metadata written to
crashes/
- BMP parser (
fuzz_bmp.exe): white-box, hand-instrumented for coverage guidance; three real integer-overflow bugs crafted to be exploitable - zlib 1.2.11 (
fuzz_zlib.exe): black-box, unmodified production code; pinned to last version before CVE-2022-37434 (heap-buffer-overflow in gzip header parsing)
- Extensible — shared
fuzz_engine.cparameterized by target function pointer and coverage flag; adding new targets is ~50 lines of code - Minimal dependencies — no libFuzzer, ASAN, Clang; uses only MSVC and Windows APIs
- Portfolio-ready — two contrasting targets (synthetic vs real, white-box vs black-box) demonstrate different fuzzing angles
Requirements:
- Windows 10+, x64
- Visual Studio 2022 with MSVC (
cl.exe)
build.batThis generates two fuzzers and their seed generators:
build\fuzz_bmp.exe— coverage-guided white-box target (BMP parser)build\fuzz_zlib.exe— black-box target (zlib 1.2.11 inflate)seeds\minimal_8bit.bmp— valid 8-bit BMP seed for BMP fuzzerseeds\minimal.gz— minimal gzip seed for zlib fuzzer
cd build
fuzz_bmp.exe ..\seeds\minimal_8bit.bmp 100000Expected output:
[*] Target: bmp (coverage-guided)
[*] Starting fuzzing with seed of 2102 bytes
[*] Iterations: 100000
[CRASH] [bmp] Type: 1, Site-hash: 0xb77b643f, Exploitability: 85%
[*] 10000 iterations, 1 unique crashes, 6 queue entries, 12/65536 edges
...
[+] Fuzzing complete. Found 2 unique crashes
=== CRASH REPORT: bmp ===
Crash #1:
Type: 1 (Access violation (likely buffer overflow or UAF))
Crash-site hash: 0xb77b643f
Exploitability: 85%
Input size: 2023 bytes (minimized from 2100)
cd build
fuzz_zlib.exe ..\seeds\minimal.gz 1000000This target reaches inflate()'s gzip header parsing code; while CVE-2022-37434 requires very specific header field combinations to trigger, the target is ready and documented for reference/research purposes.
src/target/bmp_parser.c intentionally includes memory-corruption bugs:
size_t palette_bytes = palette_size * sizeof(bmp_color_t); /* Can wrap */
img->palette = malloc(palette_bytes); /* Allocates undersized buffer */
memcpy(img->palette, data + offset, palette_bytes); /* Overflow into heap */Severity: High — exploitable buffer overflow
Trigger: Set colors_used to a value where palette_size * 4 wraps to a small number
size_t pixel_count = (size_t)width * (size_t)height; /* Can overflow */
size_t pixel_bytes = pixel_count * bytes_per_pixel; /* Undersized allocation */
img->pixel_data = malloc(pixel_bytes);Severity: High — exploitable buffer overflow
Trigger: Set width = 0x10000, height = 0x10000, causes allocation of ~65KB instead of 4GB
if (img->file_header.pixel_offset < len) {
size_t readable = len - img->file_header.pixel_offset;
size_t to_read = (readable < pixel_bytes) ? readable : pixel_bytes;
memcpy(img->pixel_data, data + img->file_header.pixel_offset, to_read);
/* If to_read < pixel_bytes, we read uninitialized heap memory */
}Severity: Medium — information leak + potential for use-after-free
The fuzzer categorizes crashes:
- Access violation — buffer over/underflow, UAF, invalid memory access
- Stack overflow — recursion or large stack allocation
- Heap corruption — corruption of heap metadata (detectable via runtime checks)
- Null dereference — dereferencing a NULL pointer
- Integer overflow — caught by Windows structured exception handling
- Abort — assertion or abort() call
Exploitability is scored 0–100 based on:
- Crash type (stack overflow = 90%, null deref = 30%)
- Faulting address (kernel space = lower score, heap = higher)
- Input characteristics (small inputs with null deref are often parsing errors)
See docs/methodology.md for detailed discussion of:
- Fuzzing strategies (mutation corpus, seed selection, triage)
- Memory corruption root causes and why these bugs are exploitable
- Windows structured exception handling for crash detection
- Practical fuzzing workflow for security research
Run the fuzzer against the vulnerable BMP parser:
fuzz_bmp.exe ..\seeds\minimal_8bit.bmp 1000000Typical output over 1M iterations on a modern machine:
- 3–8 unique crashes detected
- Most are the integer-overflow bugs in palette and pixel allocation
- Exploitability scores range 60–85% for heap overflows, 30–50% for parsing errors
Adding new targets is straightforward via fuzz_engine.c's fuzz_run() API:
fuzz_target_t my_target = {
.name = "jpeg",
.process = jpeg_process, // Your target function
.coverage_guided = 0, // Or 1 if you add COV_TRACE probes
};
fuzz_run(&my_target, seed_path, iterations, crashes_dir);Example targets:
- libpng — uncomment coverage probes in
png_read_png(), compile with fuzz_engine - libjpeg — wrap
jpeg_read_scanlines()similarly - Protocol parsers — wrap packet-handling functions; no image format required
- Windows-only — uses Windows structured exception handling; cross-platform requires POSIX/Linux signal handling
- Single-threaded — sequential execution; could parallelize over multiple processes (AFL++ style) for speed
- Instruction-pointer dedup only — crashes keyed by Rip, not a full call-stack hash (would require stack unwinding)
- Hand-instrumented coverage only — BMP target's COV_TRACE probes were added manually; production targets would need automatic instrumentation or binary instrumentation
- No taint tracking — doesn't track which input bytes influenced a crash; would speed up minimization and root-cause analysis
- zlib target has no coverage feedback — black-box fuzzing of unmodified zlib; adding coverage would require either source instrumentation or runtime code hooking
This fuzzer and the vulnerable target parser are for authorized security research, CTFs, and educational use only. Do not use this code to develop exploits for real systems you don't own or have permission to test.
MIT — see LICENSE.
- AFL — https://github.com/google/AFL; the inspiration for edge-coverage bitmap and corpus queue
- libFuzzer — https://llvm.org/docs/LibFuzzer/; coverage-guided fuzzing for C/C++
- zlib CVE-2022-37434 — https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-37434
- CWE-190 (Integer Overflow) — https://cwe.mitre.org/data/definitions/190.html
- CWE-680 (Buffer Overflow) — https://cwe.mitre.org/data/definitions/680.html
Built as a portfolio project demonstrating fuzzing tradecraft, memory-corruption vulnerability analysis, and Windows low-level crash detection for security research and penetration-testing roles.