反序列化除了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()

这两个方法通常用于哈希表(HashMapHashSet)等集合类中

  • 原理:当一个哈希表被反序列化时,它需要重新构建内部的数据结构。在这个过程中,它会调用其存储的对象的 hashCode()equals() 方法
  • 攻击链举例
    • 攻击者构造一个恶意的哈希表,并向其中放入一个可以被利用的对象
    • 当这个哈希表被反序列化时,它的 hashCode() 方法会被调用
    • 攻击者可以利用一些特殊的类(例如 HashSet),让其在 hashCode() 方法中调用其他恶意对象的 transform() 方法,从而触发攻击链
Copyright © 版权信息 all right reserved,powered by Gitbook该文件修订时间: 2025-09-25 03:12:56

results matching ""

    No results matching ""