文件上传漏洞

参考文章:https://blog.csdn.net/qq_43390703/article/details/104858705

什么是文件上传漏洞?

攻击者上传可执行的动态脚本文件,可以是木马,病毒,恶意脚本或者WebShell等。

什么是webshell?
WebShell就是以aspphpjsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称之为一种网页后门。攻击者在入侵了一个网站后,通常会将这些asp或php后门文件与网站服务器web目录下正常的网页文件混在一起,然后使用浏览器来访问这些后门,得到一个命令执行环境,以达到控制网站服务器的目的(可以上传下载或者修改文件,操作数据库,执行任意命令等)。 WebShell后门隐蔽较性高,可以轻松穿越防火墙,访问WebShell时不会留下系统日志,只会在网站的web日志中留下一些数据提交记录。

产生原因

  • 对上传文件的后缀名没有做较为严格的限制
  • 对上传文件的MIMETYPE没有做检查
  • 权限上没有对于上传的文件目录设置不可执行权限
  • 对于web server对于上传文件或者指定目录的行为没有做限制

原理

WEB中上传文件,服务器读取这个分段(multipart)提取并保存,通常,在进行文件保存的时候,服务器端会读取文件的原始文件名,并从这个原始文件名中得出文件的扩展名,而后随机为文件起一个文件名 ( 为了防止重复 ),并且加上原始文件的扩展名来保存到服务器上

利用

  1. 上传web脚本语言,服务器执行恶意代码
  2. 上传flash的策略文件crossdomain.xml,攻击者控制在该域的行为
  3. 上传病毒木马,诱导用户下载执行
  4. 上传钓鱼图片
  5. 上传php脚本,文件包含执行

防范与绕过

1.前端过滤

原理

在表单中使用onsumbit=checkFile()调用js函数来检查上传文件的扩展名。当用户在客户端选择文件点击上传的时候,客户端还没有向服务器发送任何消息,就对本地文件进行检测来判断是否是可以上传的类型,这种方式称为前台脚本检测扩展名。

绕过方法:

上传一句话木马,改名jpg格式,bp抓包改回php

1
2
3
<?php
@eval($_POST['cmd']);
?>

2.检查扩展名

在服务器进行检查,过滤掉不合法的扩展名文件,有白名单和黑名单

绕过方法:在一些Web server中,存在解析漏洞:
1.老版本的IIS6中的目录解析漏洞,如果网站目录中有一个 /.asp/目录,那么此目录下面的一切内容都会被当作asp脚本来解析
2.老版本的IIS6中的分号漏洞:IIS在解析文件名的时候可能将分号后面的内容丢弃,那么我们可以在上传的时候给后面加入分号内容来避免黑名单过滤,如 a.asp;jpg
3.旧版Windows Server中存在空格和dot漏洞类似于 a.php. 和 a.php[空格] 这样的文件名存储后会被windows去掉点和空格,从而使得加上这两个东西可以突破过滤,成功上传,并且被当作php代码来执行
4.nginx(0.5.x, 0.6.x, 0.7 <= 0.7.65, 0.8 <= 0.8.37**)空字节漏洞 xxx.jpg%00.php** 这样的文件名会被解析为php代码运行(fastcgi会把这个文件当php看,不受空字节影响,但是检查文件后缀的那个功能会把空字节后面的东西抛弃,所以识别为jpg)
5.apache1.x,2.x的解析漏洞,上传如a.php.rar a.php.gif 类型的文件名,可以避免对于php文件的过滤机制,但是由于apache在解析文件名的时候是从右向左读,如果遇到不能识别的扩展名则跳过,rar等扩展名是apache不能识别的,因此就会直接将类型识别为php,从而达到了注入php代码的目的

检查Content-Type

原理

HTTP协议规定了上传资源的时候在Header中加上一项文件的MIMETYPE,来识别文件类型,这个动作是由浏览器完成的,服务端可以检查此类型不过这仍然是不安全的,因为HTTP header可以被发出者或者中间人任意的修改。

绕过方法

使用各种各样的工具(如burpsuite)强行篡改Header就可以,将Content-Type: application/php改为其他web程序允许的类型。

3.文件头检查文件

原理

利用的是每一个特定类型的文件都会有不太一样的开头或者标志位。

例如:TIFF (tif) 49492A00

绕过方法

给上传脚本加上相应的幻数头字节就可以,php引擎会将 <?之前的内容当作html文本,不解释而跳过之,后面的代码仍然能够得到执行比如下面:
(一般不限制图片文件格式的时候使用GIF的头比较方便(47494638),因为全都是文本可打印字符。)

