Apache HTTPD 漏洞复现系列
2023-06-16 14:30:42 # Web Security # Apache

前言

本章总结了一系列的Apache相关的漏洞,从漏洞形成到漏洞触发到漏洞总结。

什么是Apache

Apache HTTP Server是一种Web服务器,负责回应收到的web请求。

例如,Apache收到/index.php的请求时,通过CGI调用PHP解释程序,执行/index.php,返回结果给客户端

httpd是Apache超文本传输协议(HTTP)服务器的主程序。被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池。

Apache HTTPD 换行解析漏洞(CVE-2017-15715)

漏洞简介

影响版本:apache2.40~2.4.29

复现靶机:https://vulhub.org/#/environments/httpd/CVE-2017-15715/

漏洞环境:

1
2
docker-compose build 
docker-compose up -d

漏洞原理

漏洞形成点一:$与FilesMatch

在该版本的apache配置中,有一段这样的代码

1
2
3
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>

我们使用FilesMatch来匹配.php结尾的文件,并将文件解析为php文件(SetHandler application/x-httpd-php

此处$就是结尾的意思。但需要注意的是dollar符号也会匹配到换行符0xa

举个例子: 如果文件名是.php+换行符结尾,仍然会被匹配,在这个情况下,依然会被解析为php文件。

漏洞形成点二:文件上传点

image-20210904143549934

观察发现,在index.php中有一处上传点,此处会获取name参数,并检测name是否在黑名单内,如果不在,就会将上传的文件移动到当前目录下。

此处为什么不可以直接上传.PHP呢?如果你动手试一下,发现确实是可以上传的,而且绕过了黑名单。但问题在于,它并不会被解析。 在前面提到的配置文件中,FilesMatch只对.php后缀的文件进行匹配并解析,所以即使你能够上传.PHP,它也不会被解析为php文件。

但如果我们上传文件名是.php+换行符,那就可以成功绕过黑名单并解析了。

漏洞复现

抓包上传一个php木马

修改name参数(注意,POST请求中的参数名在html表格中是这样的 name="这里是参数名")

image-20210904144515665

php后面加上空格,再把这个空格改成16进制的0a(换行符)

image-20210904144609268

使用菜刀访问:/leihehe.php%0a

image-20210904144816659

注意:在windows下可能无法实现,因为windows下无法保存含有换行符的文件名

漏洞总结

$的正则匹配并不会过滤掉换行符0xa,以后遇见$,就有更多的潜在突破口了。

Reference

怎样通俗的讲解 PHP 和 Apache 的关系? - yskin的回答 - 知乎

Apache HTTPD 换行解析漏洞(CVE-2017-15715)与拓展

Apache HTTPD 多后缀解析漏洞

漏洞简介

复现靶机:https://vulhub.org/#/environments/httpd/apache_parsing_vulnerability/

漏洞环境:

1
2
docker-compose build 
docker-compose up -d

漏洞原理

漏洞形成点一:AddHandler .php及Apache解析特性

我们在配置文件下可以看到以下代码:

1
2
3
4
AddHandler application/x-httpd-php .php

DirectoryIndex disabled
DirectoryIndex index.php index.html

此处的AddHandler的意思是如果后缀为.php,那么我们就给他加上x-httpd-php处理器,也就是将此文件解析为php文件。

Apache在处理文件时有个特性 - 从右到左解析文件。

比如hello.php.jpg,Apache会先检测到.jpg这个后缀,接着他会在这个上面的配置文件中寻找,发现并没有解析.jpg的规则,于是他便往前寻找后缀,这时发现了.php后缀,再在配置文件中寻找发现.php可以被解析为php文件。由此,hello.php.jpg不会被解析为jpg,反而会被解析为php,即使php后缀不是在最后。

漏洞形成点二:文件上传点

index.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

if (!empty($_FILES)):

$ext = pathinfo($_FILES['file_upload']['name'], PATHINFO_EXTENSION);//获取后缀名
if (!in_array($ext, ['gif', 'png', 'jpg', 'jpeg'])) {
//如果后缀名不在白名单中,返回以下信息
die('Unsupported filetype uploaded.');
}

//如果后缀在白名单范围中,上传该文件
$new_name = __DIR__ . '/uploadfiles/' . $_FILES['file_upload']['name'];
if(!move_uploaded_file($_FILES['file_upload']['tmp_name'], $new_name)){
die('Error uploading file - check destination is writeable.');
}

die('File uploaded successfully: ' . $new_name);

else:
?>
<form method="post" enctype="multipart/form-data">
File: <input type="file" name="file_upload">
<input type="submit">
</form>

此处图片格式的文件可以被上传,那么我们可以伪造以下文件名:hello.php.jpg

即可将文件成功上传,该文件会被解析为.php文件(jpg没有对应的解析规则,所以会往前寻找后缀)

漏洞复现

上传一个文件名为leihehe.php.jpg的文件

image-20210905114020401

成功解析!

漏洞总结

Apache在找不到相应后缀解析规则时,会往前寻找后缀 - 该特性很重要。