1.长度检测:CONTENT-LENGTH验证

  1. if ($_FILES["fileToUpload"]["size"] > 30) {
  2. echo "Sorry, your file is too large.";
  3. }

绕过:计算限制大小,拆成小段代码上传
2.文件类型检测:客户端javascript 检测(通常为检测文件扩展名)
黑名单

  1. $postfix = end(explode('.','$_POST['filename']);
  2. if($postfix=='php'||$postfix=='asp'||$postfix=='sh'){
  3. echo "invalid file type";
  4. return;
  5. }

白名单

  1. $postfix = end(explode('.','$_POST['filename']);
  2. if($postfix=='jpg'||$postfix=='png'||$postfix=='gif'){
  3. //save the file and do something next
  4. } else {
  5. echo "invalid file type";
  6. return;
  7. }

黑名单绕过:
通过上传不受欢迎的php扩展来绕过黑名单。例如:pht,phpt,phtml,php3,php4,php5,php6
白名单绕过:
通过某种类型的技巧来绕过白名单,例如添加空字节注入(shell.php%00.gif),或使用双重扩展来上传文件(shell.jpg.php)。
此外,我们还可以尝试扩展名大小写来绕过,例如:pHp,Php,phP
白名单策略是更加安全的,通过限制上传类型为只有我们接受的类型,可以较好的保证安全,因为黑名单我们可以使用各种方法来进行注入和突破。
更多绕过技巧:

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

3.类型检测:服务端MIME 类型检测(检测Content-Type 内容)
content-Type:aplication/x-php
绕过:直接修改即可
4. 文件头检测:分析文件头内容来检查文件类型

  1. if (! exif_imagetype($_FILES['uploadedfile']['tmp_name'])) {
  2. echo "File is not an image";
  3. return;
  4. }

给上传脚本加上相应的幻数头字节如gif的:GIF89a
5.文件加载检测
一般是调用API 或函数去进行文件加载测试,常见的是图像渲染测试,再变态点的甚至是进行二次渲染(后面会提到)。
对渲染/加载测试的攻击方式是代码注入绕过;
对二次渲染的攻击方式是攻击文件加载器自身。
先说下对渲染/加载测试攻击-代码注入绕过,可以用图像处理软件对一张图片进行代码注入。用winhex看数据可以分析出这类工具的原理是在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般会是图片的注释区。对于渲染测试基本上都能绕过,毕竟本身的文件结构是完整的.

但如果碰到变态的二次渲染,基本上就没法绕过了,估计就只能对文件加载器进行攻击了。
一般进行遇到二次渲染,想绕过,它相当于是把原本属于图像数据的部分抓了出来,再用自己的API 或函数进行重新渲染,在这个过程中非图像数据的部分直接就被隔离开了。能想到的一个思路就是基于数据二义性,即让数据既是图像数据也包含一句话木马代码,就像shellcode 通过数据二义性绕过IDS 检测特殊字符一样的道理。
如果要对文件加载器进行攻击,常见的就是溢出攻击,上传自己的恶意文件后,服务器上的文件加载器会主动进行加载测试,加载测试时被溢出攻击执行shellcode比如access/mdb 溢出如果要对文件加载器进行攻击,常见的就是溢出攻击,上传自己的恶意文件后,服务器上的文件加载器会主动进行加载测试,加载测试时被溢出攻击执行shellcode比如access/mdb 溢出。
总之对文件完整性检测的绕过,通常就直接用个结构完整的文件进行代码注入即可没必要再去测到底是检查的幻数还是文件头结构之类的了。
6.解析攻击
攻击角度来分是这样的:
直接解析(完全没防御或有一点简单的防御)
比如我们直接就可以上传一个扩展名是.php的文件,只需要简单地绕过客户端javascript 检测或者服务端MIME 类型检测就行了。
配合解析(有一定程度的防御)
我们可以理解为先代码注入到服务器上,上传一个带有一句话木马的图片或文件之类
让它待在某个位置,等待这一个解析的配合。(比如php 的文件包含解析,web 服务器的解析漏洞,.htaccess 解析等)
本地文件包含解析
主要是php 的本地文件包含(远程文件包含不属于上传攻击绕过范畴)
htaccess解析
就不用多说了,看看之前.htaccess 文件攻击的那个案例,用户自己定义如何去调用解析器解析文件就可以了。
web应用程序解析漏洞以及其原理
Apache 解析漏洞
解析: test.php.任意不属于黑名单且也不属于Apache解析白名单的名称
描述: 一个文件名为x1.x2.x3 的文件,Apache 会从x3 的位置往x1 的位置开始尝试解析,
如果x3 不属于Apache 能解析的扩展名,那么Apache会尝试去解析x2 的位置,这样一直往前尝试,直到遇到一个能解析的扩展名为止
IIS 解析漏洞
解析- test.asp/任意文件名|test.asp;任意文件名| 任意文件名/任意文件名.php
描述- IIS6.0 在解析asp 格式的时候有两个解析漏洞,一个是如果目录名包含”.asp”字符串,那么这个目录下所有的文件都会按照asp 去解析,另一个是只要文件名中含有”.asp;”会优先按asp 来解析。
IIS7.0/7.5 是对php 解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL后面追加上字符串”/任意文件名.php”就会按照php 的方式去解析。
Nginx 解析漏洞
解析- 任意文件名/任意文件名.php | 任意文件名%00.php
描述- 目前Nginx 主要有这两种漏洞,一个是对任意文件名,在后面添加/任意文件名.php
的解析漏洞,比如原本文件名是test.jpg,可以添加为test.jpg/x.php进行解析攻击。还有一种是对低版本的Nginx 可以在任意文件名后面添加%00.php 进行解析攻击。
7.限制Web Server对于特定类型文件的行为
导致文件上传漏洞的根本原因在于服务把用户上传的本应是数据的内容当作了代码,一般来说,用户上传的内容都会被存储到特定的一个文件夹下,比如我们很多人习惯于放在 ./upload/ 下面要防止数据被当作代码执行,我们可以限制web server对于特定文件夹的行为。
大多数服务端软件都可以支持用户对于特定类型文件的行为的自定义,以Apache为例:
在默认情况下,对与 .php文件Apache会当作代码来执行,对于 html,css,js文件,则会直接由HTTP Response交给客户端程序对于一些资源文件,比如txt,doc,rar等等,则也会以文件下载的方式传送的客户端。我们希望用户上传的东西仅仅当作资源和数据而不能当作代码
因此可以使用服务器程序的接口来进行限制
以Apache为例,我们可以利用 .htaccess 文件机制来对web server行为进行限制
在这里插一句,如果不是专门的文件下载目录,请务必关掉文件夹浏览的权限,以防止嗅探和可能的越权,也是使用.htaccess文件,在其中加上一句

  1. Options All -Indexes

1.指定特定扩展名的文件的处理方式,原理是指定Response的Content-Type可以加上如下几行

  1. AddType text/plain .pl .py .php

这种情况下,以上几种脚本文件会被当作纯文本来显示出来,你也可以换成其他的Content-Type
2.如果要完全禁止特定扩展名的文件被访问,用下面的几行

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

在这种情况下,以上几种类型的文件被访问的时候,会返回403 Forbidden的错误
3.也可以强制web服务器对于特定文件类型的处理,与第一条不同的是, 下面的方法直接强行让apache将文件识别为你指定的类型,而第一种是让浏览器


ForceType text/plain

看代码就可以很明白的知道,符合上面正则的全部被认为是纯文本,也可以继续往里面加入其他类型。
4.只允许访问特定类型的文件

  1. <Files ^(*.jpeg|*.jpg|*.png|*.gif)>
  2. order deny,allow
  3. deny from all
  4. </Files>

在一个上传图片的文件夹下面,就可以加上这段代码,使得该文件夹里面只有图片扩展名的文件才可以被访问,其他类型都是拒绝访问。
这又是一个白名单的处理方案
永远记得,白名单是最有保障的安全措施

反制

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