背景

上周BlackHat Europe 2019的议题《New Exploit Technique In Java Deserialization Attack》中提到了一个通过注入JDBC URL实现反序列化攻击的场景,简单分析一下。

分析

当java应用使用MySQL Connector/J(官方的JDBC驱动,本文基于其8.0+版本)连接mysql时会导致潜在的反序列化攻击风险,JDBC URL的格式如下:protocol//[hosts]/[database]?properties,具体可看mysql官方文档,示例:jdbc:mysql://localhost:3306/test?useSSL=true

其中,protocol、host、database都比较好理解,URL中的properties可以设定MySQL Connector/J连接mysql服务器的具体方式,关于properties的官方文档地址,其中和本文相关的连接属性有两个,分别是autoDeserializequeryInterceptors,前者是设定MySQL Connector/J是否反序列化BLOB类型的数据,后者是拦截器,在查询执行时触发,由com.mysql.cj.protocol.a.NativeProtocol#sendQueryPacket方法源码可知,会在执行查询语句前后分别调用拦截器的preProcess和postProcess方法。

接下来定位下反序列化的触发点,在mysql-connector-java组件下全局搜索关键字“.readObject()”,定位到com.mysql.cj.jdbc.result.ResultSetImpl类中的getObject(int columnIndex)方法,部分核心代码如下:

public Object getObject(int columnIndex) throws SQLException {
……
case BLOB:
byte[] data = getBytes(columnIndex);
if (this.connection.getPropertySet().getBooleanProperty(PropertyDefinitions.PNAME_autoDeserialize).getValue()) {
Object obj = data;
// Serialized object?
try {
ByteArrayInputStream bytesIn = new ByteArrayInputStream(data);
ObjectInputStream objIn = new ObjectInputStream(bytesIn);
obj = objIn.readObject();
}
}
}

变量data即为mysql返回结果集,当JDBC URL中设定属性autoDeserialize为true时,会对类型为bit、binary以及blob的数据进行反序列化,如何触发getObject(int columnIndex)方法的调用呢?议题中给出的调用链如下:

> com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor#preProcess/postProcess
> com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor#populateMapWithSessionStatusValues
> com.mysql.cj.jdbc.util.ResultSetUtil#resultSetToMap
> com.mysql.cj.jdbc.result.ResultSetImpl#getObject

ServerStatusDiffInterceptor即为此前提到过的拦截器,在JDBC URL中设定属性queryInterceptors为ServerStatusDiffInterceptor时,执行查询语句会调用拦截器的preProcess和postProcess方法,进而通过上述调用链最终调用getObject(int columnIndex)方法。

实际利用还有一个问题,最终调用getObject方法的对象是数据库返回的结果集,由populateMapWithSessionStatusValues方法可知:

try {
toPopulate.clear(); stmt = this.connection.createStatement();
rs = stmt.executeQuery("SHOW SESSION STATUS");
ResultSetUtil.resultSetToMap(toPopulate, rs);
}

这个结果集是执行SQL语句“SHOW SESSION STATUS”后数据库返回的值,SQL语句“SHOW SESSION STATUS”返回当前数据库连接的状态值,实际是读取系统表INFORMATION_SCHEMA.SESSION_VARIABLES的值,也可能是PERFORMANCE_SCHEMA.SESSION_VARIABLES(Mysql版本差异导致)。但是mysql中INFORMATION_SCHEMA和PERFORMANCE_SCHEMA都是不允许被修改的,所以需要想办法操纵返回的数据。

利用条件

1.本质上还是Java原生的反序列化利用,所以需要环境中有可用的Gadget;

2.需要能伪造相关系统表的数据,将“SHOW SESSION STATUS”的执行结果设置为我们精心构造的反序列化数据,或者基于mysql连接协议,自定义返回数据,后面有时间的时候会写写这块儿;

3.可控的JDBC URL;

