
CVE-2026-17544 漏洞利用程序:将 PHP bcmath 越界写入(OOB write)转化为纯内存 RCE,借助运行时无偏移解析器绕过 disable_functions 和 open_basedir。
针对 CVE-2026-17544 的武器化概念验证,该漏洞是 PHP 重写的 bcmath 扩展(bc_str2num)中的越界写入。它将公开已知的仅 DoS 崩溃转化为一个完整、通用、纯内存的远程代码执行原语,同时绕过 disable_functions 和 open_basedir。
仅限授权研究/教育用途。 仅可对您拥有 或明确获准测试的系统运行。
![]()
bc_str2num 在手动设置 scale 时截断小数部分,重新去除尾随零,但未更新 fractional_end。缓冲区按重新修剪后的长度分配大小,而复制使用的是修剪前的长度 → 向 Zend MM 堆中执行受控的越界零写入。zend_string 的 refcount 清零(长度保持不变)→ refcount 失同步导致的释放后使用(UAF) → 巨型字符串相对读写 → 容错绝对任意读 → 运行时符号解析 → 完全仅数据的原生函数调用。zend_class_entry + 内联 function_table + 伪造的 zend_function{ handler = zif_shell_exec },然后将其作为方法调用。命令输出以字符串形式返回并写入响应/stdout。.data 和目标符号均在运行时通过内存扫描解析——因此同一个文件可跨不同构建和发行版使用。这是一个沙箱逃逸 / 后渗透原语,而非仅限远程输入的 RCE。
| 场景 | 结果 |
|---|---|
攻击者已能执行 PHP(webshell、反序列化、eval 汇点),但受 disable_functions + open_basedir 限制 | ✅ 原生 RCE(本 PoC) |
应用仅对原始用户输入调用 bcmath 函数,例如 bccomp($_POST['v']) | ❌ 仅 DoS / 崩溃 |
攻击者输入上的单个 bcmath 调用只会产生一次盲越界零写入,且没有任何反馈。完整的 RCE 需要任意 PHP 执行来整理堆布局、构建读写原语并运行解析器——这些都无法以函数参数的形式表达。因此,仅输入暴露的现实上限是远程拒绝服务;代码执行需要一个已存在的 PHP 执行上下文,本 PoC 随后将其从沙箱中释放出来。
该漏洞仅存在于重写后的 bcmath(PHP 8.4 / 8.5 系列)中:
已在使用相同未修改文件的 PHP 8.4.23 和 PHP 8.5.8(amd64)上完成端到端验证(uid=0,输出已捕获)——Zend 结构布局在 8.4 / 8.5 中完全相同。
bcmath。.text 逐页向下走到 ELF 头;这对任何连续映射的二进制文件都是安全的。只有人为使用 -z separate-code 构建、带有未映射 2 MB 间隙的二进制无法通过盲扫描自动解析(生产环境中未见过)。exit() 不会杀掉服务器:php-fpm、Apache mod_php,或设置了 PHP_CLI_SERVER_WORKERS>0 的内置服务器。php exploit.php "id; uname -a"
例如部署为 shell.php,然后:
GET /shell.php?cmd=id
POST cmd=id
命令输出通过 zif_shell_exec 捕获并写入响应体。
bccomp(),使越界零写入仅落在相邻 zend_string 的 refcount 上(长度保持不变)。zend_reference(通过间接引用)提供了容错绝对任意读,且从不触碰目标的带 refcount 头部。.text 指针出发:逐页向下走到 ELF 魔数(基址),解析程序头以找到 .data,然后扫描 .data 查找 shell_exec 的 zend_function_entry,其 handler 指向 .text。zend_class_entry、一个带单个 bucket 的内联 function_table(正确的 zend_string 哈希,碰撞链已终止),以及一个 handler 为 zif_shell_exec 的伪造 ;篡改探针对象的 class 指针并调用该方法。输出被返回并回显。exploit.php — 通用纯内存利用(CLI + Web)。仅供安全研究与教育用途。作者不对滥用行为负责。请勿将其部署到未经授权测试的系统上。
| PHP 分支 | 受影响 |
|---|
| 7.x, 8.0 – 8.3 | 否(旧版 libbcmath,bc_str2num 不同) |
| 8.4.0 – 8.4.23 | 是 |
| 8.5.0 – 8.5.8 | 是 |
| ≥ 8.4.24 / ≥ 8.5.9 | 已修复 |
zend_internal_function