Files
Sec-Interview/Chapter14/14-9.md
T
2025-09-25 03:55:13 +08:00

43 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### 反序列化除了readObject 还有什么触发点
**1. `readResolve()` 和 `writeReplace()`**
这两个方法主要用于控制对象的序列化和反序列化过程,它们可以用来触发攻击链
- **原理**
- `writeReplace()`:这个方法在对象被序列化时调用。它允许开发者用另一个对象来替换即将被序列化的对象。攻击者可以利用这个方法,让一个无害的对象在序列化时被替换成一个恶意的对象
- `readResolve()`:这个方法在对象被反序列化后调用。它允许开发者用另一个对象来替换刚刚反序列化得到的对象。攻击者可以利用这个方法,在反序列化时触发攻击链,例如调用一个可以触发 JNDI 注入的类
- **攻击链举例**
- 攻击者构造一个恶意的对象,这个对象的 `readResolve()` 方法被重写,用于返回一个可以触发 JNDI 注入的 `JdbcRowSetImpl` 对象
- 当应用程序反序列化这个对象时,`readResolve()` 方法会被自动调用,从而将攻击链的控制权转移到 `JdbcRowSetImpl` 上,最终导致 RCE
**2. `finalize()`**
`finalize()` 方法是一个“魔法”方法,它在对象被垃圾回收时调用
- **原理**:在某些情况下,当一个对象被反序列化后,如果它不再被引用,Java 虚拟机(JVM)可能会将其放入垃圾回收队列。在垃圾回收前,JVM 会调用对象的 `finalize()` 方法
- **攻击链举例**
- 攻击者构造一个恶意的对象,这个对象的 `finalize()` 方法被重写,用于执行系统命令
- 当应用程序反序列化并丢弃这个对象时,如果垃圾回收被触发,`finalize()` 方法就会被调用,从而执行恶意代码
- **局限性**:这种方法不常见,因为它**不可预测**。你无法控制垃圾回收何时发生,甚至无法保证它一定会发生。因此,它不是一个可靠的漏洞利用方式,但其原理是成立的
**3. `toString()`**
在某些情况下,某些类在反序列化时会调用其内部对象的 `toString()` 方法
- **原理**:当一个对象被反序列化时,如果它被放入到一个需要调用 `toString()` 的上下文中(例如,在日志记录中),那么 `toString()` 方法就会被自动调用
- **攻击链举例**
- 攻击者找到一个类,它的 `toString()` 方法可以间接触发命令执行
- 攻击者构造一个恶意的序列化对象,这个对象包含上面找到的类
- 当应用程序反序列化这个对象,并将其放入一个需要调用 `toString()` 的上下文中时,就会触发攻击链
- 典型的例子是 `BadAttributeValueExpException` 这个类,它的 `readObject()` 方法会调用内部对象的 `toString()`,从而可以触发 `InvokerTransformer` 的攻击链
**4. `hashCode()` 和 `equals()`**
这两个方法通常用于哈希表(`HashMap``HashSet`)等集合类中
- **原理**:当一个哈希表被反序列化时,它需要重新构建内部的数据结构。在这个过程中,它会调用其存储的对象的 `hashCode()``equals()` 方法
- **攻击链举例**
- 攻击者构造一个恶意的哈希表,并向其中放入一个可以被利用的对象
- 当这个哈希表被反序列化时,它的 `hashCode()` 方法会被调用
- 攻击者可以利用一些特殊的类(例如 `HashSet`),让其在 `hashCode()` 方法中调用其他恶意对象的 `transform()` 方法,从而触发攻击链