文件上传总结

检测维度

javascript

检查没有流量产生,F12或者FireBug移除JS代码

MIME

MIME检测,burp拦截后更改MIME类型

if($_FILES['userfile']['type'] != "image/gif") { // check Content-type

目录路径

$sFilePath=evil.php%00.gif  !! php<5.3.4
move_uploaded_file( $oFile['tmp_name'], $sFilePath)

php版本5.3.4以下 and gpc关闭 CVE-2015-2348

1、上传时路径可控,使用 00 截断
2、文件下载时,00 截断绕过白名单检查
3、文件包含时,00 截断后面限制(主要是本地包含时)
4、其它与文件操作有关的地方都可能使用 00 截断。

扩展名检测

黑名单绕过(大小写(win),asa/cer/cdx(IIS6)/php345/inc/phtml/phps/phpt,win server命名. _ 空格,asp0x00截断,.htaccess, .user.ini(见下文))

  • php
    由于历史原因,部分解释器可能支持符合正则 /ph(p[2-7]?|t(ml)?)/ 的后缀,如 php / php5 / pht / phtml / shtml / pwml / phtm 等 可在禁止上传php文件时测试该类型。

  • jsp
    引擎则可能会解析 jspx / jspf / jspa / jsw / jsv / jtml 等后缀,asp支持 asa / asax / cer / cdx / aspx / ascx / ashx / asmx / asp{80-90} 等后缀。

  • 其他
    同样可能带来问题,如 vbs / asis / sh / reg / cgi / exe / dll / com / bat / pl / cfc / cfm / ini 等。

  • 系统特性

    1. 在Windows系统中,上传index.php.会重命名为.,可以绕过后缀检查。 也可尝试 index.php空格index.php:1.jpgindex.php::$DATA 等。
      以及 windows 通配符:大于号(>)相等于通配符问号(?),小于号(<)相当于通配符星号(*),双引号(“)相当于点字符(.)
    1. 在Linux系统中,可以尝试上传名为 index.php/../aa/../index.php/. 的文件

白名单(asp 0x00,解析漏洞,文件包含,NTFS ADS特性)

  • .htacess
    一般来说,配置文件的作用范围都是全局的,但 Apache 提供了一种很方便的、可作用于当前目录及其子目录的配置文件—— .htaccess(分布式配置文件)
.htaccess
    <FilesMatch "filename">
    SetHandler application/x-httpd-php
    </FilesMatch>

要想使 .htaccess 文件生效,需要两个条件:
一是在 Apache 的配置文件中写上:
AllowOverride All
若这样写则 .htaccess 不会生效:
AllowOverride None
二是 Apache 要加载 mod_Rewrite 模块。加载该模块,需要在 Apache 的配置文件中写上:
LoadModule rewrite_module/usr/lib/apache2/modules/mod_rewrite.so
若是在 Ubuntu 中,可能还需要执行命令:
sudo a2enmod rewrite
配置完后需要重启 Apache。

文件内容检测

1.文件幻数检测:
JPEG:FF D8 FF E0 00 10 4A 46 49 46
PNG:89 50 4E 47
GIF:47 49 46 38 39 61
PHP:<?php>、 <?、 <%、<?= 、<script language="php">phpinfo();</script>
PHP tag
<? short_open_tag 決定是否可使用短标签或是编译php时 --enable-short-tags
<%自PHP 7.0.0起,被移除,需要asp_tags设成On
<script language="php"></script>自PHP 7.0.0起,被移除
<?=等价 <?php echo自PHP 5.4.0起,可用!

2.文件相关信息检测:添加文件信息
3.文件加载检测:二次渲染,考虑攻击加载器/绕过二次渲染

解析漏洞

apache

  • (2.0-2.2 可能影响版本)一个文件名为 x1.x2.x3 的文件,Apache 会从 x3 的位置往 x1 的位置开始尝试解析如果 x3 不属于 Apache 能解析的扩展名,那么 Apache 会尝试去解析 x2 的位置,这样一直往前尝试,直到遇到一个能解析的扩展名为止.
  • 修复方案
    后缀验证尽量使用白名单的方式,这样即使使用不存在的后缀名,也无法绕过。
  • 配置问题导致漏洞
    1、如果在 Apache 的 conf 里有这样一行配置 AddHandler php5-script .php 这时只要文件名里包含 .php 即使文件名是 test2.php.jpg 也会以 php 来执行。
    2、如果在 Apache 的 conf 里有这样一行配置 AddType application/x-httpd-php .jpg即使扩展名是 jpg,一样能以 php 方式执行。
  • 修复方案
  1. apache 配置文件,禁止 .php. 这样的文件执行,配置文件里面加入
    <Files~“.(php.|php3.)”>
          Order Allow,Deny
          Deny from all
    </Files>
    
  2. 用伪静态能解决这个问题,重写类似.php.*这类文件,打开 apache 的 httpd.conf 找到
    LoadModule rewrite_module modules/mod_rewrite.so
    把 # 号去掉,重启 apache, 在网站根目录下建立 .htaccess 文件,代码如下:
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule .(php.|php3.) /index.php
    RewriteRule .(pHp.|pHp3.) /index.php
    RewriteRule .(phP.|phP3.) /index.php
    RewriteRule .(Php.|Php3.) /index.php
    RewriteRule .(PHp.|PHp3.) /index.php
    RewriteRule .(PhP.|PhP3.) /index.php
    RewriteRule .(pHP.|pHP3.) /index.php
    RewriteRule .(PHP.|PHP3.) /index.php
    </IfModule>
    
  • 2.4.0-2.4.29 %0a绕过扩展名检测。只要用正则来匹配后缀进行php解析的Apache就有这个问题。而这个做法刚好是为了解决Apache老的解析漏洞而做的,可谓非此即彼,必然存在一种解析漏洞。详见P牛博文

IIS

  • IIS6.0 在解析 asp 格式的时候有两个解析漏洞,一个是如果目录名包含 ".asp" 字符串 ,那么这个目录下所有的文件都会按照 asp 去解析,另一个是只要文件名中含有 ".asp;jpg",服务器默认不解析;号后面的内容,因此 xx.asp;.jpg 便被解析成 asp 文件了,会优先按 asp 来解析
  • IIS7.0/7.5是对 php 解析时有一个类似于Nginx 的解析漏洞,对任意文件名只要在 URL后面追加上字符串 "/ 任意文件名 .php" 就会按照 php 的方式去解析 (IIS6.0 没测试 )

Nginx

  • 一个是对任意文件名,在后面添加/任意文件名.php的解析漏洞,比如原本文件名是 test.jpg,可以添加为 test.jpg/x.php 进行解析攻击。(php-cgi php<~5.3.9)
  • php-cgi

Is the PHP option 'cgi.fix_pathinfo' really dangerous with Nginx + PHP-FPM?

  • 修复方案
    上传目录、静态资源(CSS/JS/图片等)目录,都设置好屏蔽 PHP 执行权限;
    图片与源站分离;
    图片进行处理。
  • (0.5.,0.6, 0.7 <= 0.7.65, 0.8 <= 0.8.37)还有一种是对低版本的 Nginx 可以在任意文件名后面添加 %00.php 进行解析攻击。

其他

软链接任意读文件

上传的压缩包文件会被解压的文件时,可以考虑上传含符号链接的文件 若服务器没有做好防护,可实现任意文件读取的效果。

ln -s index.php text.txt
tar cvf test.tar text.txt

文件名 fuzz 字典

上传漏洞跟那些因素有关:

  1. 可解析的后缀,也就是该语言有多个可解析的后缀,比如php语言可解析的后缀为php,php2,php3等等
  2. 大小写混合,如果系统过滤不严,可能大小写可以绕过。
  3. 中间件,每款中间件基本都解析漏洞,比如iis就可以把xxx.asp;.jpg当asp来执行。
  4. 系统特性,特别是Windows的后缀加点(.),加空格,加::$DATA可以绕过目标系统。
  5. 语言漏洞,流行的三种脚本语言基本都存在00截断漏洞。
  6. 双后缀,这个与系统和中间件无关,偶尔会存在于代码逻辑之中。

https://www.freebuf.com/articles/web/188464.html

.user.ini 配置文件

此类文件仅被 CGI/FastCGI SAPI 处理。在php执行的过程中,除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。

如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。 .user.ini 中可以定义除了PHP_INI_SYSTEM以外的模式的选项,故可以使用 .user.ini 加上非php后缀的文件构造一个shell,比如 auto_prepend_file=01.gif
https://www.php.net/manual/zh/configuration.file.per-user.php

竞争上传绕过

有的服务器采用了先保存,再删除不合法文件的方式,在这种服务器中,可以反复上传一个会生成Web Shell的文件并尝试访问,多次之后即可获得Shell。

reference
1.《Upload Attack Framework》 v1.0 CasperKid [Syclover][Insight-Labs]
2.XMAN 2017 Web
3.利用最新Apache解析漏洞(CVE-2017-15715)绕过上传黑名单
4.信安之路
5.Web安全学习笔记-文件上传
xmsec

Updated At: Author:xmsec
Chief Water dispenser Manager, delivering but striving.
Github
comments powered by Disqus