Ripstech Java Security 2019 Calendar复现系列(三)
2020-02-17 10:24:02 Author: xz.aliyun.com(查看原文) 阅读量:292 收藏

代码

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

漏洞点

这段代码的作用是将tar文件里面的内容提取到tomcat临时目录中以test开头的文件夹中。"/tmp/uploaded.tar"是攻击者可控的。tar文件里的每个文件或文件夹都映射到一个TarArchiveEntry对象。由于第16行的TarArchiveEntry.getName()获取tar文件里的文件名,然后通过一个简单的对"../"的过滤到达接收器java.io.File。由于过滤不严,可以绕过../的检查,将文件写入到任意目录下,从而可导致RCE攻击。

复现过程

1. 环境

由于此攻击需要Linux系统下才能成功,使用docker复现

  • docker pull tomcat:9.0.30-jdk8-openjdk
  • docker run -p 80:8080 -it container_id /bin/bash
  • 启动tomcat
  • 将打包好的war包放入/usr/local/tomcat/webapps目录下

2. war包

  • IDEA+maven-archetype-webapp

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>day11</servlet-name>
    <servlet-class>com.ananasker.day11.ExtractFiles</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>day11</servlet-name>
    <url-pattern>/day11</url-pattern>
  </servlet-mapping>
</web-app>

ExtractFiles.java

...

