Wazuh SIEM Detect PHP2Shell 13 Steps 2026 How-To Guide

wazuh siem detect php2shell 13 steps 2026

Wazuh SIEM Detect PHP2Shell 13 Steps 2026 How-To Guide

wazuh siem detect php2shell 13 steps 2026

A useful PHP2Shell defense starts by finding every PHP runtime and making its active workers visible to your security monitoring. PHP2Shell puts your server, logs, host activity, and configuration in view, but patching remains the priority.

Wazuh can bring together asset inventory, PHP and web logs, host activity, and file monitoring. FIM means file integrity monitoring, a control that records and alerts on changes to selected files. This guide walks you through 13 practical steps for monitoring PHP exposure and suspicious activity.

Monitoring supports detection, not prevention. It can help your team spot exposure and investigate activity, but it cannot replace a fixed release or sound access controls. First confirm which PHP version each live worker runs.

Key Takeaways

  • Inventory PHP in servers, containers, appliances, and managed services.
  • Compare package versions with active PHP binaries and workers.
  • Collect PHP, PHP-FPM, web-server, and host events in Wazuh.
  • Preserve volatile evidence before restarting a suspect host.
  • Use FIM for monitored file changes, not memory-only exposure.
  • Recheck the running version after patching and restarting workers.

Treat a clean alert queue as a monitoring result, not proof that every PHP host is patched.

Why PHP2Shell Needs More Than Application-Level Monitoring

PHP2Shell matters to defenders because the vulnerable behavior sits in PHP’s request-processing engine, not only in website code. That runtime layer can handle a request before application code starts, so application logs may miss important activity.

CVE-2026-109618 and CVE-2026-109619 each have a CVSS v4.0 score of 9.2. Both can allow unauthenticated remote code execution in affected PHP request-processing environments. PHP’s October 21, 2026 security updates fixed memory-safety vulnerabilities in the core PHP engine.

PHP request processing beside Wazuh host event logs

A memory disclosure can expose passwords, authentication tokens, API keys, and certificates. It may do so without leaving a web shell or other changed file for FIM to find. Your team should consider the systems and credentials reachable from the affected process.

For example, exposed API keys can connect a web host to other services. Keep keys out of source code and logs, and rotate a key when exposure is plausible. A practical API key protection guide can help your team review credential handling.

Use host and process telemetry to complement web logs because a memory disclosure can leave no code-execution artifact.

Arctic Wolf Labs observed scanning and active exploitation attempts shortly after disclosure on October 21, 2026. Potassium, a Mirai-derived botnet family first identified in March 2026, was among the activity defenders should keep in mind.

Scanning and exploitation attempts show interest, not a confirmed compromise. Match web activity with host and process evidence before deciding what happened.

Application monitoring alone cannot show every runtime event. Pair request logs with host signals, especially when a suspicious request does not produce a file change or clear application error.

PHP engine memory exposure alongside host monitoring events

Use host and process telemetry to complement web logs because a memory disclosure can leave no code-execution artifact.

Which PHP Hosts and Releases Need Attention?

Any reachable web-facing PHP runtime below its branch’s fixed release needs remediation, even if its application is up to date. Prioritize reachable hosts and identify the PHP mode before planning the work.

PHP versions 5.4 through 8.5.11 are vulnerable to CVE-2026-109618 and CVE-2026-109619. The PHP project’s fixed releases are 8.5.12, 8.4.27, 8.3.36, and 8.2.35. PHP 8.1 and earlier have no PHP project fix because those branches are end of life.

PHP release inventory across production server deployment types

Apache mod_php was the highest-risk configuration in observed activity. Exploitation was demonstrated with one unauthenticated request, before application code began executing.

Deployment or release Exposure detail Priority action
PHP-FPM Long-running PHP workers may retain vulnerable runtime state Update PHP and restart every serving worker
Apache mod_php Highest-risk observed configuration; request can arrive before app code Prioritize reachable hosts and apply a fixed release
PHP 8.1 and earlier End-of-life branches have no PHP project fix Move to a supported branch or vendor-maintained fix
PHP 8.2-8.5 below fixed releases Versions below 8.2.35, 8.3.36, 8.4.27, or 8.5.12 are affected Update to the fixed release for that branch

