java反序列化
类比快递,打包拆包
json xml原生
有些快递打包和拆包时有独特需求,比如易碎朝上。类比重写writeObject和readObject
为什么产生安全问题?
只要服务端反序列化数据,客户端传递类的readObject中会自动执行,给予攻击者在服务器上运行代码的能力
可能的形式
1.入口类的readOject直接调用危险方法。
2.入口类的参数中包含可控类,该类有危险方法,readObject时调用
入口A HashMap 接收参数O
目标类B URL
目标调用B.f
A.readObject->B.f
URLDNS
3.入口类的参数中包含可控类,该类又调用其他有危险危险方法的类,readObject时调用
B.f
A[O]->O.abc
O[B]invoke ->B.f
比如类型定义为Object,调用equals/hashcode/toString
重点相同类型同名函数
4.构造函数/静态代码块等类加载时隐式执行
共同条件继承Serializable
入口类source(重写readObject 参数类型宽泛 最好自带jdk)
调用链gadget chain
执行sink (rce ssrf写文件等等)
反射
从原型class里面实例对象
获取类里面的属性
调用类里面的方法
反射的作用:让java具有动态性
修改已有对象的属性
动态生成对象
动态调用方法
操作内部类和私有方法
在反序列化漏洞中的作用:
定制需要的对象
通过invoke调用除了同名函数以外的函数
通过Class类创建对象,引入不能序列化的类
动态代理
代理是一种设计模式
不修改原有类 增加功能
动态代理 意义:
少修改代码 适配强
在反序列化漏洞中的作用:
readObject > 反序列化自动执行
invoke > > 函数调用自动执行
拼接两条链
任意->固定
类的加载机制
1、类的加载与反序列化
类加载的时候会执行代码
初始化:静态代码
实例化:构造代码、无参构造函数
2、动态类加载方法
Class.forname
初始化/不初始化
Class.Loader.loadClass 不进行初始化
底层的原理、实现加载任意类
ClassLoad->SecureClassLoad->URL->AppClassLoader
loadClass->findClass(重写方法)->defineClass(从字节码加载类)
UrlClassLoader 任意类加载 : file/http/jar
ClassLoader.defineClass 字节码加载任意类 私有
Unsafe.defineClass 字节码加载任意类 public类不能直接生成Spring 里面可以直接生成