Mysql JDBC反序列化

admin 2023年10月26日23:36:10评论15 views字数 4020阅读13分24秒阅读模式


Mysql JDBC反序列化

明天要面试,不想复习啊。

之前不怎么学习这个漏洞。但是最近被问了两次,而且后来我发现不同类型数据库的反序列化漏洞还挺多的。

看了看资料略写写还算简单。主要是分析反序列化部分,CC链部分不管,mysql协议部分不管。

利用点

jdbc连接数据库的过程中,配置连接地址以及一些连接参数就有可能造成反序列化漏洞。

如下是jdbc连接数据库代码。

  Class.forName("com.mysql.jdbc.Driver");
  String jdbc_url = "jdbc:mysql://127.0.0.1:3309/test?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai" +
                "&autoDeserialize=true" +
                "&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor";
        Connection con = DriverManager.getConnection(jdbc_url, "root""123123");

利用场景

可以修改jdbc连接数据库参数配置的地方如后台数据库配置或者一些配置文件。

以及对mysql-connector-java版本有要求,不同版本的利用参数略有区别,有些版本利用不了

payload&&复现环境工具

模拟mysql协议恶意请求包poc:
https://github.com/Drun1baby/JavaSecurityLearning/blob/main/JavaSecurity/JDBC/exp.py 【弹计算器】
大家需要其他exp可以自己利用ysoserial生成然后去修改exp.py中payload

分析

这是一个原生的反序列化漏洞,找到外部可控的readobject即可

  • 在mysql-connector-java-8.0.13.jar搜索readobejct发现
    ResultSetImpl.java类存在getObject方法中存在两处的readObject调用

  @Override // java.sql.ResultSet
    public Object getObject(int columnIndex) throws SQLException {
        int columnIndexMinusOne;
        try {
            checkRowPos();
            checkColumnBounds(columnIndex);
            columnIndexMinusOne = columnIndex - 1;
        } catch (CJException e) {
            throw SQLExceptionsMapping.translateException(e, getExceptionInterceptor());
        }
        if (this.thisRow.getNull(columnIndexMinusOne)) {
            return null;
        }
        Field field = this.columnDefinition.getFields()[columnIndexMinusOne];
        switch (AnonymousClass1.$SwitchMap$com$mysql$cj$MysqlType[field.getMysqlType().ordinal()]) {
            case 1:
                if (!field.isBinary() && !field.isBlob()) {
                    return field.isSingleBit() ? Boolean.valueOf(getBoolean(columnIndex)) : getBytes(columnIndex);
                }
                byte[] data = getBytes(columnIndex);
                if (this.connection.getPropertySet().getBooleanProperty(PropertyKey.autoDeserialize).getValue().booleanValue()) {
                    Object obj = data;
                    if (data != null && data.length >= 2) {
                        if (data[0] == -84 && data[1] == -19) {
                            try {
                                ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
                                ObjectInputStream objIn = new ObjectInputStream(bytesIn);
                                obj = objIn.readObject();
                                objIn.close();
                                bytesIn.close();
                            } catch (IOException e2) {
                                obj = data;
                            } catch (ClassNotFoundException cnfe) {
                                throw SQLError.createSQLException(Messages.getString("ResultSet.Class_not_found___91") + cnfe.toString() + Messages.getString("ResultSet._while_reading_serialized_object_92"), getExceptionInterceptor());
                            }
                        } else {
                            return getString(columnIndex);
                        }
                    }
  • 搜索哪些方法调用了ResultSetImpl.getObject,idea 右键 find usages,最终找到了ResultSetUtil类的resultSetToMap方法

Mysql JDBC反序列化

搜索谁调用了resultSetToMap 找到了

ServerStatusDiffInterceptor类中的populateMapWithSessionStatusValues 方法

Mysql JDBC反序列化

ServerStatusDiffInterceptor是一个拦截器,populateMapWithSessionStatusValues方法在prepocess以及postProcess中调用,只有开启拦截器设置JDBC URL 中设定属性 queryInterceptors 为 ServerStatusDiffInterceptor 时,执行查询语句会调用拦截器的 preProcess 和 postProcess 方法

  • 检查getObjetc函数

Mysql JDBC反序列化

这块代码首先会判断是不是二进制binary形式,以及autoDeserialize的bool值所以要设置autoDeserialize值为true.

反序列化到这里就完成了一大半。

后面具体的payload需要分析mysql协议。exp主要是利用ysoserial cc链生成的以及需要符合mysql协议格式

为什么后面要使用CC链

java反序列化readobject过程中是需要使用类加载器找到对应的类才能进行反序列化的,如果类加载器在服务器上找不到对应类直接去执行readobject就会报错

必须用服务器上存在的类,怎么让它在readObject执行过程中触发呢?这里就是CC链的重要意义了,如果反序列化的类定义了readObject方法,服务器上执行ObjectInputStream.readObject时,会自动调用反序列化类中的readObject方法,更进一步的,如果反序列化类的readObject方法中执行了该类成员变量的某些方法,而这些成员变量是可控的,一个反序列化利用或许就出现了

引用:

https://www.cnblogs.com/bitterz/p/15035581.html

https://xz.aliyun.com/t/8159#toc-1


原文始发于微信公众号(天才少女Alpha):Mysql JDBC反序列化

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年10月26日23:36:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Mysql JDBC反序列化http://cn-sec.com/archives/2149050.html

发表评论

匿名网友 填写信息