Include bundled PHP in appliances and containers in the inventory. A container image may hold a separate runtime, while an appliance may receive updates through its vendor.

Check the vendor’s package notes when its release number differs from the upstream version. The PHP fixed-release list gives the upstream branch levels used for comparison.

Record vendor-maintained backports separately from upstream version strings so a package label does not create a false vulnerable finding.

What Should You Preserve Before Restarting a Suspect Host?

If a PHP host is showing active probing or unusual PHPSESSID cookies, preserve worker memory before restarting it. Volatile heap evidence disappears when a long-running PHP process restarts.

PHP-FPM and Apache workers hold memory state while they run. A restart destroys that state, so treat a suspected active incident differently from routine patching.

PHP worker memory capture before a suspect server restart

Coordinate memory capture with incident responders who can follow your organization’s evidence process. Preserve relevant logs, the host’s time settings, active service details, and the worker identifiers tied to the alert.

Do not reflexively restart a server when active probing or anomalous session cookies are present. First decide whether evidence collection is needed, then contain the host through your response process.

Capture context around the response as well as the memory image. Useful details include the PHP service, host name, worker process ID, and nearby request times.

Routine maintenance is different: once investigators clear the need to preserve volatile evidence, patching and restarting workers can apply remediation. Keep those operational changes recorded so the timeline remains clear.

Record the capture time and affected worker identifiers so investigators can align volatile evidence with nearby logs.

Steps 1-3: Establish the Wazuh Fleet Baseline

Start with a fleet inventory that includes PHP embedded in containers and products, not only packages installed on standard servers. A complete baseline helps your team spot missing hosts before relying on alerts.

Include internet-facing servers, container images, appliances, and managed PHP deployments. Do not mark a host clean when Wazuh has no current agent data for it.

Step 1: Inventory PHP assets

Build a list of assets that run or provide PHP, then note which ones accept internet traffic. Include the owner or service group when known, so your team can route follow-up work without guessing.

Distinguish PHP-FPM from Apache mod_php and other deployment types. They use different worker models, and the distinction helps explain which runtime is active.

Step 2: Check Wazuh manager and agent health

Check the Wazuh manager service state and agent connectivity before using agent-collected inventory. An offline agent can leave old package data that looks current at a glance.

Review the last contact time and any agent connection errors. Your team can then separate a genuine no-PHP result from an inventory gap.

Step 3: Locate packages, binaries, and runtime processes

Wazuh syscollector can provide installed-package and system inventory data. Compare package records with PHP binaries on disk and active php-fpm, php-cgi, or Apache worker processes.

A package list does not always identify the binary serving live requests. Check process details and service configuration to find the active executable.

Keep these fields together for each host:

  • Asset identifier
  • PHP deployment type
  • Installed version
  • Active binary or worker
  • Internet exposure

Use the same asset identifier across inventory and alert records. That makes a host easier to find when multiple services or containers share a server.

Check whether managed services expose runtime details through an agent, provider report, or approved inventory feed. Store the method used, so a later review can tell direct telemetry from vendor reporting.

Mark assets with missing agent data for manual verification rather than treating them as clean.

Steps 4-6: Audit Runtime Status, Patch, and Recheck

A version check is incomplete until it confirms which binary the live PHP workers are executing. Compare runtime and disk state so an updated package does not hide an older process.

A local audit should report the PHP binary version, vendor backport status, active worker process, and whether runtime and on-disk versions agree. Updating files alone can leave vulnerable PHP-FPM or Apache workers running.

Step 4: Build a local PHP audit

Make the audit script gather facts from the host without changing service state. It should identify the executable used by each PHP worker and compare its version with the package record.

Include vendor backport information when available. An upstream version string can appear old even when a vendor has applied a security fix.

Step 5: Schedule and collect audit output

Write structured output with stable field names, such as host, binary path, runtime version, package version, worker process, and audit status. Send that output to Wazuh through a configured local log file or another supported collection path.

Keep error output clear. A failed command or missing binary should produce a visible audit result, not a blank event that resembles a clean host.

Step 6: Patch, restart, and verify workers

Updating PHP and restarting the actual web-serving workers are necessary to apply the fix. Restart PHP-FPM, Apache, other long-running PHP workers, or redeploy containers after an update.

