Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
php-cve-2026-10961x-lab-poc — PHP CVE-2026-109618/109619 — 在原生 PHP 8.5.11 上实现自包含的未认证 RCE(带内 PS(id)→cookie 内存泄露 + UAF 链),完整控制权提升阶梯,以及在 8.5.12 上的修复版本阴性对照 | Kitploit
工具/GitHubGitHub/dinosn/php-cve-2026-10961x-lab-poc
内存取证漏洞分析漏洞利用Web应用程序漏洞利用WAF绕过Web安全模糊测试论文与研究二进制利用

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
实验室与实践
GitHubdinosn/php-cve-2026-10961x-lab-poc

php-cve-2026-10961x-lab-poc

PHP CVE-2026-109618/109619 — 在原生 PHP 8.5.11 上实现自包含的未认证 RCE(带内 PS(id)→cookie 内存泄露 + UAF 链),完整控制权提升阶梯,以及在 8.5.12 上的修复版本阴性对照

查看仓库网站
66164416小时59分前尚未审核

php2shell lab — PHP CVE-2026-109618 / CVE-2026-109619

针对 PHP 8.5.11 php2shell 类漏洞(CVE-2026-109618、CVE-2026-109619,2026 年 10 月)的实验复现与漏洞研究包。 状态:已证实 — 自包含 RCE(四个普通 HTTP 请求,无需调试器,无需本地访问),另附下文中的放大效应、补丁缺口与 FPM 陈旧状态发现。

目录: 结果 · 利用链 · 放大效应 · 补丁缺口 · FPM 陈旧状态 · WAF 绕过 · 环境 · 快速开始 · 证明规范 · 目录结构 · 公开背景 · 声明


结果一览

#发现分类
1在 PHP 8.5.11 上实现端到端自包含 RCE — 四个普通 HTTP 请求,通过 PS(id)→cookie 泄露进行带内地址获取,两个基址均来自一次 512 字节的 PHPSESSID 泄露;12/12 次触发成功,uid=33,覆盖 8 个 ASLR 代次已证实 — 自包含 RCE
2通过重复的 6 字节 multipart 头部实现 52 倍内存放大 — 在 PHP 7.4–8.5.11 上突破 post_max_size(2.57 MB 请求体即可使 128M 限制发生 OOM)已证实 — 实验环境,全部四个版本
3三条利用路径在 8.5.12 安全补丁后依然存活(n=1015 时的 var_destroy 重入 UAF、序列化处理器不匹配、上传进度注入)已证实 — 在经 GPG 验证的 8.5.12 上通过 ASAN
4FPM 陈旧 BG(unserialize):worker 在会话解码 OOM 后存活,陈旧状态被下一请求的 rfc1867 窗口消费,堆塑形消费导致 worker 发生 SIGSEGV已证实 — 机制 + DoS;RCE 未证实
5Content-Type 分隔符绕过(multipart/form-data, boundary=X)— 所有已公开的以 Content-Type 为锚点的 WAF 签名均可被绕过已证实 — SAPI.c 解析器行为
6两条 CVE 利用链在已修补的 8.5.12 上均失效(configure 令牌一致,源码经 GPG 验证)已证实 — 阴性对照
7公开的“缓存 zval session.upload_progress”理论 — 在 4 个原版 PHP 版本 + 3 个 LiteSpeed 厂商构建、所有清理/并发角落上均被驳斥已驳斥 — 穷尽验证

利用链

两条独立的内存破坏利用链在原版 php:8.5.11-apache 镜像上均能到达攻击者可控的间接调用;端到端封装将链 B 的机制与一种新颖的带内泄露相结合,实现完全远程触发。

链 A — 陈旧 bucket链 B — 悬空引用
机制OOM 退出路径留下一个已发布但未初始化的 HashTable bucket;关闭过程将其作为伪造 zval 消费 → 伪造数组 → pDestructorRINIT 前 OOM 使 PS(http_session_vars) 持有悬空的 zend_reference;一个存活的 31 字节字符串将其回收;伪造引用 → zend_hash_destroy pDestructor
分配器tracked/system(USE_ZEND_ALLOC=0)原版默认 Zend MM
终端libc system()(经 gdb 校准的地址)zif_system @ libphp+0x5996e0(无 libc)
触发时调试器仅用于校准无 — FIRE_GDB=0
可复现性2 个随机化父代次可重复,包括跨运行

端到端回执(12/12 次触发,8 个 ASLR 代次,无调试器,无本地访问)

