Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
php2shell-detect — Zeek and Suricata Detections for "php2shell" CVE-2026-109618 and CVE-2026-109619 | Kitploit
Tools/GitHubGitHub/corelight/php2shell-detect
Defensive ToolsPacket Sniffing & AnalysisVulnerability AnalysisWeb SecurityNetwork SecurityIntrusion DetectionIncident Response
GitHubcorelight/php2shell-detect

php2shell-detect

Zeek and Suricata Detections for "php2shell" CVE-2026-109618 and CVE-2026-109619

View Repository
10593 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

php2shell Detection

Zeek detections and Suricata rules for HTTP indicators associated with "php2shell" CVE-2026-109618 / CVE-2026-109619, potential RCE in PHP longjmp() memory handling. Findings identify suspicious traffic or potentially affected software.

  • [Corelight blog: PHP2Shell detection before disclosure][blog]
  • PHP advisory

Zeek

Requires Zeek 7.0.0 or later. Install with the Zeek Package Manager:

zkg install https://github.com/corelight/php2shell-detect

Load installed packages with @load packages in your Zeek configuration. For a direct checkout, load /path/to/php2shell-detect/scripts. The package uses standard Zeek HTTP, file-analysis, notice, and cluster APIs.

The package inspects POST field-name lengths, selected serialized-data structures, and repeated MIME headers. It also correlates related suspicious transactions using configured session cookies. Response headers provide separate PHP version inventory. Traffic must be visible to Zeek's HTTP analyzer; encrypted HTTP requires decryption before inspection.

Notices

All notice types are under PHP2SHELL:::

NoticeObservation
PHP_Crash_SequenceRelated suspicious HTTP transactions within one session
Multipart_Header_FloodExcessive repetition of recognized MIME headers
Large_Form_KeyUnusually long URL-encoded form field name
Serialized_Integer_OverflowUnusually large serialized integer token
Serialized_Integer_CollisionsRecognized serialized integer-key pattern
Serialized_String_CollisionsRecognized serialized string-key pattern
Serialized_Duplicate_ArrayRepeated serialized array-entry pattern
Serialized_Object_RepetitionRepeated serialized object pattern
Potentially_Affected_PHP_VersionResponse header advertises a version within the configured affected range

Results go to standard notice.log; the package creates no additional log stream. The notice sub field supplies bounded context such as header name, transaction depth, counts, and a short escaped POST-body sample. Samples are limited to 64 raw bytes before escaping by default; set notice_body_sample_bytes=0 to omit them. Cookies and their digests are used only in memory and are not logged by this package.

By default, each distinct request indicator can emit a notice per transaction. Repeated matches of the same indicator are suppressed. Set detect_only_once=T to stop body inspection after the first request finding in each transaction. Version inventory notices are independent of request findings.

Configuration

All settings use the PHP2SHELL:: namespace:

SettingDefaultEffect
detect_only_onceFReport each distinct request indicator; T stops after the first finding
max_trans_depth3Inspect the first three HTTP transactions per connection; 0 means all
inspect_cookiesTUse session cookies for correlation
session_cookie_names{"PHPSESSID"}Cookie names used to associate sessions
correlation_window1 minMaximum age of pending session correlation state
max_pending_sessions1000Cap retained entries in each correlation table
inspect_post_bodiesTInspect POST entity data and MIME headers
http_body_analysis_byte_depth8388608Conservative 8 MiB ceiling on POST-body inspection work, shared across MIME parts; 0 disables body delivery
body_overlap_bytes256Retained overlap for patterns crossing body chunks
large_form_key_bytes65536Form-name wire-byte threshold
multipart_header_threshold128Repeated recognized MIME headers needed for a finding
notice_body_sample_bytes64Maximum raw body bytes per notice sample; 0 omits samples
detect_affected_php_versionsTEnable response-header version inventory
php_version_notice_interval1 hrSuppress version notices per server IP across ports and versions
php_fixed_patch_versions8.2: 35, 8.3: 36, 8.4: 27, 8.5: 12Provisional first fixed patch per branch

For example:

redef PHP2SHELL::detect_only_once = T;
redef PHP2SHELL::notice_body_sample_bytes = 0;
redef PHP2SHELL::session_cookie_names += { "custom_session" };

POST inspection uses file-analysis chunks with bounded overlap, rather than assembling whole bodies. Form-name counting respects value separators and raw NUL termination. Only eligible POST entities receive an analyzer; body budgets and transaction limits intentionally constrain detection scope. These indicators are incomplete and can also match benign traffic.

In a Zeek cluster, workers route small session observations to proxies with Cluster::publish_hrw(). Both stages for the same session reach the same proxy, which matches them and raises PHP_Crash_Sequence directly. The notice retains the follow-up's connection ID, UID and transaction depth; peer_descr identifies the proxy. Workers do not retain full connection or HTTP records for callbacks.

Triggers and unmatched follow-ups expire after correlation_window, with max_pending_sessions limiting each table. Proxies retain the first unmatched follow-up for each session key. A trigger looks up that key directly to handle messages arriving in reverse order; later unmatched follow-ups for the same key are coalesced until that entry matches or expires. Matching uses observation timestamps and the client, server, server port, HTTP host and session digest. Standalone Zeek correlates locally. Normal proxy connectivity is required.

Proxy notices use standard notice suppression keyed by UID and transaction depth for correlation_window. This is independent of worker findings and does not stop worker body inspection. Simultaneous matches for different session cookies on different proxies can still produce duplicate notices before cluster suppression propagates.

PHP version inventory

Outer Server and X-Powered-By response headers are checked, including responses to GET. Header names are case-insensitive. The affected lower bound is PHP 5.4.0. The following cutoffs assume the next patch after the latest stable releases checked on 18 October 2026 will address both bugs:

BranchLatest stable when checkedProvisional first fixed release
8.28.2.348.2.35
8.38.3.358.3.36
8.48.4.268.4.27
8.58.5.118.5.12

Configured fixed releases and later patches in the same branch do not alert. Branches without a configured cutoff remain candidates. Common vendor suffixes use the underlying numeric version. Banners can be absent, rewritten, or reflect a vendor build with backported fixes, so these are inventory hints.

Suricata rules

The three rules in [suricata/php2shell.rules][rules] run independently of Zeek. Installing the Zeek package with zkg does not load these rules into Suricata. All three rules are enabled in the file; Zeek configuration options do not affect them.

SIDInspection bufferObservation
3000650http.request_body with method POSTDetection marker in a request body
3000651http.response_headerPotentially affected PHP version advertised by Server or X-Powered-By
3000652http.response_bodyPotentially affected PHP version in a phpinfo-shaped HTML heading

Loading the rules

Add the rule file to the existing rule-files list in your suricata.yaml, keeping your other rule entries. Use the absolute path to your checkout:

rule-files:
  - /path/to/php2shell-detect/suricata/php2shell.rules

Validate your configuration, then reload or restart Suricata using your normal deployment procedure:

suricata -T -c /path/to/suricata.yaml
Download Tool