发布于2022年11月4日2年前 Tomcat PUT方法任意写文件漏洞复现(CVE-2017-12615) 版本信息Tomcat测验版本:7.0.79漏洞影响悉数的 Tomcat 版本:Apache Tomcat 7.0.0 - 7.0.79 (windows环境)漏洞剖析在tomcat官网下载一个Tomcat7的源码压缩包,打开来慢慢看看里边的.xml文件与java代码。关键装备装备文件途径apache-tomcat-7.0.10-src\conf\web.xmlDefaultServlet类处理除了JSP文件以外的静态资源 readonly默认为true,在(CVE-2017-12615)的状况下为false。 servlet-name:default对应的是servlet-class:DefaultServletdefaultorg.apache.catalina.servlets.DefaultServletdebug0listingsfalsereadonlyfalse1JspServlet类负责JSP文件的汇编与运转 servlet-name:jsp对应的是servlet-class:JspServletjsporg.apache.jasper.servlet.JspServletforkfalsexpoweredByfalse3servlet-mapping主要是截获恳求的:假如url-pattern界说的是途径,那么以后一切对这个途径下资源的恳求都会由servlet-name中界说的servlet处理;假如你的url-pattern界说的是资源格局例如*.jsp等,那么对于一切符合这种格局的资源的恳求都由指定的servlet处理。这儿说明了/类型的资源都由servlet-name:default处理,*.jsp与*.jspx类型的资源都由servlet-name:jsp处理 default/jsp*.jspjsp*.jspx代码剖析DefaultServlet.java文件途径apache-tomcat-7.0.10-src\\java\\org.apache\\catalina\\servlets\\DefaultServlet.java受影响的doPut函数/** * Process a PUT request for the specified resource. * * @param req The servlet request we are processing * @param resp The servlet response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet-specified error occurs */ @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if (readOnly) { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } String path = getRelativePath(req); boolean exists = true; try { resources.lookup(path); } catch (NamingException e) { exists = false; } boolean result = true; // Temp. content file used to support partial PUT File contentFile = null; Range range = parseContentRange(req, resp); InputStream resourceInputStream = null; // Append data specified in ranges to existing content for this // resource - create a temp. file on the local filesystem to // perform this operation // Assume just one range is specified for now if (range != null) { contentFile = executePartialPut(req, range, path); resourceInputStream = new FileInputStream(contentFile); } else { resourceInputStream = req.getInputStream(); } try { Resource newResource = new Resource(resourceInputStream); // FIXME: Add attributes if (exists) { resources.rebind(path, newResource); } else { resources.bind(path, newResource); } } catch(NamingException e) { result = false; } if (result) { if (exists) { resp.setStatus(HttpServletResponse.SC_NO_CONTENT); } else { resp.setStatus(HttpServletResponse.SC_CREATED); } } else { resp.sendError(HttpServletResponse.SC_CONFLICT); } }动态调试进入doPut函数,上传的文件名为12w3.jsp/,能够看到readOnly==false因为12w3.jsp/不存在服务器中,所以调用bind函数进行写入。进入resources.bind函数进入dirContext.bind函数进入bind函数传入的name参数为/12w3.jsp/,在File函数中会将name中的/去除,进入File函数进行检查child==/12w3.jsp/,由fs.normalize函数处理,进入fs.normalize函数normalize(path)函数中调用normalize(path, len, off)函数对/进行处理,进入normalize(path, len, off)函数normalize(path, len, off)函数对path处理完后,返回\12w3.jsp从File函数中出来,把name==/12w3.jsp/传进rebind函数,进入rebind函数在rebind函数中调用File函数获得完整途径F:\\Tomcat\\apache-tomcat-7.0.79\\webapps\\ROOT\\12w3.jsp将文件内容写入F:\\Tomcat\\apache-tomcat-7.0.79\\webapps\\ROOT\\12w3.jsp文件上传完结。漏洞使用访问Tomcat主页,抓包右击,挑选send to repeater修正红框中的内容:将GET恳求改为PUT增加文件名backdoor.jsp/(注意后面要增加/)增加文件内容点击send发送。检查response,文件创建成功。检查Tomcat根目录,多了一个backdoor.jsp,上传成功。
创建帐户或登录后发表意见