Leak-A 布置一个悬空的 PS(id)(第 1001 个变量触发 max_input_vars → headers_sent=1;空 cookie 的 reset_id 失败使 send_cookie=1 保持为 1; 一个 24 MiB 的字段在 RINIT 之前触发 OOM)。Leak-B 落下一个 257 元素的数组,其 zend_array 与 PS(id)−0x10 重叠:ZSTR_LEN 读取到 nTableSize=512,并且 URL 编码的 cookie 携带 pDestructor(→ libphp 基址)以及九个 arData 堆指针(多数投票 → chunk 基址)。实测的 chunk−libphp 差值 在不同代际之间并非恒定(−0x1a00000 / +0x3600000 / −0x1c00000), 因此该信息泄露确实起着关键作用。随后利用泄露的地址执行触发。前提条件:display_errors=On、post_max_size 高于 OOM 字段、memory_limit 低于它、单 worker 的 prefork。

A status='HTTP/1.1 200 OK'   → OOM fatal, worker survives, PS(id) armed
B Set-Cookie: PHPSESSID=<512-byte encoded disclosure>
FIRE → MARKER=uid=33(www-data) gid=33(www-data) groups=33(www-data)
FIRE_OK   (×12 across 8 distinct ASLR layouts)

完整复现与控制阶梯:docs/END-TO-END.md。

52 倍内存放大

优化后的重复头部放大:短的 X: a 头部(线上 6 字节)利用 PHP 为每个保存的头部固定分配 256 字节 SMART_STR_START_SIZE(每 6 字节线上数据约 314 B 内存)。在 8.5.11 上通过精确的 OOM 阈值二分法测量;在 7.4.33 / 8.1.34 / 8.4.26 上结果相同(51–52 倍):

memory_limit最小 OOM 请求体放大倍数
8M153 KB54.8x
32M636 KB52.8x
128M2.57 MB52.3x
256M5.14 MB52.2x

所有请求体均能容纳于默认的 post_max_size=8M 之内——实际的上传屏障在每个未修补版本上均被突破。分块传输编码还额外绕过了 Content-Length 预检查(8.85 MB 的分块请求体被解析并触发 OOM,而同一请求体带 Content-Length 时被拒绝)。8.5.12 补丁封堵了这两个向量(未知头部过滤 + 流式 post_max_size 强制执行)。嵌套数组“炸弹”形态不会呈现指数级放大(最大 9.6 倍,1.16 MiB——即使 8M 也无法 OOM)。详情:docs/RELEASE-RECONCILIATION-2026-10-21.md。

8.5.12 上的补丁缺口

在经 GPG 验证、令牌完全一致的 8.5.12 ASAN 构建上验证——两个 CVE 已修复,但仍有三条独立的可利用路径在补丁后存活:

  1. var_destroy 重入 UAF(CWE-416)——边界在 n=1015 处不变,与 8.5.11 相同(故障位于 var_unserializer.c:906:67);补丁的 ZEND_HAS_OOM 防护在此路径上无效;BG(serialize_lock) 在 __destruct 调度周围仍未被获取。
  2. 序列化处理器不匹配——由 php_serialize 写入的 | 键会话,在应用阶段 session_start() 之后由 php 处理器解码,会在 mod_php php_value 和 FPM .user.ini 上同样实例化 gadget;补丁的 incomplete_classes_only 防护仅作用于 RINIT 前的上传窗口。
  3. 上传进度注入——攻击者控制的键被原样存入会话文件。

FPM 陈旧 BG(unserialize)

在 php:8.5.11-fpm 上经实验室验证:在 memory_limit=32M 下,一个 24 MB 的会话在 php_var_unserialize 内部触发 OOM,而工作进程存活——退出码 70 的屏障仅适用于启动阶段的 OOM。gdb 显示 BG(unserialize).level=1 以及陈旧数据指针持续存在,进入下一个请求的 rfc1867 RINIT 前窗口;一个 8191 字节的 multipart 字段产生 8216 字节的 _emalloc,与陈旧指针重叠,并在请求启动期间于 var_tmp_var 中使工作进程发生 SIGSEGV。实测影响:可重复的工作进程崩溃(DoS)外加一个内存破坏原语;崩溃之外的 RCE 尚未证实。前提条件:较低的 memory_limit、较大的受攻击者影响的会话、一个 session_start() 端点、upload_progress=On,以及 pm=static max_children=1 以实现可靠的同一工作进程配对。因此,对于此类问题,FPM 是有条件地而非绝对地受到保护。

WAF 签名绕过

Content-Type: multipart/form-data, boundary=X(逗号分隔符)会被 PHP 接受——SAPI.c 在 ;、, 和空格处截断。所有以 Content-Type: multipart/form-data; 为锚点的已发布 php2shell WAF 签名均可被绕过。防御者指南见 docs/WAF-BYPASS.md。

本仓库未证明的内容

  • 针对加固生产部署的单次利用(多工作进程 prefork 可靠性、display_errors=Off 以及高 memory_limit 均仍是真实屏障——参见 docs/RELEASE-RECONCILIATION-2026-10-21.md 中的集群研究);
  • 从 FPM 陈旧状态原语实现 RCE(目前仅能崩溃);
  • 对除明确测试过的版本之外的 PHP 版本的影响(7.4.33 / 8.1.34 / 8.4.26 / 8.5.11 / 8.5.12 原版,3 个 LiteSpeed 构建)。