Control Use Caution
Fixed release patch Complete fix for affected PHP runtime Restart every serving worker or redeploy its container
session.upload_progress.enabled=0 Interim mitigation for CVE-2026-109619; keep disabled after patching Apply before request parsing and restart workers
memory_limit=-1 Interim CVE-2026-109618 mitigation in protected FPM or Apache configuration Uncapped runaway requests can exhaust server resources
Upload-size limits Use post_max_size of 8M without uploads or 32M when uploads are needed Keep upload_max_filesize below post_max_size

Configuration mitigations are temporary, not a substitute for a fixed release. Set session.upload_progress.enabled=0 after patching, then restart the PHP workers again if that setting changed.

Where uploads are not needed, use the smaller post_max_size limit. Where they are needed, set the documented larger limit and keep the file-size cap below it.

The interim PHP configuration mitigations require care, especially the uncapped memory setting. Test configuration changes against the service’s normal request needs.

Re-run the audit after the worker restart and retain the result that confirms the runtime version, not just the package version.

Steps 7-9: Send the Right Logs and Validate Detection Rules

Collecting the correct log files matters more than writing a complex rule against data Wazuh never receives. Start with useful records from the PHP runtime and the web server.

Wazuh agents can collect configured local log files for centralized analysis. PHP-FPM, Apache, and Nginx use different paths, so match each configuration to its actual log location.

Step 7: Collect PHP and web-server logs

Configure collection for the PHP error log, PHP-FPM master log, and web access log. Include relevant system journal events that show service starts, stops, or failures.

Check log rotation and permissions. A path that works before rotation may stop sending events after a new file replaces the old one.

Step 8: Normalize fields with decoders

Use decoders to make fields consistent when the source records contain them. Useful fields include timestamp, source IP, request method, status, request size, and process name.

Do not invent fields that a log does not record. Keep the original message available so an analyst can review context that parsing did not capture.

Step 9: Test rules before rollout

Use representative benign and suspicious log samples in wazuh-logtest before enabling alerts. Check decoder output first, then confirm each custom rule matches only the intended event.

Include routine uploads and ordinary server errors in the test set. They help reveal rules that would flood the queue during normal use.

Practical Wazuh guidance also recommends testing representative records and custom rules with wazuh-logtest rule checks before deployment.

Keep a copy of the test cases and expected fields beside each custom rule so later changes can be regression-tested.

Steps 10-11: Add Custom Rules and Confirm Patch Status

The useful alert is not merely “old PHP found,” but a finding that identifies the host and the live runtime needing action. Make each finding actionable with a clear status and supporting audit fields.

Custom Wazuh rules can flag vulnerable version strings and mismatches between the binary on disk and active PHP processes. Test every condition with representative events before using it in production.

Step 10: Alert on vulnerability and runtime mismatches

Build conditions for vulnerable release status, unsupported PHP branches, missing audit data, and runtime-versus-disk mismatches. Include the asset identifier, deployment type, and observed version in the alert.

Use distinct outcomes so operators know whether to patch, upgrade a branch, investigate a mismatch, or repair telemetry. Test each result with a sample event that should match and one that should not.

Keep the status values short and stable:

  • VULNERABLE
  • UNSUPPORTED
  • PATCHED
  • RUNTIME_MISMATCH
  • NO_DATA

Step 11: Re-audit patched hosts

A post-patch audit confirms whether the running process changed, rather than merely showing that a package update completed. Compare the new runtime state with the saved pre-patch result.

When the package is fixed but a worker still reports an older version, investigate the service and process mapping. A stale worker can serve requests even when the files on disk have changed.

Keep unsupported branches distinct from supported branches that need a routine update because their remediation paths differ.

Steps 12-13: Roll Out Across the Fleet and Review Coverage

Roll out monitoring in small, representative groups before applying the same configuration fleet-wide. A phased deployment gives your team room to catch broken paths, noisy rules, and missing fields.

Wazuh agent groups can manage configuration across endpoint sets. Start with test hosts that represent different PHP modes and operating environments.

Step 12: Deploy in controlled groups

Deploy first to representative test hosts, then to production groups, and finally to the remaining fleet. Check that each group sends audit output and the right log events after its configuration changes.

Keep a record of agent group, deployment time, and any failed host. That record helps distinguish rollout gaps from hosts that were never enrolled.

