浅谈Java二次反序列化
字数 1500 2025-08-05 12:50:33
Java二次反序列化技术深度解析
一、二次反序列化概述
二次反序列化是指在反序列化过程中,通过特定技术手段触发第二次反序列化操作,主要用于解决以下场景:
- JNDI不出网情况下的利用
- 绕过反序列化黑名单限制
- 突破单一反序列化的限制
二、SignedObject二次反序列化技术
1. SignedObject类简介
SignedObject是java.security包下的类,用于创建真实运行时对象,特点:
- 包含另一个
Serializable对象 - 提供
getObject()方法触发二次反序列化
2. 核心利用链分析
基本利用模式:
SignedObject#getObject() -> x.readObject()
3. 构造恶意SignedObject示例
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
SignedObject signedObject = new SignedObject(恶意对象, kp.getPrivate(), Signature.getInstance("DSA"));
三、Getter方法触发链
1. Rome链(HashCode方式)
利用链:
hashmap#readObject()
-> ObjectBean#hashcode()
-> EqualsBean#javabeanHashCode()
-> ToStringBean#toString()
-> SignedObject#getObject()
2. Rome链(Equals方式)
利用链:
Hashtable#readObject()
-> EqualsBean#equals()
-> EqualsBean.beanEquals()
-> SignedObject#getObject()
3. CommonsBeanutils链
利用原理:
- 通过
PropertyUtils.getProperty()动态调用getter方法 - 利用
BeanComparator#compare()触发getter调用
利用链:
PriorityQueue#ReadObject()
-> PriorityQueue#siftDownUsingComparator()
-> BeanComparator#compare()
-> PropertyUtilsBean#getSimpleProperty()
-> TemplatesImpl#getOutputProperties()
4. Jackson链
利用链:
通过POJONode#toString()触发getter调用,结合:
BadAttributeValueExpException#readObject()ToStringBean#toString()
四、RMIConnector二次反序列化
1. 核心利用链
InvokerTransform#transform()
-> RMIConnector#connect()
-> RMIConnector#findRMIServerJRMP()
2. 关键方法分析
findRMIServerJRMP():
- 解码base64字符串
- 以序列化流形式进行反序列化
利用要点:
- 设置
urlPath为/stub/base64_ser_str - 通过反射修改
urlPath属性
五、实战案例分析
案例1:2023巅峰极客BabyURL
考点:
- Java代码审计
- SignedObject二次反序列化
- Jackson链利用
绕过技巧:
- 使用
File:///代替file:///绕过URL检查 - 结合
BadAttributeValueExpException触发
案例2:[TCTF 2021]buggyLoader
特殊限制:
- 使用
URLClassLoader.loadClass()而非Class.forName() - 无法加载数组类(如
[[B)
解决方案:
- 使用单
InvokerTransformer触发 - 避免使用
ChainedTransformer链式调用
案例3:2023浙江省赛secObj
特殊场景:
- Spring Security CSRF防护
- 需要携带Session和CSRF token
利用链组合:
BadAttributeValueExpException#readObject()
-> ToStringBean#toString()
-> POJONode#toString()
-> SignedObject#getObject()
-> ...
六、防御与绕过技巧
1. 常见防御措施
- 重写
resolveClass方法进行黑名单过滤 - 使用
URLClassLoader限制数组类加载 - Spring Security CSRF防护
2. 绕过方法
- 二次反序列化绕过单次过滤
- 大小写混淆绕过关键字检测
- 结合多种链式调用突破限制
七、完整EXP示例
SignedObject + Rome链示例
// 参见原文完整代码
RMIConnector利用示例
// 参见原文完整代码
Spring环境利用示例
// 参见原文完整代码
八、总结
二次反序列化技术提供了在受限环境下实现RCE的有效途径,关键在于:
- 找到合适的二次反序列化触发点(如SignedObject)
- 构建有效的getter方法调用链
- 根据环境特点选择合适的利用链组合
- 处理各种环境限制和防护措施
通过深入理解各组件的工作原理和交互方式,可以灵活组合各种技术突破安全限制。