精确环境

属性必需值
主机原生 Linux x86_64
目标PHP 8.5.11,Apache 模块(Chain B 也运行在 FPM 上以进行陈旧状态相关工作)
镜像php@sha256:974e3a920309308e1690ed607e6cc3061d6906f90cc8d30fe519daa48bccf101
Chain A 分配器USE_ZEND_ALLOC=0、USE_TRACKED_ALLOC=1(有意使用非默认值)
Chain B 分配器默认 Zend MM
PHP 限制(链)memory_limit=16M、post_max_size=32M、upload_max_filesize=32M
Apacheprefork,恰好一个 worker
调试器支持 Python 的主机 GDB(仅用于校准/回执)

快速开始(Chain A 运行器)

仅在自有且隔离的 x86_64 Linux 实验环境中运行:

sudo ./scripts/preflight.sh
sudo ./scripts/reproduce.sh

运行器会校验环境、生成字节完全一致的 5,767,505 字节 fixture、校准一个安全的 type-0x7 槽位,然后运行全新 worker 的 negative → abort → marker 流程,并执行独立的 marker 字节、worker 状态转换、健康检查和 trace 检查,最后写出完整的 SHA-256 清单。受保护放置未命中会被记录,并按每个全新 worker 重试一次——未命中绝不会被报告为已执行。只有当 runs/DATE/VERDICT.json 中的每个门禁都为 true 时,保留的判定才有效;无需触发即可重新验证:python3 scripts/verify_run.py runs/DATE。

sudo ./scripts/lab-stop.sh     # stop container, keep state
sudo ./scripts/lab-reset.sh    # remove PoC container + network only

证明规范

用例预期效果RCE 判定依据
校准观察到 Type-0x7 陈旧槽位;worker 存活无
阴性存在伪造结构;无调度;同一 worker标记缺失
中止引用计数递减;精确的 abort@plt;SIGABRT标记缺失
标记精确的目标调度;命令输出位于 /tmp 下精确的唯一字节

HTTP 错误、空响应、PHP 致命错误或 worker 崩溃不被接受为命令执行证据。FPM 陈旧状态发现之所以被报告为崩溃原语,正是因为它尚未通过这一标准。

安全属性

  • 位于内部网络上的专用 Docker 容器;不发布主机端口。
  • 镜像通过摘要固定。PoC 构建器不接受任意命令。
  • 执行载荷仅限于 id/printf 类命令,且仅在专用容器内写入 /tmp 下。
  • 每次会话中阴性用例和受控中止用例均为强制项。
  • 主机 GDB 仅附加到指定实验容器的唯一 worker。

仓库布局

app/                    Minimal PHP/Apache target
tools/                  php2shell_test.py (v1+v2) + domain_php2shell_scan.py
ninebie/                Chain B PoC (send/env scripts, fire entry point, receipts)
docs/                   Proof boundary, port write-ups, reconciliation log
evidence/reference/     Chain A two-generation proof summary + provenance
evidence/validation-*/  Chain A compact evidence, two fresh generations
scripts/                Chain A lab, calibration, body, runner, verifier
tests/                  Deterministic fixture and safety tests
artifacts/, runs/       Generated locally; ignored by Git

SOURCE-SHA256SUMS 用于认证目录树:python3 scripts/make_manifest.py --verify。

公开背景

  • docs/PUBLIC-CONTEXT-2026-10-21.md — 公开记录与本实验室的对比: 我们验证了什么、驳斥了什么(对缓存 zval 的 session.upload_progress 理论进行了穷尽性检验)。
  • docs/RELEASE-RECONCILIATION-2026-10-21.md — 发布后每项发现的 持续记录:放大效应、补丁缺口、FPM 陈旧状态、 第三方主张的裁定(junaire、bnd9、Whackermelon、ikow Chain E)。
  • docs/WAF-BYPASS.md — Content-Type 分隔符绕过 + 防御者指南。
  • docs/NINEBIE-CLASS-PORT.md — Chain B 机制、偏移量、差异。
  • docs/END-TO-END.md — 自包含的 RCE 凭证与控制阶梯。
  • docs/ASLR-STOCK.md — 默认配置(无 php.ini,128M)下 A 阶段武装 OOM 与 B 阶段 128M 堆泄漏:缓存遍历 + 伪造 PS(id) -> 从 Set-Cookie 获取 Zend-MM 块基址 (tools/php2shell_aslr_stock.py、tools/php2shell_stock_chain.py, 演示位于 demo/aslr-stock/)。

披露声明

下载工具