2023 华北分区赛 normal_snake
国赛终于解出Java题了,顺利拿下一血,思路之前也学过。继续加油
normal_snake
题目解读
hello 路由下存在 SnakeYaml 反序列化漏洞,禁用了 yaml 的常用头 !!
。但是可以通过 tag 头进行绕过
或者是
SafeConstructorWithException 中过滤了常见的 payload 关键字,HEX 编码部分禁用了 BadAttributeValueExpException 和 HotSwappableTargetSource。这些都不重要
攻击 break
给了C3P0的依赖,所以肯定是用C3P0来打
C3P0 利用链
C3P0 主要有以下利用链:
触发点 | 功效 | 适用性 |
---|---|---|
JndiRefForwardingDataSource#setLoginTimeout -- InitialContext#lookup | Jndi 注入 | fastjson/snakeyaml/jackson |
WrapperConnectionPoolDataSource#setUserOverridesAsString -- ObjectInputStream#readObject | Hex 解码后触发原生反序列化 | fastjson/snakeyaml/jackson |
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject -- IndirectlySerialized#getObject() -- InitialContext#lookup | Jndi 注入 | Java原生反序列化 |
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject -- IndirectlySerialized#getObject() -- com.mchange.v2.naming.ReferenceableUtils#referenceToObject -- URLClassLoader | URLCLassLoader 远程类加载 | Java原生反序列化 |
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject -- IndirectlySerialized#getObject() -- com.mchange.v2.naming.ReferenceableUtils#referenceToObject -- BeanFactory#getInstance | 不出网的命令注入 | Java原生反序列化不出网 |
JndiRefForwardingDataSource:Jndi 注入
com.mchange.v2.c3p0.JndiRefForwardingDataSource#setLoginTimeout(int seconds)
可以触发 jndi 注入
SnakeYaml 可以触发该 setter 方法
WrapperConnectionPoolDataSource:Hex 二次反序列化
简单解释一下为什么 SnakeYaml 可以触发 Hex 二次反序列化这条链子:首先 SnakeYaml 在反序列化的时候会根据 yaml 中的类属性描述进行相关 setter 方法并调用
WrapperConnectionPoolDataSourceBase 是 WrapperConnectionPoolDataSource的父类
com.mchange.v2.c3p0.impl.WrapperConnectionPoolDataSourceBase#setUserOverridesAsString
在 snakeyaml 反序列化的时候会被调用
然后经过一系列调用栈
C3P0ImplUtils#parseUserOverridesAsString
方法:从形参处截取掉HASM_HEADER:HexAsciiSerializedMap
字符串然后进行hex解码为字节数组
com.mchange.v2.ser.SerializableUtils#deserializeFromByteArray(byte[] bytes)
处理字节数组调用原生反序列化。
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject:jndi 注入
com.mchange.v2.naming.ReferenceIndirector#getObject()
内部可以触发 JNDI 注入
具体怎么得到正确的序列化流下部分讲解
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject:远程类加载
利用链可参考ysoerial
com.mchange.v2.naming.ReferenceableUtils#referenceToObject(Reference ref,Name name,Context nameCtx,Hashtable env)
这里会获取通过 URLClassLoader 来加载远程的类并进行初始化和 getObjectInstance 方法的调用。因此可以直接在静态块里面放入恶意数据进行RCE
PoolBackedDataSourceBase 反序列化
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject()
红框中的 ois.readObject()
获取的是 IndirectlySerialized 对象,IndirectlySerialized 是一个接口,其的唯一子类是 ReferenceSerialized,但是 ReferenceSerialized 是 ReferenceIndirector 类内部的私有类,该类不能进行初始化操作。所以我们现在要康康 writeObject 是如何将 ReferenceSerialized 写入到序列化流中的
PoolBackedDataSourceBase 序列化
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#writeObject()
中,如果序列化的类是不可序列化的话(NotSerializableException),将会在 catch 块中对 connectionPoolDataSource 属性用 ReferenceIndirector.indirectForm 方法处理后再进行序列化操作。(connectionPoolDataSource 属性是 ConnectionPoolDataSource 类的实例)
ReferenceIndirector.indirectForm
方法中会取出参数 ConnectionPoolDataSource 实例中的 Reference 对象并构造出可序列化的 ReferenceSerialized
对象并返回
所以我们就需要序列化一个没有实现 Serializable 接口的 ConnectionPoolDataSource 的实例才能将 IndirectlySerialized 写入到序列化流中,ConnectionPoolDataSource 接口有俩个子类,不过遗憾的是它们俩都可以被序列化
- WrapperConnectionPoolDataSource
- JndiRefConnectionPoolDataSource
那么只能自己写一个实现 ConnectionPoolDataSource 接口的类但是不可被序列化的类咯
大功告成
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject:BeanFactory不出网
JAVA反序列化之C3P0不出网利用 和 JNDI 高版本注入很像
解题思路
因为题目的入口点是 Yaml.load 然后又给了 C3P0 依赖,又过滤了 jndi 之类的关键字,所以能想到肯定是 SnakeYaml + C3P0 的 HEX 二次反序列化。根据上面的 5 条 C3P0 利用链,选择 SnakeYaml 反序列化触发原生反序列化
然后再触发远程类加载或者jndi注入
这俩种都可以,我最后选择了 URLClassLoader 远程加载类来触发
EXP
生成序列化内容:
需要提前准备恶意类,并将其打包成 jar 包
打 jar 包命令:
然后再本地打开监听端口
最后的 Poc:
修复 Fix
俩处任意修复一处就行吧
Fix1:
Fix2:
__EOF__

本文链接:https://www.cnblogs.com/BUTLER/p/17473487.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具