前言:
本篇文章在上一篇文章基础上,学习了解 java 反序列化漏洞的基础知识后,现在开始进行漏洞环境的代码实现。
2、项目配置
编写 application.properties
spring.thymeleaf.prefix = classpath:/templates/
pom.xml 导入相关依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>java_Deserialization</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>java_Deserialization</name>
<description>java_Deserialization</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>dat</nonFilteredFileExtension>
<nonFilteredFileExtension>swf</nonFilteredFileExtension>
<nonFilteredFileExtension>xml</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>
</project>
3、编写“java 反序列化漏洞”后端代码
java 反序列化漏洞复现起来可能相较于 sql 注入更加难一些,代码量也会更多一点
首先就是想好构造一个什么样的漏洞环境,经过自己查找相关资料,考虑到自己的能力以及时间等问题,与小组成员讨论过后,决定采用代码审计,并且最终提交 flag 的方式来达到对 java 反序列化漏洞的训练的目的。
想要完成这个漏洞实验,得到 flag,要求用户首先可以看懂 java 序列化的代码,然后同时自己可以根据给出的序列化代码,编写出反序列化代码,进而得到 flag。
根据上述思路,编写的部分源码如下:
java_deser.java
package com.example.java_deserialization.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Optional;
@Controller
public class java_deser {
@RequestMapping("/java_deser")
public void java_derser_start(String flag){
flag Flag = new flag("1234abc");
System.out.println("被序列化对象:"+Flag.toString());
Optional<byte[]> bytes = ByteArrayUtils.objectToBytes(Flag);
System.out.println(bytes);
byte[] ret = bytes.get();
String r1 = ByteArrayUtils.toHexString(ret);
System.out.println("序列化后转换字节数组-16进制表示:"+r1);
}
}
indexController.java
package com.example.java_deserialization.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class indexController {
@RequestMapping(value={"/","/index.html"})
public String index(){
return "index";
}
@RequestMapping(value={"/java_deser_index"})
public String index_java_deser(){
return "java_deser";
}
}
测试 java 序列化与反序列化、编码文件 test.java
package com.example.java_deserialization.controller;
import java.io.*;
import java.util.Base64;
public class test {
public static String str2HexStr(String str) {
char[] chars = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder("");
byte[] bs = str.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append(chars[bit]);
bit = bs[i] & 0x0f;
sb.append(chars[bit]);
}
return sb.toString().trim();
}
public static String hexStr2Str(String hexStr) {
String str = "0123456789ABCDEF";
char[] hexs = hexStr.toCharArray();
byte[] bytes = new byte[hexStr.length() / 2];
int n;
for (int i = 0; i < bytes.length; i++) {
n = str.indexOf(hexs[2 * i]) * 16;
n += str.indexOf(hexs[2 * i + 1]);
bytes[i] = (byte) (n & 0xff);
}
return new String(bytes);
}
public static void main(String[] args) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object_hex.txt"));
java_DeserializationController person = new java_DeserializationController("flag{0123abcd}", 23);
oos.writeObject(person);
FileInputStream fis = null;
File file = new File("object_hex.txt");
fis = new FileInputStream(file);
byte[] b = new byte[(int)file.length()];
while (fis.read(b) != -1) {
}
System.out.println(new String(b));
String hexStr = test.str2HexStr(new String(b));
System.out.println(hexStr);
System.out.println(test.hexStr2Str(hexStr));
String data =test.hexStr2Str(hexStr);
File file1 =new File("object_hex1.txt");
if(!file1.exists()){
file1.createNewFile();
}
FileWriter fileWritter = new FileWriter(file1.getName(),true);
fileWritter.write(data);
fileWritter.close();
}
}
4、编写“java 反序列化漏洞”前端代码
index.html:用做主界面,点击跳转到 java 反序列化漏洞环境界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>java序列化与反序列化</title>
</head>
<body>
<input type="button" value="java反序列化"
onclick="javascrtpt:window.location.href='http://localhost:8080/java_deser'" />
</body>
</html>
java_deser.html:java 反序列化漏洞界面,可以查看源码,提交 flag,查看答案。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>java反序列化</title>
</head>
<body>
<p>
java反序列化漏洞(源码分析),部分序列化代码如下:
</p>
<input type="button" value="点击执行java序列化代码"
onclick="javascrtpt:window.location.href='http://localhost:8080/java_deser'" />
<p>
序列化后转化为字符数组形式,16进制表示为:
(你需要自己编写代码,把该序列化后的字符反序列化,即可得到flag)
</p>
<form action="http://localhost:8080/java_deser_test" method="get">
输入flag: <input type="text" name="id" />
<input type="submit" value="提交" />
</form>
<form action="http://localhost:8080/answer_code" method="get">
(没做出来的话)输入序列化后的16进制形式,查看答案: <input type="text" name="id" />
<input type="submit" value="查看" />
</form>
</body>
</html>
answe_code.java:答案查询代码
package com.example.java_deserialization.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class answer_code {
@RequestMapping("/answer_code")
public void answer_mathod(@RequestParam(value = "id",required = false) String r1, Model model){
byte[] r2 = ByteArrayUtils.toByteArray(r1);
flag Flag1 = (flag) ByteArrayUtils.bytesToObject(r2).get();
System.out.println("反序列化后对象:"+Flag1.toString());
}
}
5、运行测试
启动项目
java 反序列化漏洞环境主界面
生成的十六进制编码格式
反序列化
可以看到成功反序列化,并得到 flag
|