Step 13: Review dashboard coverage and exceptions

Create an exception register for hosts without agents, vendor-managed PHP, and unsupported branches. Give each exception an owner and a review point so it does not become permanent by accident.

Use dashboard filters to organize findings by host, alert status, and rule group. Keep views focused on gaps your team can act on:

  • Vulnerable assets
  • Runtime mismatches
  • Missing audit events
  • Unresolved alerts

Compare dashboard totals with the asset inventory. A falling alert count can mean successful patching, but it can also mean an agent stopped sending data.

Check exceptions after each group deployment and note why a host is excluded. This gives later reviewers a clear path to restore coverage when the service changes.

Treat a missing event stream as a coverage failure until you verify that the host is intentionally excluded.

What PHP2Shell Request Patterns Should Wazuh Flag?

Flag PHP_SESSION_UPLOAD_PROGRESS in multipart requests when it appears on routes that do not normally receive uploads. That mismatch deserves review, but the field alone does not show whether code ran.

Collect unusual session IDs, inert canaries, and output markers when your logs capture them. Request contents show intent, not confirmed execution.

Upload-progress fields and unusual multipart requests

Review multipart POST requests that contain the suspicious upload-progress field, especially when sent to routes without ordinary upload behavior. Check whether the session identifier looks unusual or attacker-controlled.

Some probes use inert PHP canaries, unique output markers, or session-poisoning attempts. Local-file-inclusion chains can also appear in request patterns, so retain enough access-log detail for review.

Distinguish scanning from command-execution attempts

Arctic Wolf Labs observed a scanner using the user agent php2shell-scan/109618 and submitting PHP_SESSION_UPLOAD_PROGRESS. A likely weaponized request attempted to print PHP2SHELL_CONFIRMED, change to /tmp, and retrieve a file from 92.118.112[.]100.

Use three broad categories when sorting request events:

  • Basic probe: unusual multipart fields or a scanner user agent
  • Execution validation: inert canaries or unique output markers
  • Attempted second-stage delivery: a request that tries to retrieve another file

Do not reproduce an operational exploit request in alert notes. Preserve only the defensive indicators needed for triage and correlation with host evidence.

Preserve the request’s timestamp and source address so it can be correlated with independent host evidence.

How Can Wazuh Correlate PHP Errors and Worker Failures?

A single server error is noisy, but a suspicious request followed by a PHP worker failure deserves a joined investigation. Time and host context help your team decide whether separate events belong together.

PHP error logs and PHP-FPM master logs can show different parts of a request-failure sequence. Correlate by host, source, and time instead of treating one error as proof.

PHP2Shell hunting indicators include memory-limit errors, repeated HTTP 500 responses, unexplained worker restarts or segfaults, and unusually large PHPSESSID values. Each signal can also have an ordinary cause.

Signal Meaning to investigate Next check
Memory-limit fatal Request or code may have exhausted PHP memory Review nearby requests and PHP error lines
Repeated HTTP 500 Application or runtime failures may be recurring Compare timestamps with PHP error records
HTTP 502 or worker segfault Upstream worker may have stopped or crashed Check PHP-FPM master logs and worker status
Oversized PHPSESSID Session data may be unusual or manipulated Review request source and related PHP errors

Legitimate uploads can produce memory errors or repeated server failures. Unrelated extension failures can also cause an isolated crash or segfault.

A request pattern followed by a worker failure from the same host and nearby time is stronger evidence than either event alone. Preserve the separate log lines so responders can see the sequence.

Set the correlation window to match the service’s request volume and normal upload traffic. Review the chosen window when those patterns change.

Keep the correlation window configurable and review it against the host’s normal upload traffic.

Which Host Signals Can Confirm Post-Exploitation?

A PHP worker spawning a shell or downloader is more consequential than a suspicious request alone. Process ancestry can show whether activity began with php-fpm, php-cgi, or Apache.

Wazuh host telemetry should capture unusual child processes, outbound connections, and the account running the PHP worker. Review the parent process and user before assigning meaning to a process alert.

Look for workers that launch shells, interpreters, or downloaders without a known service need. An unexpected outbound connection from a PHP worker can add context, especially when the destination does not fit the host’s normal role.

