山东大学软件学院项目实训-创新实训-山大软院网络攻防靶场实验平台(十)-Java反序列化漏洞(2)


前言:

本篇文章在上一篇文章基础上,学习了解 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/> <!-- lookup parent from repository -->
    </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>

        <!-- springboot 热部署 -->
        <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");//flag
        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 {
    /**
     * 字符串转换成为16进制(无需Unicode编码)
     * @param str
     * @return
     */
    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]);
            // sb.append(' ');
        }
        return sb.toString().trim();
    }

    /**
     * 16进制直接转换成为字符串(无需Unicode解码)
     * @param hexStr
     * @return
     */
    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);
        //Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
    }

    public static void main(String[] args) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object_hex.txt"));
        //将对象序列化到文件s
        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 file doesnt exists, then create it
        if(!file1.exists()){
            file1.createNewFile();
        }

        //true = append file
        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


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌兮_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值