FUZZUER: Enabling Fuzzing of UEFI Interfaces on EDK-2
Connor Glosner (Purdue University)
Network and Distributed System Security (NDSS) Symposium 2025 · Day 2 · Fuzzing 1
Overview
The "FUZZUER: Enabling Fuzzing of UEFI Interfaces on EDK-2" talk, presented by Connor Glosner from Purdue University, introduces a novel framework for automatically generating fuzzing harnesses and identifying vulnerabilities in UEFI (Unified Extensible Firmware Interface) firmware. The research addresses the critical security implications of firmware vulnerabilities, highlighted by recent incidents like LogoFAIL in 2023, where memory corruption bugs in UEFI led to arbitrary code execution during the boot process. These vulnerabilities can enable sophisticated bootkits and rootkits, often requiring no special privileges to exploit, as demonstrated by the 24 CVEs issued across 11 different vendors in the LogoFAIL incident.
Key moments
- 0:00 Introduction and LogoFail 2023 motivation
- 1:00 Understanding UEFI firmware and its boot process
- 2:30 Key challenges in fuzzing UEFI interfaces
- 3:30 FUZZUER's three core components solution
- 4:00 Furnace: Reaching definition analysis for input
- 5:45 Furnace: Call site analysis for argument types
- 6:15 Furnace: Templated harness generation for structured input
FUZZUER: Enabling Fuzzing of UEFI Interfaces on EDK-2
Speakers: Connor Glosner (Purdue University)
Conference: NDSS Symposium
YouTube: https://www.youtube.com/watch?v=qhpCzHJVOAU
Overview
The "FUZZUER: Enabling Fuzzing of UEFI Interfaces on EDK-2" talk, presented by Connor Glosner from Purdue University, introduces a novel framework for automatically generating fuzzing harnesses and identifying vulnerabilities in UEFI (Unified Extensible Firmware Interface) firmware. The research addresses the critical security implications of firmware vulnerabilities, highlighted by recent incidents like LogoFAIL in 2023, where memory corruption bugs in UEFI led to arbitrary code execution during the boot process. These vulnerabilities can enable sophisticated bootkits and rootkits, often requiring no special privileges to exploit, as demonstrated by the 24 CVEs issued across 11 different vendors in the LogoFAIL incident.
FUZZUER specifically targets the DXE phase (Driver Execution Environment) of the UEFI boot process, focusing on drivers accessible from the UEFI shell. This area is particularly ripe for discovery due to the complex and often underspecified interfaces that characterize UEFI development. The project's core contribution is Furnace, a static analysis-assisted system for automated, source-level harness generation, designed to overcome the unique challenges of fuzzing UEFI, such as generic data types and state-dependent interactions.
By enabling robust, coverage-guided fuzzing for UEFI, FUZZUER provides a crucial tool for enhancing the security posture of modern computing systems. The ability to automatically generate effective harnesses and detect bugs in an environment as foundational as firmware represents a significant step forward in proactive vulnerability research and defense, moving beyond labor-intensive manual approaches.
Background
▶ Watch: Introduction and LogoFail 2023 motivation (0:00)
UEFI stands as the foundational firmware for modern computing systems, defining a standardized specification for how firmware components interact. This modular design allows vendors to independently develop drivers for their hardware, fostering interoperability and accelerating development. Beyond basic hardware initialization, UEFI introduces crucial security features like Secure Boot and provides a more user-friendly interface compared to its BIOS predecessor.
The UEFI boot process unfolds in four distinct phases. FUZZUER specifically concentrates on the DXE phase, or Driver Execution Environment. This phase is critical because it's where most user interaction interfaces and drivers are loaded and exposed, making it a prime target for attackers seeking to establish persistence or compromise system integrity early in the boot chain.
Fuzzing UEFI presents a unique set of challenges. One primary hurdle stems from the highly generic and often underspecified nature of UEFI interfaces. Many data types are defined as void*, leaving their actual structure ambiguous. For instance, a function like GetInfo might accept a void* argument, which could represent an MTFP packet in one context or a TFTP packet in another. This lack of explicit type information makes it exceedingly difficult for traditional fuzzers to generate meaningful, structured input. Another significant challenge is the generation of state-dependent data. The UEFI environment is asynchronous, characterized by interrupts and unpredictable function calls. Crafting inputs that correctly reflect the system's current state and trigger specific code paths requires an understanding of intricate dependencies, a task that is nearly impossible with purely random input generation.
Prior research and tools have attempted to address UEFI security, but often with limitations. Tools like RS Fuzzer, Chipseck, and Excite focused on a subset of drivers that could be accessed from the operating system, rather than the core firmware environment. HBFA (Host-Based Firmware Analyzer), which FUZZUER was compared against, operates by stubbing out drivers and relying on manually written harnesses. While effective to a degree, this approach is resource-intensive and requires significant domain expertise. Lastly, SIM Fuzzer injects random data directly into memory and can create boot process snapshots, but it is a closed-source, naive fuzzer, limiting its utility for comparison and community adoption. These existing solutions either cover a limited scope, require extensive manual effort, or lack the sophistication needed to effectively navigate UEFI's complex, stateful interfaces, leaving a significant gap that FUZZUER aims to fill.
Key Findings
▶ Watch: Key challenges in fuzzing UEFI interfaces (2:30)
The FUZZUER framework demonstrated remarkable effectiveness in uncovering vulnerabilities and improving code coverage within the complex UEFI environment. Its primary contributions and findings include:
- Significant Bug Discovery: FUZZUER successfully identified 20 new bugs within the EDK-2 implementation of UEFI. Approximately half of these reported vulnerabilities have already been confirmed by vendors, with the remainder still under review. This high rate of discovery underscores the framework's ability to pinpoint critical flaws in a previously challenging attack surface.
- Superior Code Coverage: The research showed that FUZZUER, with all its analysis techniques enabled, achieved significantly greater code coverage compared to both a random fuzzer and HBFA (Host-Based Firmware Analyzer), the closest comparable tool. This improvement in coverage is attributed to FUZZUER's ability to generate complex, stateful data types, allowing the fuzzer to reach deeper into the code and traverse blocking statements that would otherwise prevent exploration.
- Outperformance Against HBFA: In a direct comparative evaluation, FUZZUER not only achieved higher code coverage but also found 3 specific bugs that HBFA, despite its reliance on manually written, expert-crafted harnesses, was unable to discover. This highlights the limitations of manual approaches and the advantages of an automated system, especially for complex and evolving firmware.
- Validation of Automated Harness Generation: The success of FUZZUER, particularly its Furnace component, validated the effectiveness of static analysis-assisted, automated harness generation. The automatically generated harnesses were noted to be of greater size and complexity than typical manually written ones, emphasizing the need for an automated system to overcome the challenges of fuzzing UEFI interfaces without requiring extensive manual expertise.
- Effective Handling of Generic Types: The static analysis performed by Furnace proved highly effective at collecting and analyzing
void*and other generic types, accurately determining their most probable assignments through frequency analysis and heuristics. This capability was crucial for generating structured input where type information was initially ambiguous. - Importance of Points-To Analysis: Early variations of the fuzzer that lacked points-to analysis performed significantly worse. The study concluded that points-to information was essential for correctly tracking back to function definitions and understanding call site information, enabling the fuzzer to effectively navigate the system table and generate accurate inputs.
Overall, FUZZUER's key findings underscore its role as a powerful, automated solution for enhancing UEFI security, demonstrating superior bug-finding capabilities and code coverage through its innovative approach to harness generation and low-level instrumentation.
Technical Deep Dive
▶ Watch: FUZZUER's three core components solution (3:30)
The FUZZUER framework is ingeniously structured around three core components: Furnace for static analysis-assisted harness generation, Sanitation for low-level memory error detection, and the fuzzer itself, which orchestrates the input generation and execution within a simulated environment.
Furnace: Static Analysis-Assisted Harness Generation
Furnace is the intellectual core of FUZZUER, designed to overcome the challenges of generating structured input for UEFI's generic interfaces. It produces source-level C harnesses, ensuring flexibility and portability across different EDK-2 implementations. Furnace operates in three main stages:
- Reaching Definition Analysis:
This initial step focuses on a target function (the function to be fuzzed) and its arguments. The analysis systematically collects all assignments to these arguments throughout the codebase. This includes assignments from constants, assignments resulting from external function calls (which are termed "generator functions"), and direct assignments. The information is mapped across all functions in the codebase, with assignments stored in a stack order. This ordering is crucial for correctly parsing data later, ensuring that the most recent assignment to a variable or argument is tracked. For instance, if a variable packet is set by GetInfo and then later used in SetPackets, this analysis tracks the flow and the origin of packet's value.
- Call Site Analysis:
The output from the reaching definition analysis serves as input for the call site analysis. Here, Furnace parses all call sites for the target functions of interest, as well as any identified generator functions. The critical distinction of FUZZUER is that this analysis is performed at the AST (Abstract Syntax Tree) level rather than the lower-level IR (Intermediate Representation). This choice is deliberate, as operating at the AST level preserves richer type information, preventing it from being degraded to simpler, generic structures often found in IR. For each argument at every call site, Furnace collects its direction (input, output, or both), its type, and the assignment source (e.g., a specific generator function like GetInfo). The analysis also accounts for potential multiple values an argument might take due to different execution paths or branching logic. EDK-2's specific qualifiers for argument direction (IN, OUT) are leveraged here as heuristics to simplify the determination of data flow, though additional analysis handles complex INOUT cases.
- Templated Harness Generation:
In the final stage, all the collected information is fed into the templated harness generation module. This module analyzes the argument types, especially addressing the problematic void* types. For void* arguments, Furnace employs frequency analysis across the codebase to determine the most probable actual type or structure that the void* typically represents in that context. This is augmented by UEFI-specific heuristics, such as recognizing EFI_EVENT as a distinct type rather than a generic void*, to ensure highly accurate type resolution.
The module then synthesizes these elements to construct a source-level C harness. This harness includes calls to the target function with structured inputs. Crucially, if an argument's value is derived from a generator function, Furnace recursively applies the same analysis to that generator function, ensuring that the stateful input generated by it is also structured and valid. This recursive approach ensures that even complex, multi-stage state dependencies are correctly modeled in the fuzzer input. The resulting harness integrates "random" scalar values from the fuzzer's input stream with the structured, stateful data generated by these internal function calls.
Sanitation
To effectively detect memory corruption bugs in the low-level UEFI environment, FUZZUER integrates ASAN (AddressSanitizer). The project involved designing and injecting ASAN runtime libraries specifically tailored for EDK-2. A significant challenge in this adaptation was managing memory at the physical level, requiring careful implementation to ensure ASAN's capabilities could operate correctly without interfering with the firmware's delicate memory management.
The Fuzzer
For the actual fuzzing execution, FUZZUER employs a modified version of Intel's targeted software fuzzer for Simics. Simics is a high-fidelity system simulator, chosen over alternatives like QEMU for its ability to provide more comprehensive hardware feature emulation, which is crucial for accurately simulating the UEFI environment. FUZZUER made minor modifications to this fuzzer to enhance its coverage information collection capabilities. The fuzzer app runs directly on the UEFI shell within the Simics simulated environment, leveraging LibAFL as its underlying coverage-guided fuzzing engine to call the interfaces of interest with the harnesses generated by Furnace.
This integrated approach, combining sophisticated static analysis for input generation, low-level memory error detection, and high-fidelity simulation, allows FUZZUER to effectively navigate and fuzz the intricate landscape of UEFI firmware.
Demo / Proof of Concept
▶ Watch: Furnace: Call site analysis for argument types (5:45)
While the talk did not feature a live, interactive demonstration of FUZZUER in action, the effectiveness of its core component, Furnace, and its generated harnesses was conceptually demonstrated and validated through illustrative code examples and, more importantly, the robust bug-finding and coverage results.
The speaker presented an "example harness" in the form of a C code snippet, which visually conveyed how the system combines fuzzer-provided random input with structured, stateful data. This example illustrated a scalar value being read from the fuzzer's input stream, along with structured input generated by a "generator function" like GetInfo. This GetInfo function would create the necessary stateful data, which would then be correctly passed into the target function, SetPackets. This visual representation served to demonstrate the practical output of Furnace's templated harness generation, showcasing how the tool transforms complex static analysis findings into actionable, executable code for fuzzing.
Furthermore, the extensive evaluation, which included the discovery of 20 new bugs and a direct comparison against the HBFA framework, served as a compelling proof of concept. The ability of FUZZUER to find bugs that HBFA missed and achieve superior code coverage, particularly when dealing with complex data types and state dependencies, unequivocally validated the framework's design and implementation. These results, rather than a live demo, concretely demonstrated that FUZZUER's automated, static analysis-driven approach to harness generation is a viable and highly effective method for securing UEFI interfaces.
Defensive Implications
▶ Watch: Furnace: Templated harness generation for structured input (6:15)
The findings from FUZZUER have profound implications for the defensive posture of modern computing systems, particularly concerning UEFI firmware security. Given the critical role of UEFI at the very foundation of the boot process, vulnerabilities here can lead to highly persistent and difficult-to-detect compromises, as exemplified by the LogoFAIL incident.
Here are key defensive implications:
- Prioritize UEFI Fuzzing: Vendors and security teams developing or deploying UEFI firmware must recognize the DXE phase as a critical attack surface. Proactive, automated fuzzing of UEFI interfaces, especially those accessible from the shell, should become a standard part of their security development lifecycle.
- Embrace Automated Harness Generation: The limitations of manual harness creation, highlighted by HBFA's performance against FUZZUER, underscore the necessity of automated tools. Security teams should invest in or adopt solutions that can automatically generate structured, state-aware inputs for fuzzing complex firmware interfaces. This minimizes reliance on scarce domain expertise and accelerates the vulnerability discovery process.
- Integrate Low-Level Sanitizers: The successful adaptation of ASAN for EDK-2 demonstrates that robust memory error detection tools can be integrated into low-level firmware environments. Defenders should push for the inclusion of such sanitizers during firmware development and testing to catch common memory corruption bugs early.
- Focus on Generic Type Resolution: The challenges posed by
void*and other generic types in UEFI are significant. Firmware developers should strive for more explicit type definitions where possible. For fuzzing, defensive tools need to incorporate sophisticated static analysis techniques, similar to Furnace's frequency analysis and heuristics, to correctly infer and generate inputs for these ambiguous types. - Leverage High-Fidelity Simulation: The use of Simics for fuzzing, providing higher fidelity emulation than QEMU, indicates the importance of an accurate execution environment. Defenders should utilize or advocate for simulation platforms that can faithfully replicate hardware behavior to ensure fuzzing results are reliable and transferable to real-world systems.
- Open-Source Contribution: FUZZUER's open-source nature (as stated by the speaker) encourages collaborative security research. Firmware vendors and security researchers should engage with and contribute to open-source fuzzing frameworks to collectively improve UEFI security.
- Continuous Fuzzing: Firmware is not static; it evolves with new features and hardware. A continuous fuzzing pipeline, integrated into CI/CD workflows, is essential to catch new vulnerabilities introduced during updates or feature additions.
By adopting these defensive strategies, organizations can significantly enhance their ability to identify and mitigate UEFI vulnerabilities, thereby bolstering the foundational security of their computing infrastructure against sophisticated threats like bootkits and rootkits.
Key Takeaways
- UEFI Fuzzing Challenges: Fuzzing UEFI firmware is inherently difficult due to its modular nature, the prevalence of generic
void*types, and the need to generate state-dependent input in an asynchronous environment. - Furnace for Automated Harness Generation: FUZZUER introduces Furnace, a novel static analysis-assisted system that automatically generates source-level C fuzzing harnesses. This system leverages AST analysis, reaching definition, and call site analysis to create structured input.
- Effective Generic Type Resolution: Furnace employs frequency analysis and UEFI-specific heuristics to accurately resolve ambiguous
void*types, allowing the fuzzer to generate meaningful inputs for complex interfaces likeEFI_EVENT. - Significant Vulnerability Discovery: FUZZUER successfully found 20 new memory corruption bugs in EDK-2, with about half already confirmed, demonstrating its superior bug-finding ability compared to manual or stub-based approaches like HBFA.
- Enhanced Code Coverage: The framework achieved greater code coverage than existing methods by effectively generating complex, stateful inputs that enable deeper exploration of the firmware's execution paths.
- Low-Level ASAN Integration: FUZZUER successfully integrated ASAN runtime libraries into the EDK-2 environment, overcoming challenges related to physical memory management to provide robust memory error detection.
- Critical for Proactive Security: The research highlights that automated, coverage-guided fuzzing, particularly with intelligent harness generation, is crucial for proactively identifying and mitigating vulnerabilities in foundational firmware like UEFI, thereby defending against sophisticated bootkits and rootkits.
About the Speaker(s)
The talk "FUZZUER: Enabling Fuzzing of UEFI Interfaces on EDK-2" was presented by Connor Glosner from Purdue University. As the sole speaker introduced, he is the primary researcher behind the FUZZUER project, representing his academic institution in this significant contribution to UEFI security research.
Reviews
Dr. Zero (Offensive Security Researcher) — STRONG ACCEPT
Solid academic research with a real contribution: automated, static-analysis-driven harness generation for UEFI fuzzing that actually finds bugs manual approaches miss. The 20 new bugs in EDK-2, including 3 that HBFA's hand-crafted harnesses couldn't surface, is the kind of result that validates the architecture rather than just the idea.
Heather Calloway (CISO) — WEAK
Technically credible firmware security research with real results — 20 bugs found, automated harness generation validated against a known baseline. But this is a researcher presenting to researchers, and the talk does nothing to close the gap between the lab and the people responsible for firmware security at scale.
→ Top-rated talks at Network and Distributed System Security (NDSS) Symposium 2025
All talks from Network and Distributed System Security (NDSS) Symposium 2025