protected void doPost(HttpServletRequest req, HttpServletResponse res) {
        try {
            extract();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

...

3. payload构造

首先,../的检查很容易通过..././来绕过,因此可以将文件写入任意位置。例如,此例中tomcat的web目录位于/usr/local/tomcat/webapps,因此可构造如下文件名的恶意文件

..././..././..././..././..././usr/local/tomcat/webapps/ROOT/index.jsp

直接无法生成此文件名的文件,可先构造等长文件名的文件,然后将其打包为uploaded.tar,然后使用二进制修改器,将里面的名称修改为"..././..././..././..././..././usr/local/tomcat/webapps/ROOT/index.jsp"。如图所示

将修改后uploaded.tar放入/tmp目录下

4. 结果

如图所示,发送POST请求后,成功在web目录下写入文件

代码

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

漏洞点

在index.jsp中,首先定义一个customClass为"default",在包含的init.jsp中,customClass被覆盖为请求参数customClass的值,然后此值在未经过滤的情况下,被赋值给div标签的属性值中。然后customClass与username都被ESAPI给HTML编码了。此处的漏洞在于第一个div属性的customClass值完全由攻击者可控,且未经任何过滤,因此可以突破属性的限制,从而导致XSS。

复现过程

1. 环境

  • IDEA+maven-archetype-webapp

2. 添加配置文件

在resources目录下添加,ESAPI.properties以及validation.properties。文件内容在此题中,我设置为均为空,为空表示取默认值。

3. payload构造

通过双引号,突破属性值的限制。即最终的payload可为如下所示:

/index.jsp?username=123&customClass=1" </div><script>alert(1)</script>

4. 结果

结果如下所示:

代码

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

漏洞点

这段代码支持一个文件上传,并将上传的文件存入临时目录。通过ServletFileUpload类的重要方法parseRequest,对请求消息体内容进行解析,将每个字段的数据包装成独立的Fileitem对象。为了阻止攻击者上传如.jsp的文件,对消息的Content-Type进行了简单的判断是否属于text/plain,但可被简单的绕过。另一个由攻击者控制的是文件名且未经过任何检查,这导致目录遍历漏洞,因为类似/../的字符串在java中是有效的文件名。

最终,攻击者可以上传任意文件,通过目录遍历漏洞可设置上传文件的地址,最终导致RCE远程命令执行。

复现过程

1. 环境

  • IDEA+maven-archetype-webapp

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>day13</servlet-name>
    <servlet-class>com.ananaskr.day13.UploadFileController</servlet-class>
  </servlet>

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

3. 添加upload.jsp

upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<form method="post" action="/Day13_war_exploded/day13" enctype="multipart/form-data">
    <input type="file" name="uploadFile"/>
    <br/><br/>
    <input type="submit" value="upload"/>
</form>

</body>
</html>

4. 构造payload

在打印出上传路径后,得知只需返回父级目录即可。或者不确定的,可使用绝对路径。payload如下

5. 结果

代码

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

漏洞点

这段代码主要是想要利用CSV注入这个漏洞点。其中CSV文件的一个单元格内容是由攻击者完全可控的,因此可造成注入。

但是代码的逻辑却是将攻击者的输入以CSV格式响应给攻击者自身,即攻击者自己获取到了有恶意代码的CSV文件,打开在攻击者自身的环境下执行了恶意行为。因此,未进行复现。

代码

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

漏洞点

这段代码使用"find"系统命令并向用户公开当前文件夹的目录。这会导致信息泄露,但攻击者可利用此代码造成更大的伤害。第9行代码建立了基本的命令(find . -type d)。第12-15行代码接收参数options,并将其附在"find . -type d"命令后。最后调用java.lang.ProcessBuilder来执行命令。
首先直接的命令执行不可能,因为所有的输入都附在find命令后,会被当成参数。然而,攻击者控制的此命令的某些选项/参数,会导致参数注入漏洞。通过注入find命令的参数-exec,攻击者可以执行任意系统命令。

复现过程

1. 环境

  • IDEA+maven-archetype-webapp

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>day15</servlet-name>
    <servlet-class>com.ananaskr.day15.FindOnSystem</servlet-class>
  </servlet>

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

3. 修正代码

将doGet换成doPost

4. 构造payload

find命令的-exec参数后面跟command命令,它的终止是以;结束的。与之类似的是-ok参数,-ok参数是以一种更为安全的模式来执行该参数所给的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。因此,选择-exec参数,可构造如下payload

options=-exec cat /etc/passwd ;

4. 结果

代码

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

漏洞点

此代码中通过@RequestParam注释接受用户输入的name参数值,然后经过escapeQuotes函数过滤后,拼接到HQL sql语句中,进而被执行。。代码中的escapeQuotes函数的作用是将输入中的'变成两个'。因此payload中包含\'即可绕过此限制,从而导致sql注入。

复现过程

1. 环境

  • IDEA+springmvc+hibernate
  • 导入servlet以及hibernate相关的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.day16" />
    <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="FindController" class="com.ananaskr.day16.FindController">
</bean>
</beans>

5. 添加hibernate.cfg.xml

  • 在src路径下添加此配置文件
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>

        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/day</property>

        <property name="connection.username">root</property>
        <property name="connection.password"></property>

        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="current_session_context_class">thread</property>
        <property name="show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>
        <mapping class="com.ananaskr.day16.UserEntity" />

    </session-factory>

</hibernate-configuration>

6. 修正代码

FindController.java

15   List <UserEntity> users = session.createQuery("from UserEntity where FIRST_NAME ='" + escapeQuotes(name) + "'", UserEntity.class).list();
改为
15   List <UserEntity> users = session.createQuery("from UserEntity where firstName ='" + escapeQuotes(name) + "'", UserEntity.class).list();

UserEntity.java
所有持久化类必须要求有不带参的构造方法(也是JavaBean的规范)。Hibernate需要使用Java反射为你创建对象。当类中声明了其他带参构造方法时,需在类中显示声明不带参数构造方法。

public UserEntity(){
    }

7.payload构造

代码中的escapeQuotes函数的作用是将输入中的'变成两个'。因此payload中包含\'即可绕过此限制。然后在最后加上注释#,绕过最后的单引号。最终的payload如下:

test\' or 1=1 #

由于代码中只返回查询结果的数量,因此可实施盲注。

8.结果

数据库仅包含如下数据

当查询正确时

当使用payload时


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