文件上传总结

检测维度

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 截断。

扩展名检测

黑名单绕过(大小写,asa/cer/cdx(IIS6)/php345/inc/phtml/phps/phpt,win server命名. _ 空格,asp0x00截断,.htaccess, user.ini(针对php-fastcgi))
可以配合操作系统文件命名规则,上传不符合 windows 文件命名规则的文件名会被 windows 系统自动去掉不符合规则符号后面的内,然后再配合这个解析漏洞来执行文件。

test.php.
test.php(空格)
test.php:1.jpg
test.php::$DATA
//关于通配符
大于号(>)相等于通配符问号(?)
小于号(<)相当于通配符星号(*)
双引号(“)相当于点字符(.)


白名单(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.文件加载检测:二次渲染,考虑攻击加载器/绕过PHP图片转换实现RCE SCTF 2016 homework

解析漏洞

apapche

  • (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 进行解析攻击。

reference
1.《Upload Attack Framework》 v1.0 CasperKid [Syclover][Insight-Labs]
2.XMAN 2017 Web
3.PHITHON BLOG
4.信安之路
xmsec

作者:xmsec
Chief Water dispenser Manager, delivering but striving.
GitHub