制胜法宝(不是)

JAVA安全学习路线 IDEA Maven
Java Web
反射
ASM/Javassist
JNDI:8u191低版本和高版本怎么打(反序列化/本地工厂),以及如何审计
RMI是什么
Java Agent:启动原理和RASP的实现原理
JMX/JDWP
反序列化基础:gadget链、JEP290是什么
FastJson反序列化
WebLogic:二次反序列化、XML Decoder、IIOP/T3
Xstream反序列化
Hessian反序列化:dubbo
SnakeYAML反序列化
Shiro:Shiro经典漏洞、Padding Oracle漏洞形成原理、如何通过Shiro注入内存马
Struts2
Spring:Spring4Shell、Spring EL、SpringBoot Actuator利用
Tomcat:Tomcat AJP RCE
内存马原理:原理是什么、有哪些内存马
内存马如何查杀
Log4J
其他组件漏洞:Apache Solr、Flink
进阶:tabby、codeql等静态分析
### 序列化

Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。

字节,也就是byte *,1byte = 8bit,也就是一个字节等于8位,每一位都是用0或者1来表示,在内存中,数据就是以 二进制 的形式存储的

序列化是将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。

Java其自身是有一套序列化机制,可以把Java对象序列化成字节序列,还可以把自己序列再通过反序列化还原成原来的对象!

JAVA序列化样例

序列化在 Java 中是通过 ``java.io.Serializable `接口来实现的,该接口没有任何方法,只是一个标记接口,用于标识类可以被序列化。

例如以下序列化代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.FileOutputStream;

public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
try
{
FileOutputStream fileOut =new FileOutputStream("./employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
---同目录下Employee.java文件
import java.io.Serializable;

public class Employee implements Serializable {

public String name;
public String address;

}
--反序列化代码
Employee obj = null;
try {
FileInputStream fileIn = new FileInputStream("./employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
obj = (Employee ) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
} catch (ClassNotFoundException i) {
i.printStackTrace();
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);

可以看到已写入二进制文件ser中

1

JAVA序列化–接口

接口通常以interface来声明。接口并不是类,虽然接口的编写方式和类很相似,但是它们属于不同的概念。 类描述对象的属性和方法。接口则包含类要实现的方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口文件保存在 .java 结尾的文件中,文件名使用接口名。接口的字节码文件保存在 .class 结尾的文件中。接口相应的字节码文件必须在与包名称相匹配的目录结构中。接口不能用于实例化对象。接口没有构造方法。接口不能包含成员变量,除了 static 和 final 变量。

接口的声明格式:

1
2
3
public interface 接口名称 [extends 其他的接口名] {       
// 变量与抽象方法
}

在序列化中要使用implements Serializable (实现Serializable接口)接口什声明此类可以被序列化

Serializable 类中没有任何方法和属性但一定要声明,用来表示这个类允许把对象转换为流形式储存和传输。

安全问题

只要服务端反序列化数据,客户端传递类的readObject中的代码便会自动执行,从而使恶意代码可以在服务器上执行。

readObject()简介

readObject()是ObjectInputStream类中的一个方法,它用于从输入流中反序列化对象。

ObjectInputStream可以序列化对象到输出流,同时也可以从输入流中反序列化对象。readObject()方法就是用于对象的反序列化。

readObject()方法的具体作用和过程:

  • 从输入流(如FileInputStream)中读取serialized对象的描述信息。
  • 根据描述信息反序列化对象,将对象重构并创建在JVM内存中。
  • 返回反序列化后的对象引用。

通过readObject()可以反序列化get shell等。


会先做ctfshow的java的基础题,等到序列化后在更新

。。。