计算机系统应用教程网站

网站首页 > 技术文章 正文

文件上传漏洞

btikc 2024-09-10 11:59:21 技术文章 54 ℃ 0 评论

1、概念


文件上传漏洞是指由于程序员未对上传的文件进行严格的验证和过滤,而导致用户可以越过其本身权限向服务器上传可执行的动态脚本文件。


如常见的头像上传,图片上传,oa 办公文件上传,媒体上传,允许用户上传文件,如果过滤不严格,恶意用户利用文件上传漏洞,上传有害的可以执行脚本文件到服务器中,可以获取服务器的权限,或进一步危害服务器。


2、文件上传形成的原因


一方面,Web 应用开放了文件上传功能,并且对上传的文件没有进行足够的限制;


另一方面,程序开发部署时候,没有考虑到系统特性和过滤不严格;再者就是,攻击者通过Web服务器解析漏洞绕过限制,导致可以上传任意文件。


3、危害


非法用户可以上传的恶意文件控制整个网站,甚至是控制服务器,这个恶意脚本文件,又被称为 webshell,上传 webshell 后门很方便地查看服务器信息,查看目录,执行系统命令等。


php一句话木马<?php @eval($_POST['x']);?>


4、防御方法


1)前端校验


前端页面在提交上传文件时,增加文件类型的校验,如果不是指定的文件类型,就拒绝提交。


这种方式只能算是防止正常用户的误操作,完全不能阻止有心的黑客上传危害性的脚本,编辑一下页面JS,或者使用BP工具就能绕过了。虽然没有大用处,但也不可或缺。


2) 后端检查文件扩展名


在文件被上传到后端服务器的时候,先对文件的扩展名进行校验:


  • 黑名单法凡是在黑名单中的文件扩展名均不允许被上传,直接返回给前端错误信息;
  • 白名单法限制只有白名单中的文件扩展名才会被服务器接受;


如果我们使用的是白名单规则,即只允许上传文件后缀为jpg、png、gif的文件,那么如上的情况就可以避免,而且可以阻止其它我们暂时没有想到的绕过规则。


通常情况下,如果白名单能满足需求,就尽量使用白名单,因为白名单更加的安全,而黑名单容易被意想不到的方法进行绕过。


比如,我们黑名单规则为,凡是上传文件后缀为php、asp、jsp的都会被过滤,那么针对以下情况就会被绕过:


老版本的IIS服务器存在分号漏洞,即服务器会在解析上传文件的文件名时会把分号后面的内容丢弃,那么黑客构造一个文件名为danger.asp;jpg的危险脚本,就能绕过黑名单校验规则,且能被服务器解析为asp脚本,当访问该脚本的时候,就会执行文件的脚本程序; 老版本的windows-server存在点号和空格漏洞,即会将文件名最后的点号或者空格自动丢弃,那么黑客构造一个文件名为danger.asp.或者danger.asp(此处有空格)的文件脚本,就能绕过黑名单校验规则,且能被服务器解析为asp脚本,当访问该脚本的时候,就会执行文件的脚本程序; 老版本的Nginx存在%00截断漏洞,即对文件名中%00之后的内容进行截断,比如黑客构造一个文件名为danger.php%00.jpg的危险脚本,当上传成功后,服务器在解析该文件的时候,会截断%00之后的内容,把文件当成danger.php进行执行; 老版本的apache服务器解析漏洞,即服务器在解析文件名的时候从右往左,遇到识别不了的后缀会自动跳过,读取可以识别的后缀,如果黑客构造一个文件名为danger.asp.rar或者danger.asp.gif的危险脚本,就能绕过黑名单校验规则,且能被服务器解析为asp脚本,当访问该脚本的时候,就会执行文件的脚本程序;


3) 后端检查Content-Type