Build a baseline for approved mail tools, image-processing programs, and maintenance scripts. Some sites use these tools from PHP, so an unfamiliar child process needs review rather than automatic judgment.

Compare the process account with the service design. A worker running as a limited web user has different reach from one with broad system access.

Check whether a parent process belongs to a web service or an unrelated scheduled task. Process ancestry can help separate PHP activity from a nearby process that happens to share the same host.

Pair process events with destination, command line, and service status. A single unusual connection may be routine, while a worker-launched downloader followed by a new child process merits prompt triage.

Preserve process ancestry, command line, user identity, and connection destination in the alert record.

Steps for Wazuh FIM to Catch Web-Shell Changes

Start FIM at the real web root used by the host, not at a copied example path that the server never serves. Path accuracy matters because FIM can only watch the locations you configure.

Wazuh FIM alerts on file creation, modification, and deletion. It supports real-time monitoring and scheduled scans, with a default scheduled interval of 12 hours.

Monitor the correct web root

Set the monitored path to the actual web root and selected upload locations. A documented example watches /var/www/html in real time, but your server may use another directory.

FIM can record MD5, SHA-1, and SHA-256 hashes, along with file size, owner, group, permissions, and modification time. Real-time checks can raise alerts soon after a change; scheduled scans find changes during their next run.

The documented example uses a 900-second interval for 15-minute scans. Set the interval to fit the host and alert volume, then confirm scheduled scans run as expected.

Add PHP extension and content rules

Watch PHP extensions that may hold executable code: .php, .phtml, .php3, .php4, .php5, .phps, and .phar. Review the server’s actual handler settings because an extension can be served as text on one host and run as code on another.

Example content indicators include passthru, exec, eval, shell_exec, assert, system, base64_decode, proc_open, and pcntl_exec. A match needs review because these terms can also appear in legitimate code.

Wazuh example rule 100500 assigns level 12 to file creation, and rule 100501 assigns level 12 to modification. Rule 100502 assigns level 15 when a modified file matches content indicators.

Use report_changes only when you need copies of changed content for review. It stores private copies and increases storage use, so set access and retention to match your evidence needs.

Wazuh Active Response can run YARA on files added or modified after a FIM alert. Treat that scan as added analysis, not a replacement for reviewing the file and host context.

The Wazuh FIM web-root example shows the monitored path and file attributes that need adapting to your server.

Test an authorized file change and confirm the expected Wazuh alert before relying on the rule in production.

How Do You Separate a Probe from a Likely Compromise?

A suspicious request is a reason to investigate, not a verdict that the host was compromised. Look for independent evidence that connects request activity with runtime, process, or file changes.

A request indicator alone does not prove PHP was vulnerable or that execution succeeded. Memory disclosure may leave no file or process artifact.

Evidence Working assessment Immediate action
Suspicious request only Probe or attempted activity Preserve the request and check host telemetry
Request plus PHP error Higher concern, cause still uncertain Correlate PHP, web, and service logs
Unexpected PHP-worker process activity Possible command execution Escalate and preserve process details
Web-root change plus suspicious host activity Likely compromise requiring response Contain under incident procedures and preserve evidence

Recently uploaded or modified files, unusual web-server connections, and obfuscated PHP can point to web shells. A file change becomes more meaningful when it lines up with a suspicious process or network event.

Do not downgrade a case just because FIM finds no new file. A memory disclosure can expose secrets without creating code or changing the web root.

Keep the original request, PHP errors, process data, and file events available for review. Analysts need timestamps and host identity to test whether signals belong to one event.

Escalate when independent request and host signals agree, and preserve the original events for incident review.

What Should Your Team Do After a High-Confidence Alert?

If a PHP worker shows credible command execution, handle the host as an incident and involve your response team. Use the response plan so containment does not erase evidence or disrupt unrelated systems.

Follow a clear order: escalate, contain, preserve evidence, scope access, rotate exposed secrets when needed, then patch and restart workers. Rotate secrets based on exposure risk and scope, not assumption alone.

Contain and preserve evidence

  • Escalate the alert to your incident response team.
  • Contain the affected host under your organization’s process.
  • Preserve memory when relevant, plus logs and host context.
  • Assess PHP worker privileges and reachable systems.

Keep containment proportionate to the host’s role and risk. Record any service change, network block, or isolation step with its time and owner.

