0%

动态代理在Java反序列化中的应用

动态代理简介

何为代理?在日常生活中我们或多或少都接触过房产中介、4S店以及各种各样的代理商,他们在经济社会运行当中扮演着代理的角色,负责对接厂商与客户。
用户如果想要投诉产品、寻求赔偿等,可以统一找到代理商,由代理商向厂商提出,这样便极大的节约了用户的各方面成本。
在编程中所谓的代理模式也是同样的道理,当我们想要对某一个类进行功能扩展而又不想直接修改当前类的代码的时候,我们可以创建一个代理类来对目标类进行包装。
通过在当前类的运行前、运行后、运行异常时添加新的代码从而实现目标类功能的增强与拓展。这便是代理模式的运行。如下图,A表示被代理类,B表示代理类,当A没有被代理时,外界的其他方法可以直接调用A的方法,
当A被代理后,C的方法如果要想调用A的方法就需要先通过B类再由B类调用A类的方法,那么我们便可以在B类中增加一些其他的功能。B类此时就类似一个收保护费的,要想从此过,留下买路钱,正所谓漫天要价,坐地还钱。

阅读全文 »

利用链分析

关于序列化与反序列化过程中使用的代理选择器以及代理这里就不再介绍了,代理(Surrogate)可以使得不能被序列化的类被序列化,具体的操作需要用户自行实现一个ISerializationSurrogate接口并实现其GetObjectData以及SetObjectData方法。

阅读全文 »

利用链分析

TextFormattingRunProperties实现了System.Runtime.Serialization.ISerializable接口,故其在序列化以及反序列化过程中会自动执行GetObjectData以及特定的构造方法internal TextFormattingRunProperties(SerializationInfo info, StreamingContext context)
img1
我们直接从反序列化时执行的特殊构造方法创建对象的过程开始。
在调用构造方法创建对象期间会调用GetObjectFromSerializationInfo方法从serializationInfo中获取属性值。

阅读全文 »

本文总结了一些常见的Java动态代理InvocationHandler在反序列化中的作用,这些InvocationHandler根据其功能的不同往往能达成奇妙的效果,本文对这些类进行了梳理总结,方便漏洞挖掘时能够快速有效地串联其各个Gadgets形成有效的利用链。

阅读全文 »

成员变量含义

变量名 默认值 含义
DEFAULT_INITIAL_CAPACITY 16 默认初始化容量
MAXIMUM_CAPACITY 1 << 30 最大容量
DEFAULT_LOAD_FACTOR 0.75 默认加载因子,当数组中元素数量超过总长度的0.75的时候会进行自动扩容
TREEIFY_THRESHOLD 8 当链表长度超过8的时候会将链表转换为红黑树
UNTREEIFY_THRESHOLD 6 当链表元素少于6的时候会将红黑树转换为链表
MIN_TREEIFY_CAPACITY 64 只有当数组长度大于64的时候才会执行链表的树化,因为链表树化会增加空间复杂度,如果只要某一个链表长度超过8就进行树化得到的查询时间优化与增加的空间消耗两相比较是得不偿失的
阅读全文 »

过滤器初始化

Struts2 的访问从配置的org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter过滤器开始。
过滤器在程序加载过程中首先被执行的是init方法

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
public void init(FilterConfig filterConfig) throws ServletException {
// 创建 InitOperations 对象 负责各个关键组件的初始化操作
InitOperations init = createInitOperations();
Dispatcher dispatcher = null;
try {
// 简单的包装了一下 filterConfig
FilterHostConfig config = new FilterHostConfig(filterConfig);
// 初始化日志记录器 不是重点
init.initLogging(config);
// 初始化dispatcher 重点
dispatcher = init.initDispatcher(config);
// 初始化静态类容加载器
init.initStaticContentLoader(config, dispatcher);

prepare = createPrepareOperations(dispatcher);
execute = createExecuteOperations(dispatcher);
// 设置将哪些path排除到strutsd的filter之外 这些请求将不会被struts处理 而交给之后的filter或者servlet处理
this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
// 用户可以继承该过滤器 重写该方法 做一些额外的初始化操作
postInit(dispatcher, filterConfig);
} finally {
if (dispatcher != null) {
dispatcher.cleanUpAfterInit();
}
init.cleanup();
}
}
阅读全文 »