该漏洞利用php在处理multipart/form-data请求时,对post数据大小限制(post_max_size)的解析逻辑缺陷,通过构造极长的边界字符串或大量小字段,使php内部缓冲区在验证阶段反复扩容,最终耗尽内存。核心在于php未能在早期阶段正确截断或拒绝超出限制的畸形请求,导致内存分配失控。

为什么multipart请求能触发此漏洞?
multipart请求包含特殊的Content-Type和Boundary参数,PHP需要逐行解析以提取表单字段。当Boundary字符串被恶意构造为极长序列时,PHP的内部解析器在匹配边界时会进行大量的字符串比较和内存复制操作。这种设计初衷是为了支持大文件上传,但在面对精心构造的输入时,解析过程中的临时缓冲区会迅速膨胀,从而触发内存耗尽。

post_max_size内如何耗尽内存?
post_max_size限制了整个POST请求体的最大大小,但PHP在解析multipart数据时,会在达到该限制之前先进行分块处理。攻击者可以发送一个总大小略小于post_max_size的请求,但其中包含成千上万个微小的、带有超长Header的字段。PHP在处理每个字段时都会分配新的内存空间来存储键值对,这些碎片化的内存分配累积起来,远超实际数据体积,导致Zend Engine内存管理器崩溃。

基于具体输入条件的内存溢出验证
为了验证这一机制,我们可以构造一个简单的PHP脚本模拟接收multipart数据的过程。虽然直接测试CVE需要特定的PHP版本和环境,但以下代码展示了如何通过控制输入来观察内存行为。在实际环境中,这通常表现为500错误或进程被SIGKILL。
<?php // 模拟multipart解析的简化逻辑
$boundary = "----WebKitFormBoundary" . str_repeat("A", 1000);
$content_type = "multipart/form-data; boundary=" . $boundary;
// 构造一个小的payload,但具有复杂的头部结构
$fields = [];
for ($i = 0; $i < 10000; $i++) {
$fields[] = "--{$boundary}\r\nContent-Disposition: form-data; name=\"field_{$i}\"\r\n\r\nvalue\r\n";
}
$payload = implode("", $fields) . "--{$boundary}--";
echo "Payload size: " . strlen($payload) . " bytes\n";
echo "Memory limit: " . ini_get('memory_limit') . "\n";
// 注意:实际CVE利用需要更精细的控制,此处仅为演示结构
// 在真实攻击中,边界字符串的长度和字段的数量是关键变量
?>











