Meta Bug Bounty — Fuzzing "netconsd" for Fun and Profit — Part 3
The final installment: generating meaningful fuzz corpora using real kernel messages and symbolic execution with Klee, minimizing test cases, then running a full AFL++ fleet with 20+ instances using different coverage strategies and custom mutators.
Why Corpus Generation Matters
A fuzzer is only as good as its starting seeds. Good initial test cases dramatically improve code coverage by guiding the fuzzer toward structurally valid inputs that exercise deeper code paths — rather than spending all cycles on trivially invalid inputs.
Method 1: Real Kernel Messages from /dev/kmsg
The simplest and most authentic source of test cases is your own machine's kernel log stream:
Each line represents a real netconsole message in the exact format netconsd expects. Some lines were stored individually; others were grouped together to exercise the fragment reassembly code that was the key to finding the heap overflow.
Method 2: Symbolic Execution with Klee
Klee is a symbolic execution engine that explores program paths mathematically, generating inputs that exercise different branches. Using Klee requires modifying the harness to use a symbolic input buffer:
What is Symbolic Execution?
Instead of running programs with concrete values, symbolic execution treats inputs as symbolic variables and explores multiple code paths simultaneously — automatically generating test cases that satisfy different branch conditions.
Running Klee in Docker
Optimizing the Corpus
Collecting thousands of test cases from both /dev/kmsg and Klee
creates lots of redundancy. Two AFL++ tools minimize this before fuzzing:
- afl-cmin: Removes inputs that cover the same code paths (deduplication)
- afl-tmin: Shrinks each individual test case to its minimal crashing/covering form
The Full Fuzzing Setup
The Makefile compiles the harness with multiple coverage strategies for maximum path exploration:
Running 20+ AFL++ Instances in tmux
Conclusion & Results
After running the full fleet for an extended period, AFL++ discovered the heap overflow in netconsd's fragment reassembly code. Coverage analysis showed near-100% block coverage of the parser code — meaning the fuzzer exercised virtually every reachable code path.
- The bug was caused by improper bounds checking in
ncfragoffset arithmetic when assembling message fragments - The crash was reproducible against the real netconsd daemon, confirming exploitability
- The vulnerability was reported to Meta and fixed
- The complete fuzz harness source is available at: github.com/fadyosman/netconsd_ncrx_fuzz
Build Your Security Research Skills with ZINAD
ZINAD's training programs cover binary exploitation, fuzzing methodologies, and vulnerability research — the same techniques used in this series. Our experts also provide hands-on application security assessments and red team engagements.
https://ZINAD.net/support-page.htmlWritten by Fady Othman, Co-founder and Director of R&D at ZINAD.