4.限制Web Server对特定类型文件的行为

原理

导致文件上传漏洞的根本原因在于服务把用户上传的本应是数据的内容当作了代码,一般而言:用户上传的内容都会被存储到特定的一个文件夹下,比如我们很多人习惯于放在 ./upload/ 下面要防止数据被当作代码执行,我们可以限制web server对于特定文件夹的行为。(在Response的Content-type修改)

  1. 指定特定文件名的处理方式(纯文本) AddType text/plain .pl .py .php

  2. 完全禁止特定扩展名的文件被访问(黑名单)

    1
    2
    3
    4
    5
       Options -ExecCGI
    AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi识别

    3. 强制web服务器对于特定文件类型的处理,**与第一条不同的是, 下面的方法直接强行让apache将文件识别为你指定的类型,而第一种是让浏览器符合上面正则的全部被认为是纯文本,也可以继续往里面加入其他类型。**

    <FilesMatch “.(php|pl|py|jsp|asp|htm|shtml|sh|cgi)$”>
    ForceType text/plain

    ```
  3. 只允许访问特定类型文件(白名单)

绕过方法

可以通过 move_uploaded_file 函数把自己写的.htaccess 文件上传,覆盖掉服务器上的文件,来定义文件类型和执行权限如果做到了这一点,将获得相当大的权限。

补充知识htaccess:

.htaccess文件(或者”分布式配置文件”),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法, 即,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以通过Apache的AllowOverride指令来设置。概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

5,。文件系统00阻断

原理

在上传的时候,当文件系统读到【0x00】时,会认为文件已经结束。利用00截断就是利用程序员在写程序时对文件的上传路径过滤不严格,产生0x00、%00上传截断漏洞。

绕过方法

通过抓包截断将【evil.php.jpg】后面的一个【.】换成【0x00】。在上传的时候,当文件系统读到【0x00】时,会认为文件已经结束,从而将【evil.php.jpg】的内容写入到【evil.php】中,从而达到攻击的目的。

6.NTFS文件系统特性绕过

NTFS交换数据流(alternate data streams简称ADS)是NTFS磁盘格式的新特性,见漏洞详细可查CVE-1999-0278。

一个完整的流的格式为:::
文件主流即我们平时可以看见的可以存储数据的文件。而非主文件流寄宿于主文件流中,无法直接读取。
修改宿主文件的内容或流的内容,不会对彼此造成影响。
流类型总是以符 号 作 为 开 始 ,NTFS文 件 系 统 中 的 文 件 至 少 包 含 一 个 主 流 , 也 就 是data流 ( 符号作为开始,NTFS文件系统中的文件至少包含一个主流,也就是data流(符号作为开始,NTFS文件系统中的文件至少包含一个主流,也就是data流(DATA),默认流名为空。
ADS可以省略流名,但不能省略流类型。
NTFS文件系统中的文件夹没有data流,但可以指派data流,文件夹的主流为directory流 , 流 名 默 认 为 l30
当我们对一个在NTFS分区中的ASP文件发出包含D A T A 请 求 , I I S 会 检 查 最 后 一 个 “ . ” 后 面 的 扩 展 名 , 因 为 多 了 : : DATA请求,IIS会检查最后一个“.”后面的扩展名,因为多了::DATA请求,IIS会检查最后一个“.”后面的扩展名,因为多了::DATA,结果IIS不认为这是一个ASP文件,而文件系统可以识别该请求,于是返回ASP的源代码。

绕过方法

看不懂先跳了

7.二次渲染绕过

图片的二次渲染形成代码

8.条件竞争

原理

与服务端频繁交互导致处理顺序出错

9.其他漏洞

  1. 后缀名大小写绕过 用于只将小写的脚本后缀名(如php)过滤掉的场合; 例如:将Burpsuite截获的数据包中的文件名【evil.php】改为【evil.Php】
  2. 双写后缀名绕过 用于只将文件后缀名过滤掉的场合,例如”php”字符串过滤的; 例如:上传时将Burpsuite截获的数据包中文件名【evil.php】改为【evil.pphphp】,那么过滤了第一个”php”字符串”后,开头的’p’和结尾的’hp’就组合又形成了【php】。
  3. 特殊后缀名绕过 用于检测文件合法性的脚本有问题的场合; 例如:将Burpsuite截获的数据包中【evil.php】名字改为【evil.php6】,或加个空格改为【evil.php 】等。