# CVE-2021-28164

# 漏洞简介

Jetty WEB-INF 敏感信息泄露漏洞。 jetty是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。

Jetty 9.4.37引入对RFC3986的新实现,而URL编码的.字符被排除在URI规范之外,这个行为在RFC中是正确的,但在servlet的实现中导致攻击者可以通过%2e来绕过限制,下载WEB-INF目录下的任意文件,导致敏感信息泄露。该漏洞在9.4.39中修复。

# 漏洞环境

# jetty9.4.37 下载与启动

jetty9.4.37 (opens new window)

然后解压,进入 bin目录下执行

./jetty.sh start 启动jetty

# 准备一个简单的 war 包

由于jetty安装包下的webapps下没有任何web项目,需要准备一个war包

  • 这里使用IDEA生成简单的 hello word 项目

img.png

  • 工程名称study

img.png

  • 增加 archetypeCatalog internal 参数

img.png

  • 打war包

在工程根目录下运行: mvn clean package

  • war包复制到 jetty-distribution-9.4.37.v20210219/webapps/下

# 漏洞复现

# 直接访问/WEB-INF/web.xml将会返回404页面

img.png

# 使用%2e/来绕过限制下载web.xml

curl -v 'http://localhost:8080/study/%2e/WEB-INF/web.xml'
1

img.png

# RASP防护

rasp拦截调用参数和栈

