目录

  1. 1. 前言
  2. 2. Tomcat PUT方法任意写文件漏洞(CVE-2017-12615)
  3. 3. Tomcat URL解析差异性导致的安全问题
    1. 3.1. HTTPServletRequest对URL的解析差异性
    2. 3.2. 特殊字符的URL解析
      1. 3.2.1. 正常访问
      2. 3.2.2. 插入 ./ 访问
      3. 3.2.3. 插入 ../ 访问
      4. 3.2.4. 插入 ;/ 访问
    3. 3.3. 调试
    4. 3.4. 攻击利用

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

Tomcat漏洞总结

2024/7/23 Web Java CVE
  |     |   总文章阅读量:

前言

参考:

https://xz.aliyun.com/t/10083

https://xz.aliyun.com/t/7544


Tomcat PUT方法任意写文件漏洞(CVE-2017-12615)

复现环境:https://github.com/vulhub/vulhub/blob/master/tomcat/CVE-2017-12615/

版本限制:不确定,貌似是一个配置漏洞

漏洞成因:

/usr/local/tomcat/conf/web.xml

<init-param><param-name>readonly</param-name><param-value>false</param-value></init-param>

readonly设置为false,此时我们就可以使用 PUT 方法进行文件上传

image-20240726115438187

返回201,说明成功上传

看一下 /usr/local/tomcat/webapps/ROOT 目录

image-20240726115527994

可以看到刚才上传的test.txt文件

接下来尝试上传.jsp,返回404,应该是当成路径访问进行解析了

image-20240726115822467

这里就需要进行绕过,有三种方法:

  1. Windows下不允许文件以空格结尾:以PUT /a001.jsp%20 HTTP/1.1上传到 Windows 会被自动去掉末尾空格
  2. Windows NTFS流:PUT /a001.jsp::$DATA HTTP/1.1\
  3. /在文件名中是非法的,也会被去除(Linux/Windows):PUT /a001.jsp/ HTTP/1.1

这里只演示第三种:

image-20240726120126859

成功上传,然后蚁剑getshell即可


Tomcat URL解析差异性导致的安全问题

后台使用getRequestURI()getRequestURL()函数来解析用户请求的URL时,若URL中包含了一些特殊符号,则可能会造成访问限制绕过的安全风险

HTTPServletRequest对URL的解析差异性

在Servlet处理URL请求的路径时,HTTPServletRequest有如下几个常用的函数:

  • request.getRequestURL():返回全路径;
  • request.getRequestURI():返回除去Host(域名或IP)部分的路径;
  • request.getContextPath():返回工程名部分,如果工程映射为/,则返回为空;
  • request.getServletPath():返回除去Host和工程名部分的路径;
  • request.getPathInfo():仅返回传递到Servlet的路径,如果没有传递额外的路径信息,则此返回Null;

设Servlet的匹配路径为/test%3F/*,并且Web应用是部署在/app

此时请求的URL为http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=s%3F+ID?p+1=c+d&p+2=e+f#a,则各个函数解析如下表:

函数 URL解码 解析结构
getRequestURL() no http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=s%3F+ID
getRequestURI() no /app/test%3F/a%3F+b;jsessionid=s%3F+ID
getContextPath() no /app
getServletPath() yes /test?
getPathInfo() yes /a?+b

特殊字符的URL解析

Tomcat中的URL解析是支持嵌入./../;xx/等特殊字符的

新建一个Java Web项目,1.jsp如下:

<%
out.println("getRequestURL(): " + request.getRequestURL() + "<br>");
out.println("getRequestURI(): " + request.getRequestURI() + "<br>");
out.println("getContextPath(): " + request.getContextPath() + "<br>");
out.println("getServletPath(): " + request.getServletPath() + "<br>");
out.println("getPathInfo(): " + request.getPathInfo() + "<br>");
%>

放在test目录下

正常访问

http://localhost:8082/test/1.jsp

image-20240726172209143

插入 ./ 访问

插入多个./访问,即http://localhost:8082/test/./././1.jsp

image-20240726172226480

接着尝试这种形式http://localhost:8082/test/.a/.bb/.ccc/1.jsp

image-20240726172358304

返回404,未找到资源

插入 ../ 访问

插入../访问,即http://localhost:8082/test/../1.jsp

image-20240726172534288

404,因为此时实际访问的是http://localhost:8082/test/1.jsp,也就说明进行了目录穿越

插入 ;/ 访问

插入多个;/访问,即http://localhost:8082/test/;/;/;/1.jsp

image-20240726172725318

正常返回,同样的在;后面加字符串也能正常访问


调试


攻击利用

遇到下面这种filter:

package filter;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class testFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse)servletResponse;

        String url = httpServletRequest.getRequestURI();

        if (url.startsWith("/test/info")) {
            httpServletResponse.getWriter().write("No Permission.");
            return;
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

此时我们如果想要访问 /test/info 下的文件,如/test/info/secert.jsp的话会被拦截返回No Permission

而根据前面的url解析我们可以得到下面这几种绕过的方法:

http://localhost:8080/test/./info/secret.jsp
http://localhost:8080/test/;aaa/info/secret.jsp
http://localhost:8080/test/aaa/../info/secret.jsp