HTTP协议规定了上传资源的时候会在请求头Header中添加一项MIMETYPE,即Content-Type,用来标识上传资源内容的类型,这个动作一般由浏览器来完成,常见的MIMETYPE类型如下:


  • text/plain,纯文本
  • text/html,HTML文档
  • text/javascript,JS代码
  • application/x-www-urlencoded,POST方法提交的表单
  • application/msword,MicrosoftWord文件
  • application/变成语言,该种编程语言的代码
  • application/pdf,PDF文档
  • application/octet-stream,二进制数据
  • application/xhtml+xml,XHTML文档
  • image/gif+jpeg+png,各种类型的图片
  • vedio/mpeg,动画
  • multipart/form-data,POST提交时伴随文件上传的表单


后端在处理上传请求的时候,可以获取header种的Content-Type类型,来判断上传的文件是否符合要求。当然这种方式也很容易被绕过,使用BP工具,拦截浏览器请求,修改Content-Type类型就行了,虽然这种方法不保险,但是加上一层防护也还是必要的。


4) 后端检查文件头内容


每一种特定类型的文件都会有自己固定的文件头,通常是用十六进制表示。


  • JPG对应FF D8 FF E0 00
  • GIF对应47 49 46 38 39 61
  • PNG对应89 50 4E 47
  • ZIP对应50 4B 03 04
  • RAR对应52 61 72 21
  • DOC/XLS/PPT对应D0 CF 11 E0 A1 B1 1A E1


后端可以检查文件头的前几位字节,就可以判断是否为合法的文件类型,但是这种方式也不是完全保险的,并不能替代检查文件后缀的方式,因为黑客完全可以构造一个脚本文件,其文件头伪装成正常的上传文件类型。


5)控制服务器对指定目录的行为


服务器对恶意脚本的执行是造成漏洞生效的直接原因。


我们一般会把用户上传的文件放在一个固定的目录,比如/upload下面,按照预想计划,当用户访问这个文件夹下面的文件时,应该发起下载逻辑,而不是把文件当成脚本去执行。因为,我们可以设置服务器对特定目录的行为来有效避免漏洞的发生。


6)上传文件重命名


服务器对恶意脚本的执行是造成漏洞生效的直接原因。


所以我们还可以通过让黑客无法找到他上传的恶意脚本来避免这个问题。当文件上传到服务器之后,服务器可以对文件进行随机重命名,然后再保存到上传目录中。


7)隐藏上传文件路径


服务器对恶意脚本的执行是造成漏洞生效的直接原因。


所以,我们需要将文件上传的路径隐藏起来,使其不能被用户直接访问到。比如,我们将文件上传路径放在非项目内,或者放在别的服务器上。当用户上传文件的时候,通过程序将文件传输到对应的目录;当需要读取该文件的时候,也由程序以文件流的方式去对应的目录加载,如此,用户根本无法直接访问到上传的文件,更不能使其执行。


5、绕过方式


(1)、关闭浏览器JS功能


///Chrome浏览器:在浏览器地址栏输入Chrome://settings/content/javascript;


或设置–>高级–>隐私设置与安全性–>内容设置–>javascript


///火狐浏览器:在地址栏输入about:config 然后搜索javascript.enabled,双击


编辑


(2)、中间人攻击


在使用浏览器上传的时候,使用burp拦截抓包,通过更改文件后缀名形式达到绕过JS验证的效果,从而成功上传文件。


如我们向某网站上传webshell为PHP语言,原文件名为shell.php。前端JS校验只允许上传jsp或png格式的文件,我们可以将我们的webshell后缀名改为.jpg,并开启burp拦截,点击上传,从burp抓到的请求包中将文件后缀名修改为.php,选择放包则上传成功。


(3)、MIME-Type验证


1)MIME Typr常见分类


?编辑


2)MIME TYPE验证


MIME类型服务端检测,检查http包的Content-Type字段中的值,判断上传文件是否合法,验证成功。


<?php
	if ($_FILES['userfile']['type'] !="image/gif") {
	......
?>



3)绕过MIME-Type验证


上传PHP文件,使用burpsuite拦截查看MIME类型(Content-Type类型),发现PHP文件的MIME类型为application/octet-stream,服务端判断文件类型是否为image/gif(允许上传gif格式的文件)


无法通过MIME类型验证,需要将Content-Type改为image/gif


4)Type绕过防御机制


