What The PHUZZ?! Finding 0-Days In PHP Apps wt Coverage-guided Fuzzing - Sebastian
Sebastian
Nullcon Goa 2025 · Main Stage
Overview
This talk, "What The PHUZZ?! Finding 0-Days In PHP Apps wt Coverage-guided Fuzzing," by Sebastian, delves into the development and application of PHUZZ, a novel coverage-guided fuzzer specifically designed for PHP web applications. Sebastian, a PhD student at TU Berlin and an IT security freelancer, presented this work, which was a collaborative effort with Lawrence and Jean Pier, and previously published at an academic conference. The presentation aims to educate the audience on how to leverage advanced fuzzing techniques to uncover critical vulnerabilities, including zero-days, in real-world web applications.

Key moments
- 0:00 Introduction to finding 0-days in PHP apps
- 2:00 Speaker's background and research focus
- 3:40 What is blackbox fuzzing?
- 5:40 Limitations of traditional blackbox web fuzzing
- 6:20 Introducing coverage-guided fuzzing for improved vulnerability discovery
- 8:50 Challenges of applying coverage-guided fuzzing to web apps
What The PHUZZ?! Finding 0-Days In PHP Apps wt Coverage-guided Fuzzing - Sebastian
Speakers: Sebastian, PhD Student, TU Berlin & IT Security Freelancer
Conference: Nullcon
YouTube: https://www.youtube.com/watch?v=sgMRoZO4lh4
Overview
This talk, "What The PHUZZ?! Finding 0-Days In PHP Apps wt Coverage-guided Fuzzing," by Sebastian, delves into the development and application of PHUZZ, a novel coverage-guided fuzzer specifically designed for PHP web applications. Sebastian, a PhD student at TU Berlin and an IT security freelancer, presented this work, which was a collaborative effort with Lawrence and Jean Pier, and previously published at an academic conference. The presentation aims to educate the audience on how to leverage advanced fuzzing techniques to uncover critical vulnerabilities, including zero-days, in real-world web applications.
The core problem PHUZZ addresses is the limitation of traditional blackbox fuzzing in web environments. While blackbox fuzzers inject malformed inputs, they often lack the detailed feedback needed to understand internal application behavior and effectively identify deep-seated bugs. PHUZZ overcomes this by integrating robust instrumentation, allowing it to monitor code execution, catch suppressed errors, and optimize input generation based on code coverage, thereby significantly enhancing vulnerability detection capabilities in complex PHP ecosystems.
The significance of PHUZZ lies in its ability to bring the proven power of coverage-guided fuzzing, traditionally applied to binary applications, to the web application domain. By demonstrating the discovery of two zero-day vulnerabilities in widely used WordPress plugins, Sebastian effectively showcases PHUZZ's practical utility. This research not only provides a powerful new tool for security researchers and bug bounty hunters but also offers valuable insights into common vulnerability patterns and effective defensive strategies for PHP developers.
Background
▶ Watch: Introduction to finding 0-days in PHP apps (0:00)
Fuzzing, a software testing technique dating back to 1988, traditionally involves feeding random inputs to an application to identify crashes or undefined behavior. The most basic form, blackbox fuzzing, operates without any internal knowledge of the application. In the context of web applications, this typically means sending malformed HTTP requests to a web server and observing the HTTP responses. While tools like those described by the OWASP project employ blackbox methods, they are often limited by relying on a fixed set of payloads and heuristics. For instance, a fuzzer might send an SQL injection payload and only detect the vulnerability if the application explicitly returns an "error in your SQL syntax" message. If the application merely returns a generic 500 error or a blank page, the fuzzer receives insufficient feedback to pinpoint the root cause or even confirm a vulnerability.
This limitation led to the development of coverage-guided fuzzing, a technique that instruments the target application to monitor code execution. By understanding which functions are executed and how much code is covered by a given input, the fuzzer can intelligently generate new inputs that explore previously unreached code paths. This approach has proven highly successful in finding vulnerabilities in binary applications, with prominent examples like AFL (American Fuzzy Lop), AFL++, and OSS-Fuzz. However, applying coverage-guided fuzzing to web applications, particularly those built with PHP, introduces several unique challenges.
Unlike binary applications that often consume a single stream of input (e.g., from stdin or a file), web applications interact through multiple endpoints, each accepting diverse parameters. The first challenge is therefore endpoint and parameter discovery. Once identified, input mutation becomes complex; simple bit-flips, common in binary fuzzing, are ineffective for web requests that require adherence to HTTP structure, parameter names, and sometimes semi-structured payloads (e.g., ../ for path traversal, <script> for XSS). The third major hurdle is instrumentation and coverage collection. Web servers and PHP applications often run in separate processes or even on different machines from the fuzzer, making direct memory access or shared memory for feedback difficult. Furthermore, instrumenting PHP code without modifying the interpreter or breaking the application itself requires a sophisticated approach. Finally, vulnerability detection needs to be adapted to the web context, considering both server-side errors and client-side manifestations like XSS in HTTP responses. PHUZZ was designed to systematically address these challenges, bringing advanced fuzzing capabilities to the PHP web application security landscape.
Key Findings
▶ Watch: What is blackbox fuzzing? (3:40)
The central contribution of this work is PHUZZ, a novel, modular, and open-source coverage-guided fuzzer specifically engineered for PHP web applications. PHUZZ successfully overcomes the inherent challenges of applying advanced fuzzing techniques to the web environment, demonstrating its efficacy by uncovering multiple bugs and two critical zero-day vulnerabilities in widely used WordPress plugins.
PHUZZ's architecture is built around several key innovations:
- Browser-based Endpoint Discovery: Recognizing the limitations of traditional crawlers, PHUZZ utilizes a user-driven, browser-based approach. Users interact with the web application in a browser (with developer tools open), and the recorded HTTP Archive (HAR) file is then processed to extract all endpoints and parameters, ensuring comprehensive coverage of application functionality.
- Intelligent Input Mutation: Instead of simple random bit-flips, PHUZZ employs a strategy of random byte additions, removals, replacements, or modifications to parameter values. Crucially, it preserves parameter names and adheres to HTTP request structures, ensuring that mutated inputs actually reach the application logic. It also intelligently injects specialized vulnerability triggers for classes like Cross-Site Scripting (XSS) and Path Traversal.
- Transparent PHP Instrumentation: A significant breakthrough is PHUZZ's transparent instrumentation method, which does not require recompiling the PHP interpreter or modifying the target application's source code. It leverages existing PHP extensions like uopz for function hooking and Xdebug or PCOV for coverage collection. This allows PHUZZ to gain deep insights into internal application execution, even catching suppressed errors and exceptions.
- Sophisticated Vulnerability Detection: PHUZZ supports the detection of seven distinct vulnerability classes, including SQL Injection, Remote Code Execution, External Entity Injection, Cross-Site Scripting, and Path Traversal. It correlates code coverage reports with HTTP responses and hooked function errors to identify vulnerabilities, looking for specific keywords in error messages (e.g., SQL syntax errors) or injected triggers in HTML output (e.g., XSS payloads).
Beyond its technical capabilities, PHUZZ's practical impact was concretely demonstrated through a fuzzing campaign against 183 popular WordPress plugins, totaling over 180 million active installations. This campaign, which involved disabling authentication and CSRF checks using PHUZZ's function hooking capabilities to maximize code coverage, successfully identified more vulnerabilities than a comparative blackbox fuzzer like Burp Suite Pro. Critically, this led to the discovery of two zero-day vulnerabilities: a Server-Side Request Forgery (SSRF) and Arbitrary File Read in the Pop-up Builder plugin (200,000+ installations), and a Local File Inclusion (LFI) in the SO Widgets Bundle (500,000+ installations).
An interesting side finding was PHUZZ's utility as a debugging tool. By logging invalid queries or file access attempts, it could identify non-security-critical bugs that might lead to application misbehavior, highlighting its broader value for developers. The project is open-source and modular, inviting community contributions to expand its capabilities and vulnerability class support.
Technical Deep Dive
▶ Watch: Limitations of traditional blackbox web fuzzing (5:40)
PHUZZ's architecture is modular and containerized, with each component running in a separate Docker container, facilitating parallel fuzzing and easy extensibility. The workflow begins in the configuration stage, where a crawler and browser are used to collect endpoints. This is primarily achieved by having a user manually navigate the web application with browser developer tools open, then exporting the network traffic as an HTTP Archive (HAR) file. This HAR file, a JSON-formatted record of all requests and parameters, is then processed by PHUZZ's configuration generation components to create precise fuzzing configurations. This browser-based approach is preferred over automated crawlers, which often struggle with interactive elements and complex application flows.
The central component is the fuzzer core, written in Python. This orchestrates the entire fuzzing campaign, handling input mutation, HTTP request generation, and vulnerability detection. To ensure that mutated inputs reach the application logic, PHUZZ leverages the Python requests library to construct properly formatted HTTP requests. This library handles the complexities of methods, URLs, endpoints, parameters, cookies, and headers, preventing the web server from rejecting malformed requests before they even reach the PHP application. PHUZZ explicitly preserves parameter names (e.g., email, password, username) and only mutates their values, as altering parameter names would often lead to the application simply ignoring the input. Mutations involve single-byte changes (add, remove, replace, modify) to parameter values, complemented by the occasional insertion of specialized vulnerability triggers for XSS or path traversal.
The most critical aspect of PHUZZ is its transparent instrumentation and coverage collection mechanism for PHP applications. This is achieved without modifying the PHP interpreter source code or the target application itself, a significant advantage over other approaches. PHUZZ utilizes three open-source PHP extensions:
- uopz: This extension allows for function hooking, enabling PHUZZ to intercept function calls, inspect their arguments, and even modify their return values or catch exceptions. The
uopz_set_returnfunction is central to this, allowing PHUZZ to "wrap" original functions. For example,my_sqli_querycan be hooked to capture SQL errors that might otherwise be suppressed by PHP's@operator or unhandled by the application. This hooking mechanism is also crucial for disabling security checks likeis_logged_in(),is_admin(),check_csrf_nonce(), allowing the fuzzer to reach deeper functionalities without getting stuck at authentication or authorization barriers. By returningtruefor these functions, PHUZZ effectively bypasses them during the fuzzing campaign. - Xdebug or PCOV: These extensions are used to collect code coverage information, indicating which lines or functions of the PHP application have been executed by a given fuzzed input. This feedback is essential for the coverage-guided nature of PHUZZ, allowing it to prioritize inputs that explore new code paths.
To ensure that the instrumentation code runs before and after the target application's code, PHUZZ leverages PHP's auto_prepend_file and auto_append_file configuration directives. These directives force PHP to execute specific initialization and cleanup scripts (containing uopz hooks and Xdebug/PCOV start/stop calls) before and after every request, guaranteeing consistent coverage collection. The collected coverage data and any intercepted error logs are then stored on a shared volume, accessible to the fuzzer core.
Finally, vulnerability detection is handled by a modular ParmBasedVulnChecker class. This component analyzes the collected coverage reports and HTTP responses. It looks for specific keywords in error messages (e.g., "you've got an error in your SQL syntax" from mysqli_query exceptions) to identify SQL injections. For client-side vulnerabilities like XSS or Open Redirection, it inspects the HTTP response body or headers to see if injected payloads or manipulated URLs are reflected. The modular design allows for easy extension to support more vulnerability classes.
Demo / Proof of Concept
▶ Watch: Introducing coverage-guided fuzzing for improved vulnerability discovery (6:20)
To validate PHUZZ's effectiveness, Sebastian and his team conducted an extensive fuzzing campaign targeting popular WordPress plugins. WordPress, being PHP-based and widely used, with an extensive ecosystem of open-source plugins, provided an ideal testing ground. They downloaded 183 plugins with over 300,000 active installations each, representing a significant portion of the WordPress user base (totaling 180 million active installations).
Since manually generating HAR files for 183 plugins would be impractical, they developed an automated method to extract API endpoints and parameters from plugin source code (looking for $_REQUEST, $_GET, $_POST, $_COOKIE). This yielded over 1,000 API endpoints and parameters for 115 plugins. A crucial step for maximizing coverage during fuzzing was the strategic disabling of authentication, authorization, and CSRF checks using PHUZZ's function hooking capabilities (e.g., forcing is_admin() or check_csrf_nonce() to return true). This allowed PHUZZ to reach deep into the plugin's functionality, bypassing common security barriers that would otherwise prevent the fuzzer from triggering vulnerabilities.
The fuzzing campaign ran for several days, comparing PHUZZ's performance against Burp Suite Pro on the same set of parameters and plugins. The results showed that PHUZZ consistently found more vulnerabilities. This outcome underscored the advantage of PHUZZ's coverage-guided, instrumented approach, which provides deeper insights into application behavior compared to Burp Suite's blackbox methodology. All discovered issues were reported to the affected plugin authors following coordinated vulnerability disclosure principles, leading to prompt remediation in many cases.
While many findings were debugging-related (e.g., invalid SQL queries, non-existent file access) due to PHUZZ's server-side insights, two critical zero-day vulnerabilities emerged after manual validation and careful consideration of the WordPress threat model, particularly in multi-site environments. The key insight revolved around the is_admin() function in WordPress. While its name suggests an administrator check, WordPress documentation clarifies that it merely returns true if a page under the wp-admin URL is accessed. In a multi-site setup, both network administrators (full control) and site administrators (limited control over a subsite) access wp-admin pages. If is_admin() is used to gate functionality intended only for network administrators, a site administrator could potentially exploit it, constituting a privilege escalation.
The first zero-day was found in the Pop-up Builder plugin, which had roughly 200,000 active installations. PHUZZ initially identified an arbitrary file read, but manual validation revealed an accompanying Server-Side Request Forgery (SSRF) vulnerability. The vulnerable API endpoint was sgpb_pb_import_subscriber, specifically through the import_list_url parameter. An attacker, even a site administrator, could supply ../ sequences for arbitrary file reads (e.g., /etc/passwd) or provide a URL to trigger an SSRF, forcing the server to make requests to internal or external resources.
The second zero-day, a Local File Inclusion (LFI), was discovered in the SO Widgets Bundle plugin, impacting over 500,000 installations. The vulnerability resided in the sow_widget_bundle_manage endpoint, exploitable via the widget parameter. This LFI had specific exploitation requirements: the supplied path had to end with .php, and the directory containing the included file had to share the same name as the file itself (without the .php suffix). For demonstration, a specially crafted file in /tmp/testdir/testdir.php could be included and executed. While the immediate impact on existing WordPress network installations was not fully tested, the existence of a network.php file in such setups suggested potential for broader exploitation, especially if other plugins created similarly structured files.
These findings conclusively demonstrated PHUZZ's capability to uncover critical, previously unknown vulnerabilities in widely deployed PHP applications, highlighting the power of coverage-guided fuzzing in the web security domain.
Defensive Implications
▶ Watch: Challenges of applying coverage-guided fuzzing to web apps (8:50)
The insights gained from the development and application of PHUZZ offer several critical defensive implications for developers and security professionals working with PHP web applications, particularly within the WordPress ecosystem.
Firstly, the research underscores the limitations of relying solely on blackbox testing. While essential, blackbox scanners often miss vulnerabilities that manifest deep within the application logic or are obscured by generic error handling. Coverage-guided fuzzing, as demonstrated by PHUZZ, provides a significantly more comprehensive approach by gaining internal visibility into code execution. Developers should consider integrating similar instrumentation-based testing into their CI/CD pipelines to catch bugs earlier.
Secondly, the discovery of zero-days hinges on a nuanced understanding of permission models, especially in complex frameworks like WordPress. The is_admin() function example is a prime illustration: its misleading name can lead developers to incorrectly assume it grants full administrative privileges, when it merely indicates access to an admin-related URL. Developers must meticulously verify the actual capabilities and roles associated with each permission check, particularly in multi-tenant or multi-site environments. Functions intended for network administrators in a WordPress multi-site setup should employ more specific checks than is_admin(), such as is_super_admin() or custom role-based access controls, to prevent privilege escalation from site administrators.
Thirdly, the ability of PHUZZ to catch suppressed errors (via uopz hooking) highlights a common defensive blind spot. PHP's @ error suppression operator, while sometimes used to clean up user-facing output, can hide critical information about underlying vulnerabilities like SQL injection errors. Developers should minimize the use of error suppression and ensure robust, centralized error logging that captures all exceptions and warnings, even if not displayed to the end-user. This internal logging is invaluable for debugging and security monitoring.
Fourthly, the identified vulnerabilities (SSRF, Arbitrary File Read, LFI) are classic web application flaws. This reinforces the need for diligent input validation and sanitization for all user-supplied data, especially when dealing with file paths, URLs, or data that will be used in database queries. Developers should:
- Restrict file access: Use allowlists for file names and paths, or ensure that any file inclusion mechanism strictly validates and sanitizes input to prevent path traversal (
../) and arbitrary file inclusion. - Sanitize URLs: For features that fetch content from external URLs (like the
import_list_urlin Pop-up Builder), rigorously validate the URL scheme, host, and port to prevent SSRF. Consider disallowing private IP ranges and loopback addresses. - Implement strong authentication and authorization: While PHUZZ bypassed these for fuzzing, in production, these layers are crucial. Ensure that every sensitive action is protected by appropriate, context-aware authorization checks.
Finally, PHUZZ's secondary role as a debugging tool is noteworthy. Its ability to detect invalid SQL queries or attempts to access non-existent files, even if not immediately security-critical, can help developers improve code quality and stability. Integrating such feedback mechanisms could lead to more robust applications, reducing the attack surface by eliminating unexpected behaviors. The modular and open-source nature of PHUZZ also encourages the security community to contribute, enhancing its capabilities and fostering a collaborative approach to improving PHP application security.
Key Takeaways
- Coverage-Guided Fuzzing is Powerful for Web Apps: PHUZZ demonstrates that advanced coverage-guided fuzzing, traditionally for binaries, can effectively uncover deep vulnerabilities in PHP web applications by providing internal execution feedback.
- Blackbox Fuzzing Has Limitations: Traditional blackbox methods, like those in Burp Suite, often lack the necessary internal visibility to find complex bugs, especially when errors are suppressed or generic responses are returned.
- Transparent Instrumentation is Key: PHUZZ's use of
uopz,Xdebug, andPCOVfor transparent PHP instrumentation (without modifying interpreter or app code) is a significant innovation, enabling deep code coverage and error detection. - WordPress Permission Models are Nuanced: The
is_admin()function in WordPress can be misleading; developers must understand the distinction between site and network administrators in multi-site environments to prevent privilege escalation vulnerabilities. - Input Validation Remains Critical: The zero-days found (SSRF, Arbitrary File Read, LFI) highlight the persistent need for strict input validation, sanitization, and robust authorization checks for all user-supplied data, especially file paths and URLs.
- Fuzzing as a Debugging Tool: Beyond security, coverage-guided fuzzing can identify non-security-critical bugs (e.g., invalid queries, file access issues), improving overall application stability and quality.
About the Speaker(s)
The speaker for this presentation is Sebastian. He is currently a PhD student conducting research at the TU in Berlin. In addition to his academic pursuits, Sebastian works as an IT security freelancer. He has a background in bug bounties, which he engaged in during his bachelor's and master's studies, and has a keen interest in finding vulnerabilities. Sebastian is also actively involved in the Capture The Flag (CTF) community, particularly with the team Inole, and was involved in developing web challenges for the Hack IM CTF, which offered tickets to Nullcon. He previously presented a different academic approach at Nullcon Goa 2023. Sebastian is passionate about building tools that can be used for bug bounty work and encourages community contributions to projects like PHUZZ.
Reviews
Dr. Zero (Offensive Security Researcher) — SOLID
Legitimate research with real zero-days and a genuinely useful tool, but the contribution is evolutionary rather than groundbreaking — coverage-guided fuzzing applied to PHP is a well-understood problem space, and the novel pieces (uopz hooking, HAR-based endpoint discovery) are incremental improvements rather than paradigm shifts. A competent academic paper that translates to a competent conference talk.
Heather Calloway (CISO) — WEAK
Technically credible research with a real finding — coverage-guided fuzzing applied to PHP web apps is genuinely useful work, and the WordPress zero-days are legitimate. But the talk never climbs above the researcher's workbench. There is no path from this work to a security leader, a developer team lead, or a policy decision.