什么是文件上传漏洞?
文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
造成文件上传漏洞的原因
-
对于上传文件的后缀名(扩展名)没有做较为严格的限制
-
对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查
-
权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件)
-
对于web server对于上传文件或者指定目录的行为没有做限制
文件上传校验姿势
1.客户端js校验(也称前端验证,一般只校验后缀名)
一般都是在网页上写一段javascript脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。
判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。前端验证非常不可靠,通过修改数据包后缀名即可绕过,甚至关闭js都可以尝试绕过。
2.服务端校验:
(1).文件头content-type字段校验(image/gif)
(2).文件内容头校验(GIF89a)
(3).后缀名黑名单校验
(4).后缀名白名单校验
(5).自定义正则校验
3.WAF设备校验(根据不同的WAF产品而定)
实战靶场
这里使用的练习靶场是GitHub上的开源靶场,下载下来后放入PHPstudy的www文件夹即可本地运行。靶场下载地址
前端验证绕过
审计源码,发现只能上传jpg、png、jif的文件类型。
解题步骤:1、写一个一句话木马,然后修改为jpg为后缀名或其他的可以上传的文件。
2、通过抓包修改上传到服务器上的文件后缀名,使其能够被web容器解析。
这里把1.jpg修改为1.php
把包发出去,然后连接一句话。
Content-Type方式绕过
通过分析源码可知是文件内容检测,查看了文件内容或者文件头,绕过方法我们制作一个图片马就Ok了。
可以看到在文件底部有一个我们制作的一句话木马。还是通过抓包修改后缀为php
黑名单绕过
分析代码,发现拦截了后缀为.asp、.aspx、.php、.jsp的文件。那么问题来了,只有后缀名.php的文件才会被php解析池解析吗?答案是否定的,看下面这张图。
如果默认状态下.php3/.php4/.php5/.phtml都会被当做php被解析。直接修改上传马的后缀名为其中任意一项就ok了,在这题种经过我的测试,只有后缀名为.php3和.phptml的可以被当做php文件解析。
.htaccess文件绕过
.htaccess是什么?.htaccess文件也被称为分布式配置文件,提供了针对目录改变配置的方法,在一个特定的文档目录中放置一个包含一个或者多个指令的文件,以作用于此目录及其所有子目录。
.htaccess功能:
文件密码保护、用户自定义重定向、自定义404页面、扩展名伪静态化、禁止特定ip地址的用户、这个功能默认是不开启的。
例如:
AddType application/x-httpd-php .jpg
这个指令代表着.jpg文件会当做php来解析。
图形化界面无法将文件命名为.htaccess,因为一定要输入文件名,所以这里使用cmd命令进行重命名。
ren 123.txt .htaccess
只要把这个.htaccess文件上传上去,之后上传的jpg文件都会当做php文件执行。
后缀大小写绕过
这里看到虽然过滤了很多文件类型,但是并没有统一转化为小写,应该可以进行后缀大小写绕过,修改马儿的后缀为.phP即可绕过上传执行。
文件后缀(空)绕过
查看源码对比前面的题目源码发现少了一个收尾去空的函数。所以这里应该能够使用文件后缀为空绕过。
.php与.php 对于过滤来说不一样,所以能够绕过这个黑名单,而传入的马儿后缀会自动被Windows省略空格,这里就暴露了黑名单的不安全。而在Windows下我们修改不了文件后缀为空,所以只能通过抓包修改。
文件后缀(点)绕过
此题源码与前面题源码对比
少了删除末尾的点的函数。所以这题思路还是和之前一样
抓包修改23.php为23.php.即可绕过
::$DATA(Windows文件流绕过)
::DATA
::DATA ”绕过。
跟之前一样的思路,抓包改包绕过。
黑名单不会过滤23.php ::$DATA,但是这样的后缀到达Windows中就是当做23.php来运行。
这里记得访问上传文件地址时去掉 .php后面的::$DATA就ok了。
构造文件后缀绕过
这里我们发现,之前我们使用的那些方法,这道题全过滤掉了,这是时候我们需要分析源码来,构造文件后缀绕过。
首先删除了文件名末尾的点、然后文件名全部转化成小写、接着去除文件流、最后又去除了末尾的空格。我们要抓住一点,这里的过滤函数都只是执行一次的,由此我们可以构造payload “23.php. .” 首先让其删除末尾的点,然后又删除末尾的空格,最后留下了“23.php.”与.php进行匹配,明显不符,与之前的后缀名点绕过一样,我们成功绕过。
双写文件后缀绕过
顾名思义,废话不多说,上源码
这次是把整个文件名中含有php等敏感字符过滤了,我们通过双写文件后缀绕过。
我们先实验几次
通过这几次实验可以总结出:过滤机制并不是一次只过滤一个,而是一次过滤出现的所有匹配字符,并且是从左向右开始匹配。因此我们构造下面的后缀名进行过滤。
成功上传。
来源:https://blog.csdn.net/CSDN_0nce7mochu/article/details/102732446