On October 21, 2026, PHP released fixes for two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, collectively known as PHP2Shell. Both can allow unauthenticated remote code execution on affected PHP installations. Exploitation attempts were seen as early as October 17, four days before disclosure.
Exploitation of PHP2Shell began four days before PHP shipped its fixes, so a webshell planted in that window can survive the update on a fully patched server. Rubrik Threat Hunting scans existing backups with YARA rules and file hashes. Security teams can use it to find suspicious files across recovery points, identify the earliest snapshot where they appear, and pinpoint the latest clean snapshot as a candidate for recovery. Here’s how.
Patching is Step One
Patch first: Update to 8.5.12, 8.4.27, 8.3.36, 8.2.35, or your vendor's patched package.
Patching fixes the vulnerabilities but does not remove files an attacker may have left behind. A webshell installed before the update can remain accessible afterward. Once patches are applied, the investigation needs to establish whether a compromise occurred and if so, which backups may be suitable for recovery.
Hunt in Your Backups
Rubrik Threat Hunting scans your existing snapshots with YARA rules and file hashes. Scanning historical backups lets investigators look for suspicious files across recovery points without running the hunt against the production workloads. Results identify the earliest matched backup and the latest backup without matches. These findings help narrow the investigation and identify candidate recovery points.
The Rules
These examples search for a vulnerable PHPUnit component and common PHP webshell patterns. They do not test for PHP2Shell exposure or establish how an attacker gained access.
Vulnerable Component - PHPUnit: The first rule looks for code associated with PHPUnit’s vulnerable eval-stdin.php helper, tracked as CVE-2017-9841. This is separate from PHP2Shell. A match warrants checking the installed PHPUnit version and whether the file is accessible through the web server. Its presence in a backup alone does not establish external exposure.
rule PHPUnit_EvalStdin_CVE_2017_9841
{
meta:
description = "Vulnerable PHPUnit eval-stdin.php helper (evaluates php://input)"
reference = "CVE-2017-9841"
strings:
$php = "<?php"
$eval = /eval\s*\(\s*['"]\?>['"]\s*\.\s*\\?file_get_contents\s*\(\s*['"]php:\/\/input['"]\s*\)/
condition:
$php at 0 and $eval and filesize < 2KB
}
Potential Compromise - PHP Webshells: The next two rules identify files for investigation. The first looks for command-execution functions and web-request input references in the same PHP file. It does not establish whether that input reaches an execution function.
rule PHP_Webshell_Cmd_Exec
{
meta:
description = "Command-execution functions and request-input references in one PHP file"
strings:
$php = "<?php"
$exec = /\b(shell_exec|passthru|proc_open|pcntl_exec|popen|system|exec)\s*\(/
$src = /\$_(GET|POST|REQUEST|COOKIE)\s*\[/
condition:
$php and $exec and $src
}
The second looks for eval or assert alongside decoding functions or web-request input references. These combinations can appear in webshells, but also in legitimate code.
rule PHP_Webshell_Obfuscated_Eval
{
meta:
description = "PHP eval/assert with decoding or request-input patterns"
strings:
$php = "<?php"
$eval = /\b(eval|assert)\s*\(/
$d1 = "base64_decode"
$d2 = "gzinflate"
$d3 = "gzuncompress"
$d4 = "str_rot13"
$src = /\$_(GET|POST|REQUEST|COOKIE)\s*\[/
condition:
$php and $eval and (any of ($d*) or $src)
}
Tuning a Threat Hunt for speed without losing accuracy: A hunt spends its time reading files, so you speed it up by narrowing WHERE it looks — not WHAT it looks for. Your hashes, YARA rules, and file patterns stay identical, so detection accuracy is unchanged; you're only shrinking the haystack.
Four settings do most of the work:
1. Snapshots to scan: Scan the latest 1 for "Is this host affected right now?" or just the 2–3 around the suspected window for "When did it land?" Don't scan the whole retention history (usually the biggest single speed-up.) You still cover the recovery points that matter.
2. Max file size: Set a cap around 1 MB. Web shells and malicious scripts are only a few kilobytes, so a cap well above that skips large videos, archives, and logs without missing anything.
3. File type/path: Point the hunt at the application's directories and script types only (for a PHP web-shell, the web folders and .php files) instead of the whole disk. Match the filter to where that threat actually lands.
4. Changed-files only: For recurring hunts, after one full baseline, scan only files modified since the last run. You catch anything new or tampered with in a fraction of the time.
Rule of thumb: keep your indicators fixed, and limit scope by snapshot range, file size, file type/path, and change date. Speed comes from scope, so accuracy stays intact.
Tip: When you first add a file path/type filter, run it once against a known-affected snapshot to confirm it still flags the artifact before you rely on it.
It’s important to treat these matches as leads for investigation. These rules can match legitimate files and will not detect every webshell. After confirming a file is malicious, use its SHA-256 hash to search other protected workloads and snapshots for exact copies. YARA rules can identify files that share the specified patterns.
Lab Results
In our lab, we tested a Linux server running PHP. The hunts identified the vulnerable PHPUnit component and webshell samples introduced for the test.
Rubrik Security Cloud Threat Hunting: exposure hunt result for eval-stdin.php
Rubrik Security Cloud Threat Hunting: webshell hunt result for reports_export.php
Use the snapshot results to trace where the matched files appear in the scanned backup history. The earliest matched snapshot helps establish when an artifact was present; it does not necessarily mark the start of the intrusion. The latest snapshot without matches is a candidate for recovery, subject to further validation.
A patch closes the vulnerability, but the investigation stays open until someone checks what the attacker left behind. Exploitation of PHP2Shell began four days before disclosure, so any server running vulnerable PHP in that window needs a review of its backups.
Rubrik Threat Hunting supplies the evidence: the earliest snapshot with a match, the latest snapshot without one, and the SHA-256 hash of any confirmed file for finding exact copies across other workloads. Patching secures the server going forward. Recovery depends on knowing which backup went in clean.