JDBC导致的反序列化攻击的更多相关文章

  1. JAVA 反序列化攻击

    Java 反序列化攻击漏洞由 FoxGlove 的最近的一篇博文爆出,该漏洞可以被黑客利用向服务器上传恶意脚本,或者远程执行命令. 由于目前发现该漏洞存在于 Apache commons-collec ...

  2. 同时大量连接导致的DDOS攻击,导致收发器宕机,用户大面积超时掉线

    前段时间一个客户改成电信网通自动路由后(当然和这个没有关系,但是客户一般没有分析能力,会多想),用户经常大面积掉线,用户才180多个,在线最多也才120多,十分苦恼,原先帮其维护的技术人员,只是远程诊 ...

  3. 方案:抵御 不明SSL证书导致的 中间人攻击

    基于SSL数字证书的中间人攻击已经不是一个新技术了,但是我发现很多人并不清楚这种威胁,甚至感觉无所谓,我相信他们是由于短暂的无知蒙蔽了双眼,希望这篇文章可以让更多的人知道这种攻击方式,并清除这种网络威 ...

  4. Java学习笔记47(JDBC、SQL注入攻击原理以及解决)

    JDBC:java的数据库连接 JDBC本质是一套API,由开发公司定义的类和接口 这里使用mysql驱动,是一套类库,实现了接口 驱动程序类库,实现接口重写方法,由驱动程序操作数据库 JDBC操作步 ...

  5. jdk紧急漏洞,XMLDecoder反序列化攻击

    昨天在公司发现了一个jdk中的XMLDecoder反序列化的漏洞,看起来很危险!下面通过两个示例来看看这个漏洞的危害! 示例1:利用XmlDecoder删除本地文件 首先来看这个xmldecoder. ...

  6. jdbc导致的问题

    遇到的问题:利用eclipse编写web project,Tomcat服务器成功开启,也通过build path导入了jdbc的路径,但是还是出现下面问题 连接数据库代码如下: 连接数据库语句没有问题 ...

  7. target="_blank" 导致的钓鱼攻击

    挺久的漏洞,之前没仔细看现在看了下 直接构建实验环境: test1.html: <!DOCTYPE html> <html> <head> <meta cha ...

  8. 实战经验丨PHP反序列化漏洞总结

    又到了金三银四跳槽季,很多小伙伴都开始为面试做准备,今天小编就给大家分享一个网安常见的面试问题:PHP反序列化漏洞. 虽然PHP反序列化漏洞利用的条件比较苛刻,但是一旦被利用就会产生很严重的后果,所以 ...

  9. NodeJS反序列化漏洞利用

    原文来自:http://www.4hou.com/web/13024.html node.js是一个服务器端的运行环境,封装了Google V8引擎,V8引擎执行JavaScript速度非常快,性能非 ...

随机推荐

  1. nyoj 257 郁闷的C小加(一)(栈、队列)

    郁闷的C小加(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说 ...

  2. 领扣(LeetCode)3的幂 个人题解

    给定一个整数,写一个函数来判断它是否是 3 的幂次方. 示例 1: 输入: 27 输出: true 示例 2: 输入: 0 输出: false 示例 3: 输入: 9 输出: true 示例 4: 输 ...

  3. objc里的伪指针TaggedPointer

    如果你看过我前面两篇objc函数枢纽msgSend和你印象中的NSString是这样吗,相信已经多次看过它的身影了,到底它是何物何作用,我今日就来揭开谜团.我之所为称呼它为伪指针,是因为它像幽灵一样, ...

  4. salesforce lightning零基础学习(十五) 公用组件之 获取表字段的Picklist(多语言)

    此篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) 我们在lightning中在前台会经常碰到获取pi ...

  5. 【论文阅读】Between-class Learning for Image Classification

    文章:Between-class Learning for Image Classification 链接:https://arxiv.org/pdf/1711.10284.pdf CVPR2018 ...

  6. Spring事务笔记

    1:在同一个类中,如果A方法有事务,B方法也有事务(propagation = Propagation.REQUIRES_NEW),如下代码所示: @Override@Transactionalpub ...

  7. JVM系列一(Java内存区域和对象创建).

    一.JVM 内存区域 堆 - Heap 线程共享,JVM中最大的一块内存,此内存的唯一目的就是存放对象实例,Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称为"GC堆"( ...

  8. 二叉查找树的平衡(DSW算法)

    树适合于表示某些领域的层次结构(比如Linux的文件目录结构),使用树进行查找比使用链表快的多,理想情况下树的查找复杂度O(log(N)),而链表为O(N),但理想情况指的是什么情况呢?一般指树是完全 ...

  9. python_排序

    快速排序 基本思想是:从一个数组中随机选出一个数N,通过一趟排序将数组分割成三个部分,1.小于N的区域 2.等于N的区域 3.大于N的区域,然后再按照此方法对小于区的和大于区分别递归进行,从而达到整个 ...

  10. 基于servlet+filter+反射模拟实现天猫首页的后端

    前言:为了深入web原理,本项目没有使用框架,主要描述了从请求到页面展现的思路,详情请见文末的具体项目 一.为什么要用filter?直接servlet实现不就行了 因为天猫这样的项目需要很多servl ...