{
    "protocol":"HTTP/1.1",
    "method":"GET",
    "remoteHost":"[0:0:0:0:0:0:0:1]",
    "requestURI":"/study/%2e/WEB-INF/web.xml",
    "stackTrace":[
        "java.io.File.<init>(File.java:275)",
        "sun.nio.fs.AbstractPath.toFile(AbstractPath.java:96)",
        "org.eclipse.jetty.util.resource.PathResource.getFile(PathResource.java:424)",
        "org.eclipse.jetty.server.CachedContentFactory.getMappedBuffer(CachedContentFactory.java:355)",
        "org.eclipse.jetty.server.CachedContentFactory$CachedHttpContent.getDirectBuffer(CachedContentFactory.java:596)",
        "org.eclipse.jetty.server.HttpOutput.sendContent(HttpOutput.java:1346)",
        "org.eclipse.jetty.server.HttpOutput.sendContent(HttpOutput.java:1225)",
        "org.eclipse.jetty.server.ResourceService.sendData(ResourceService.java:728)",
        "org.eclipse.jetty.server.ResourceService.doGet(ResourceService.java:294)",
        "org.eclipse.jetty.servlet.DefaultServlet.doGet(DefaultServlet.java:449)"
    ],
    "localAddr":"[0:0:0:0:0:0:0:1]",
    "parameterMap":{

    },
    "remoteAddr":"[0:0:0:0:0:0:0:1]"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# RASP截获的文件日志非常多如何做防护?

JRASP对文件创建进行了hook,优点是能拿到全部数据,缺点是数据太多了不能精准告警。

对study web工程启动过程中的文件创建做了分类

第一类:创建文件的线程没有处理过HTTP (占比62%)

/Users/xxx/Downloads/jetty-distribution-9.4.37.v20210219/webapps/study.war

{
  "stackTrace":[
    "java.io.File.<init>(File.java:275)",
    "sun.nio.fs.AbstractPath.toFile(AbstractPath.java:96)",
    "org.eclipse.jetty.util.Scanner$Visitor.visitFile(Scanner.java:210)",
    "org.eclipse.jetty.util.Scanner$Visitor.visitFile(Scanner.java:156)",
    "java.nio.file.Files.walkFileTree(Files.java:2670)",
    "org.eclipse.jetty.util.Scanner.scanFiles(Scanner.java:671)",
    "org.eclipse.jetty.util.Scanner.scan(Scanner.java:640)",
    "org.eclipse.jetty.util.Scanner$1.run(Scanner.java:558)",
    "java.util.TimerThread.mainLoop(Timer.java:555)",
    "java.util.TimerThread.run(Timer.java:505)"
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

第二类:创建文件的线程处理过HTTP请求 (占比38%)

/Users/xxx/Downloads/jetty-distribution-9.4.37.v20210219/lib/apache-jsp/org.eclipse.jdt.ecj-3.19.0.jar

{
    "protocol":"HTTP/1.1",
    "method":"GET",
    "remoteHost":"[0:0:0:0:0:0:0:1]",
    "requestURI":"/study/",
    "stackTrace":[
        "java.io.File.<init>(File.java:275)",
        "sun.net.www.protocol.file.Handler.openConnection(Handler.java:80)",
        "sun.net.www.protocol.file.Handler.openConnection(Handler.java:72)",
        "java.net.URL.openConnection(URL.java:1001)",
        "sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:84)",
        "sun.net.www.protocol.jar.Handler.openConnection(Handler.java:41)",
        "java.net.URL.openConnection(URL.java:1001)",
        "java.net.URLClassLoader.getResourceAsStream(URLClassLoader.java:238)",
        "java.lang.Class.getResourceAsStream(Class.java:2223)",
        "org.eclipse.jdt.internal.compiler.parser.Parser.readTable(Parser.java:783)",
        "org.eclipse.jdt.internal.compiler.parser.Parser.initTables(Parser.java:632)",
        "org.eclipse.jdt.internal.compiler.parser.Parser.<clinit>(Parser.java:161)",
        "org.eclipse.jdt.internal.compiler.Compiler.initializeParser(Compiler.java:803)",
        "org.eclipse.jdt.internal.compiler.Compiler.<init>(Compiler.java:293)",
        "org.eclipse.jdt.internal.compiler.Compiler.<init>(Compiler.java:213)",
        "org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:556)",
        "org.apache.jasper.compiler.Compiler.compile(Compiler.java:381)",
        "org.apache.jasper.compiler.Compiler.compile(Compiler.java:351)",
        "org.apache.jasper.compiler.Compiler.compile(Compiler.java:335)",
        "org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:597)",
        "org.apache.jasper.servlet.JspServletWrapper.service.md(JspServletWrapper.java:399)",
        "org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)",
        "org.apache.jasper.servlet.JspServlet.service.md(JspServlet.java:330)",
        "org.eclipse.jetty.jsp.JettyJspServlet.service.md(JettyJspServlet.java:106)"
    ],
    "localAddr":"[0:0:0:0:0:0:0:1]",
    "parameterMap":{

    },
    "cookies":[
        {
            "httpOnly":false,
            "maxAge":-1,
            "name":"JSESSIONID",
            "secure":false,
            "value":"node0h6ryrkhuq9iz1a4ml2c1u2rb30.node0",
            "version":0
        }
    ],
    "remoteAddr":"[0:0:0:0:0:0:0:1]"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

/private/var/folders/jl/gknl50qx6l13gl4_svpyj5sw0000gn/T/jetty-0_0_0_0-8080-study_war-_study-any-27103262034593673/webapp/WEB-Ieb.xml

{
    "protocol":"HTTP/1.1",
    "method":"GET",
    "remoteHost":"[0:0:0:0:0:0:0:1]",
    "requestURI":"/study/%2e/WEB-INF/web.xml",
    "stackTrace":[
        "java.io.File.<init>(File.java:275)",
        "sun.nio.fs.AbstractPath.toFile(AbstractPath.java:96)",
        "org.eclipse.jetty.util.resource.PathResource.getFile(PathResource.java:424)",
        "org.eclipse.jetty.server.CachedContentFactory.getMappedBuffer(CachedContentFactory.java:354)",
        "org.eclipse.jetty.server.CachedContentFactory$CachedHttpContent.getDirectBuffer(CachedContentFactory.java:596)",
        "org.eclipse.jetty.server.HttpOutput.sendContent(HttpOutput.java:1346)",
        "org.eclipse.jetty.server.HttpOutput.sendContent(HttpOutput.java:1225)",
        "org.eclipse.jetty.server.ResourceService.sendData(ResourceService.java:728)",
        "org.eclipse.jetty.server.ResourceService.doGet(ResourceService.java:294)",
        "org.eclipse.jetty.servlet.DefaultServlet.doGet(DefaultServlet.java:449)"
    ],
    "localAddr":"[0:0:0:0:0:0:0:1]",
    "parameterMap":{

    },
    "remoteAddr":"[0:0:0:0:0:0:0:1]"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

/private/var/folders/jl/gknl50qx6l13gl4_svpyj5sw0000gn/T/jetty-0_0_0_0-8080-study_war-_study-any-3269624983158066311/webapp/WEB-INF/web.xml

{
    "protocol":"HTTP/1.1",
    "method":"GET",
    "remoteHost":"[0:0:0:0:0:0:0:1]",
    "requestURI":"/study/%2e/WEB-INF/web.xml",
    "stackTrace":[
        "java.io.File.<init>(File.java:275)",
        "sun.nio.fs.AbstractPath.toFile(AbstractPath.java:96)",
        "org.eclipse.jetty.util.resource.PathResource.getFile(PathResource.java:424)",
        "org.eclipse.jetty.server.CachedContentFactory.getMappedBuffer(CachedContentFactory.java:354)",
        "org.eclipse.jetty.server.CachedContentFactory$CachedHttpContent.getDirectBuffer(CachedContentFactory.java:596)",
        "org.eclipse.jetty.server.HttpOutput.sendContent(HttpOutput.java:1346)",
        "org.eclipse.jetty.server.HttpOutput.sendContent(HttpOutput.java:1225)",
        "org.eclipse.jetty.server.ResourceService.sendData(ResourceService.java:728)",
        "org.eclipse.jetty.server.ResourceService.doGet(ResourceService.java:294)",
        "org.eclipse.jetty.servlet.DefaultServlet.doGet(DefaultServlet.java:449)"
    ],
    "localAddr":"[0:0:0:0:0:0:0:1]",
    "parameterMap":{

    },
    "remoteAddr":"[0:0:0:0:0:0:0:1]"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 开启阻断

请求被阻断

img.png

# 总结:当满足2个条件时才告警

  • 文件创建线程处理了http请求

  • 敏感文件/路径(设置黑名单、白名单)