文件上传(二)--Apache和Nginx

本文最后更新于:10 个月前

下面我们来总结另外几个与中间件以及http请求头有关文件上传的漏洞,它们都与客户机或服务器的操作系统无关。

Apache

文件名解析漏洞

由于Apache解析文件后缀名的顺序是从右往左,所以我们可以在文件名最后加上Apache无法识别的文件后缀名来绕过。例如我们要上传一个PHP木马,那我们可以把文件名命名为”*.php.123”,其中”123”是Apache无法识别的后缀名,则Apache会解析左边的”php”后缀名,从而实现绕过。

.htaccess

Apache中的.htaccess文件是用户用来自定义管理目录的,我们可以新建一个”.htaccess”文件,并在里面写入自定义的内容,例如:

1
2
3
4
<FilesMatch "test">
SetHandler
application/x-httpd-php
</FilesMatch>

这样Apache会把文件名中含有”test”的文件当作PHP文件执行。利用这个特性,我们可以把图片马以这样的方式让Apache解析。

Nginx

文件名解析漏洞

大多数网站都使用白名单机制限制上传文件类型,但是我们可以在上传文件的路径后面加上”*.php”,例如https://www.example.com/upload/1.png/2.php。当Nginx解析到URL中的”2.php”时,由于我们并没有真正上传这个文件,Nginx会向上级目录查找,即把我们实际上传的”1.png”当作PHP文件解析。这里”1.png”实际上是修改了后缀名的大马或小马。

PHP

.user.ini

和上面Apache的.htaccess配置文件类似,.user.ini是用户自定义的PHP配置文件,我们可以利用这个文件来构造后门和隐藏后门。

PHP 配置项中有两个配置可以起到一些作用:

1
2
auto_prepend_file = <filename>         //包含在文件头
auto_append_file = <filename> //包含在文件尾

这两个配置项的作用相当于一个文件包含,比如:

1
2
3
4
5
// .user.ini
auto_prepend_file = 1.jpg
// 1.jpg
<?php phpinfo();?>
// 1.php(任意php文件)

满足这三个文件在同一目录下,则相当于在1.php文件里插入了包含语句require(‘1.png’),进行了文件包含。

另一条配置包含在文件尾,如果遇到了 exit 语句的话就会失效。

.user.ini使用范围很广,不仅限于 Apache 服务器,同样适用于 Nginx 服务器,只要服务器启用了 fastcgi 模式 (通常非线程安全模式使用的就是 fastcgi 模式)。

但它同时也存在局限。在.user.ini中使用这条配置也说了是在同目录下的其他.php 文件中包含配置中所指定的文件,也就是说需要该目录下存在.php 文件,通常在文件上传中,一般是专门有一个目录用来存在图片,可能小概率会存在.php 文件。但是有时可以使用 ../ 来将文件上传到其他目录,达到一个利用的效果。

base64解码

在PHP的base64_decode中,会只对合法字符合并后解码,非法字符则直接丢弃,不参与整体的base64解码。合法字符包含以下64个字符:

1
A-Za-z0-9/+

等于号是占位符,不是编码范围内的字符。利用PHP的这种特性,我们可以编写图片马,在正常的图片中插入base64编码后的一句话木马:

1
2
3
PD89YCRfR0VUWzFdYDs7Pz4C
//base64_decode后得到:
<?=`$_GET[1]`;;?>

使用方式:URL?1=phpinfo()

MIME类型检测

服务器通过对http请求头里的”content-type”字段进行检验,来判断文件类型是否符合要求。常见的符合要求的文件名有:image/jpeg,image/gif,image/png等。要利用这个漏洞,我们需要把http请求头中的”content-type”字段改为上面几种符合要求的MIME即可。不过要注意要在文件头加上”GIF89a”来绕过可能的文件头校验。

那如果遇到白名单检测呢?这时候就要配合文件包含和%00截断漏洞了。在以后的笔记中,我将会总结WAF绕过的一些技巧。


文件上传(二)--Apache和Nginx
https://rookieterry.github.io/2021/10/07/文件上传(二)-Apache和Nginx/
作者
HackerTerry
发布于
星期四, 十月 7日 2021, 5:58 下午
许可协议