Scope access and rotate exposed secrets

Memory exposure can involve passwords, authentication tokens, API keys, and certificates. Review what the worker could access and which connected systems trusted those credentials.

Rotate or revoke secrets when the investigation shows exposure is plausible. Your team can then replace credentials in dependent services and check for related access.

After evidence collection, apply a fixed release and restart the relevant workers. The fixed releases include 8.5.12, 8.4.27, 8.3.36, and 8.2.35 for their branches.

Confirm the live runtime after restart and retain the audit record. Also note which worker processes changed, since a package update alone does not prove the service now uses the fixed code.

Keep a record of containment, evidence handling, and the runtime version verified after remediation.

How Do You Keep PHP2Shell Monitoring Useful Over Time?

Detection coverage drifts when new containers, alternate PHP binaries, or web roots appear without corresponding Wazuh changes. Review the inventory often enough to catch these shifts during routine operations.

PHP workers can keep running after PHP files on disk are replaced. Keep runtime-version checks in the ongoing monitoring process.

Reconcile PHP assets against the host and service inventory. Review package paths, container images, and vendor-managed deployments when infrastructure changes.

Test decoders and custom rules with saved sample events after changes. Review alert sources that have become noisy, as well as sources that have gone silent.

Revisit exceptions when hosts move, agents return, or a managed service changes its reporting method. A reasonable exception can become a blind spot when the system around it changes.

Review FIM real-time paths and scheduled scans when web-root locations or hosting layouts change. Confirm that both modes still cover the files the web server serves.

Make runtime-version verification and alert testing part of the normal PHP change process.

Keep test cases with rule configuration so your team can check behavior after a decoder edit. Record meaningful changes to paths and services in the same change review.

Conclusion

PHP2Shell monitoring is strongest when verified patch status and host-level evidence support what the web logs show. Wazuh adds visibility across inventory, logs, process events, and file changes, while patching and restarting active workers remain essential.

Your team’s next step is specific: check the highest-risk internet-facing PHP host, inspect its live worker version, and confirm alert coverage.

Choose one internet-facing PHP host today, verify its active worker version, and confirm that Wazuh receives its relevant events.

FAQ

Does Wazuh include a native PHP2Shell rule?

No, do not assume Wazuh has a native rule named for PHP2Shell. Build custom rules around audit records, parsed logs, and host events that your agents actually collect. Test decoder fields and rule matches with representative samples before enabling alerts. Keep ordinary uploads and routine service errors in the test set, so normal activity does not trigger unnecessary response.

Which PHP versions are affected by CVE-2026-109618 and CVE-2026-109619?

PHP versions 5.4 through 8.5.11 are affected by both vulnerabilities. The fixed releases are PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. PHP 8.1 and earlier branches are end of life, and the PHP project is not releasing fixes for them. Check vendor backport status separately when a package uses a different version label.

Is changing PHP files on disk enough to patch PHP2Shell?

No, changing files on disk alone does not prove the live service uses the fixed runtime. PHP-FPM, Apache, and other long-running PHP workers can keep running with their earlier memory state. Restart the serving workers or redeploy the container after the update. Then check the active process version, not only the package record or binary stored on disk.

Can Wazuh FIM detect every PHP2Shell compromise?

No, Wazuh FIM detects changes only in the paths and files you monitor. It can alert on creation, modification, and deletion, but a memory disclosure may leave no code-execution artifact. Pair file monitoring with request logs, PHP errors, and host telemetry. A clean FIM result means no watched file change was found, not that every runtime is safe.

What does PHP_SESSION_UPLOAD_PROGRESS in a request mean?

It is suspicious when it appears in a multipart request sent to a route that does not normally accept uploads. The field can be a clue to probing, especially beside unusual session IDs or other odd request markers. It does not prove that PHP was vulnerable or that an attacker ran code. Correlate the request with host and runtime evidence.

Should I restart a host as soon as I see suspicious PHP activity?

No, not when active probing or anomalous PHPSESSID cookies suggest a possible incident. A restart destroys volatile memory held by PHP-FPM and Apache workers. Coordinate capture with incident responders and preserve nearby logs and host context first. Routine patching can proceed after responders decide memory evidence is no longer needed or has been collected.

on this page