目录设为不可执行----只要web容器无法解析该目录下的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,因此此点至关重要。


判断文件类型----判断文件类型时,应结合MIME-Type、后缀检查等方式。推荐使用白名单的方式。


用随机数改写----文件上传如果要执行代码,则需要用户能访问到这个文件。在某些环境下,用户能上传,但是不能访问。


(4)、文件扩展名绕过




?编辑


2)检查方式


黑名单----黑名单检测是一种不安全的方式,黑名单定义了一系列不安全的扩展名,服务器端一般有个专门的blacklist文件,里面会包含常见的危险脚本文件类型,在接收文件后,与黑名单扩展名对比,如果发现文件扩展名与黑名单存储的扩展名匹配,则认为文件不和发。


白名单----白名单检测方式与黑名单恰恰相反,黑名单是定义不允许上传的文件扩展名,而白名单则定义允许上传的文件扩展名,白名单拥有比黑名单更好的防御机制。


3)黑名单检测


定义blacklist检查文件扩展名,判断上传文件是否合法,过滤危险脚本。


 <?php
 $Blacklist = array('asp','php','jsp','php5','asa','aspx');
 ......
 ?>



4)白名单检测


在获取到文件扩展名后对$WhiteList数组里的扩展名迭代判断,如果文件扩展名被命中,程序将认为文件是合法的,否则不允许上传


<?php
$WhiteList = array('rar','jpg','png','bmp','gif',jpeg','doc');
......
?>



(5)、黑名单绕过


忽略的扩展名----攻击者可以从黑名单找到web开发人员忽略的扩展名,如cer、phtml等。


大小写转换----所示代码中并没有对接收到的文件扩展名进行大小写转换操作,那就意味着可以上传AsP、PhP之类的文件名绕过黑名单检测,而此类扩展名在windows平台依然会被web容器解析。


windows特性----在windows系统下,如果文件名以“.”或者空格作为结尾,系统会自动去除“.”与空格,利用测特征也可以绕过黑名单验证。如上传“asp.”或者“asp ”扩展名程序,服务器接收文件名后在写文件操作时,windows将会自动去除小数点和空格。


双写后缀----双写后缀名绕过,用于只将文件后缀名,例如:上传时将Burpsuite截获的数据包中文件名【xxx.php】改为【xxx.phphpp】,那么开头的ph和结尾的p就结合又形成了【php】。


(6)、白名单绕过


IIS----IIS6.0攻击者把木马文件名改为xxx.php;1.jpg上传,此时文件格式为JPG格式,从而顺利通过验证,而IIS6.0会把xxx.php;1.jpg当做ASP脚本执行,最终攻击者可以绕过白名单检测,并执行木马程序。


Apache----在Apache1.x 2.x中,对文件名的解析是从后行前解析的,直到遇到一个Apache认识的文件类型为止。如:phpshell.php.rar.rar.rar,因为Apache不认识.rar这个文件类型,所以会一直遍历所有后缀到.php,然后认为这是一个php类型的文件从而绕过白名单。


(7).user.ini、.htaccess、二次渲染绕过


.user.ini绕过


需要有指向文件index.php,里面有没有内容不重要


需要php 7版本


文件包含配置项有auto_pretend_file


a.先上传这个user.ini文件,发现上传成功。


b.然后本来不能上传规定外的文件,现在就可以上传了


c.这个x.txt里面就是一句话木马


<?php @eval($_POST[x]);?>


d.这个x.txt木马就被自动包含进原来目录里的php文件了(一般是index.php)


如果会过滤,那就想办法绕过,先一个一个试过滤的是什么东西,然后针对这个来绕过。
二次渲染绕过


1)配合条件竞争漏洞


竞争条件是指多个线程在没有进行锁操作或者同步操作的情况下同时访问同一个共享代码,变量,文件等,运行的结果依赖于不同线程访问数据的顺序。


2)配合文件包含漏洞


将一句话木马插入到网站二次处理后的图片中,也就是将二次渲染后保留的图片和一句话木马制作成图片马,再配合文件包含漏洞解析图片马中的代码,获取webshell。

?

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表