Cybersecurity research podcast

Automated Whitebox Fuzz Testing

SAGE executes concrete inputs, records x86 binary traces, symbolically collects input-dependent path constraints, negates selected predicates and solves them to generate new inputs. The authors report more than 30 previously unknown bugs in shipped Windows applications; exploitability remained their assessment. Coverage was not a universal predictor of crashes, and SAGE’s incomplete heuristic exploration cannot prove that unexplored paths or bugs are absent.

Episode 25 Aug 2026 · Paper 7 Feb 2008 · Network and Distributed System Security Symposium 2008 · VERSION of RECORD

Progress will be saved on this device
Listen continuously

Research summary

A technical explanation of the paper's research question, method, reported findings and limitations. The authors reported that SAGE found more than 30 previously unknown bugs in shipped Windows applications. Some appeared potentially exploitable, but that judgment came from the authors rather than an independent assessment. For a compressed format, the…

SAGE proved that expensive, incomplete symbolic reasoning could pay on real binaries and directly influenced production whitebox and hybrid concolic fuzzing. Modern practice is a portfolio: coverage for breadth, structure for valid inputs, selective constraints for hard predicates, environment models for realism, and agents for bounded planning. However, coverage and raw crash totals are weak proxies; judge independently confirmed unique exploitable defects per time and cost.

Paper details

Authors: Patrice Godefroid , Michael Y. Levin , David Molnar

Transcript

Highlighting follows the podcast. Select any word to seek.

Automated Whitebox Fuzz Testing. Patrice Godefroid, Michael Y. Levin, and David Molnar presented this work at the Network and Distributed System Security Symposium in 2008. Their system, SAGE, executes shipped binaries, tracks how input data affects branches, and solves altered branch conditions to generate new tests. The tension is whether this costly, deliberately incomplete reasoning can still uncover useful defects.

Whitebox fuzzing means generating tests with information obtained by analyzing the program’s execution. SAGE uses dynamic symbolic execution: it follows a real run while representing input-dependent values and branch decisions as symbolic expressions. Those decisions form a path constraint, meaning a set of conditions the original input satisfied along its route through the program. SAGE can reverse a selected condition and ask a solver for input bytes that satisfy the altered route. The resulting concrete file may steer the next execution toward code not previously reached. This combines observations from actual execution with mathematical reasoning about possible inputs.

The research question is not whether every program path can be explored; path explosion makes that infeasible. It is whether guided, heuristic exploration can find defects in realistic compiled software despite expensive analysis and incomplete models. Working from x86 binary traces allowed SAGE to test shipped programs produced from different source languages and build configurations. That makes the approach operationally interesting for binary-analysis and product-security teams. The relevant test is defect discovery under limited time and computing resources, while recognizing that an incomplete search cannot certify that the remaining program is safe.

SAGE begins with a concrete input and records the machine instructions executed while the target processes it. The system then replays that trace symbolically, collects the conditions influenced by input data, reverses selected conditions, and asks a constraint solver to construct new inputs. Its generational search produces many child tests from each expensive symbolic replay. It scores those children by newly executed code blocks and limits repeated attempts to reverse the same conditions. To reduce solver and trace costs, the implementation discards unrelated conditions, reuses previous work, and simplifies the remaining expressions. It can also substitute concrete values where symbolic modeling is difficult. That keeps analysis moving, but it sacrifices completeness and can send a generated test down a different path from the one predicted.

The authors reported that SAGE found more than 30 previously unknown bugs in shipped Windows applications. Some appeared potentially exploitable, but that judgment came from the authors rather than an independent assessment. For a compressed format, the generated tests exposed a stack overflow and an infinite loop, and those flaws were fixed within a week; additional read access violations were also fixed within a week. In selected media-parser comparisons, generational search explored substantially more tests and new code blocks than depth-first search, and it found crashing files in a case where the depth-first run found none. These results demonstrate useful defect discovery, not exhaustive analysis or proof that every crash represented a distinct exploitable vulnerability.

One experiment targeted the animated-cursor vulnerability. On a single processor core, SAGE generated a crashing input after 7 hours 36 minutes and 7,706 test cases. The search therefore took substantial time and many generations of inputs to reach the failure. In selected parser experiments, well-formed starting files tended to expose deeper behavior, and no single seed discovered every distinct crash cluster. Using varied starting inputs was operationally useful.

The evaluated prototype had two broad kinds of limitation. Its platform scope was narrow: it targeted deterministic x86 Windows applications that consume files, while networked or concurrent targets, other processor architectures, and whole-system hardware behavior were outside the evaluation. Its symbolic model was intentionally incomplete, so difficult program operations and effects outside the target could be replaced with concrete observations or missed. These constraints had practical consequences: predicted and actual paths sometimes diverged at rates above 60 percent, and individual symbolic tasks could take tens of minutes. Added block coverage did not consistently predict crashes in the reported comparisons. Path explosion also means SAGE can discover defects but cannot prove that unexplored paths contain none.

Later deployment evidence shows that the idea operated beyond the prototype. A Microsoft retrospective reported more than 400 machine-years of SAGE use across hundreds of applications and billions of processed constraints. Because this was Microsoft describing its own deployment, it should not be treated as an independently audited measure of effectiveness across the industry. Later hybrid fuzzers retained SAGE’s concrete-plus-symbolic idea while invoking solver-heavy analysis selectively. For current campaigns, the evidence supports a portfolio: fast coverage-guided mutation for broad exploration, grammars for structured inputs, and symbolic methods for tight input-dependent conditions. When comparing approaches, independently confirmed unique exploitable defects per unit time and cost are more defensible outcomes than raw coverage or crash totals alone.

Godefroid, Levin, and Molnar demonstrated that tracing x86 binaries and solving altered path conditions could uncover previously unknown defects in shipped Windows software, despite incomplete symbolic exploration. They did not demonstrate exhaustive exploration or applicability beyond the evaluated class of software, and they did not independently confirm every finding as exploitable. Security teams that analyze binaries or build fuzzing campaigns can use selective symbolic execution to cross difficult input checks. When campaigns plateau, they can combine it with complementary fuzzing methods and treat high block coverage, or a run without crashes, as evidence of exploration rather than safety.

Download plain-text transcript