背景

上周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的官方文档地址,其中和本文相关的连接属性有两个,分别是autoDeserialize和queryInterceptors,前者是设定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. 通过 position:fixed 实现底部导航

    通过 position:fixed 实现底部导航 HTML <div id="footer">页脚</div> CSS #footer { clear: b ...

  2. PHP 提交复选框数据

    PHP 提交复选框数据 前台,name要加 []: <input type="checkbox" name="cate[]" value="ca ...

  3. nyoj 96-n-1位数 (strlen, atoi, ceil)

    96-n-1位数 内存限制:64MB 时间限制:3000ms 特判: No 通过数:30 提交数:47 难度:1 题目描述: 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2) ...

  4. shell脚本2——控制语句

    1.顺序结构体 命令从上往下顺序执行 2.分支结构体 1)判断真假 test 表达式 或者 [ 表达式 ](必须有空格) 真返回0,假返回1 test的别名是[, 参数是] 判断表达式 记忆 解释 ! ...

  5. ZeroC ICE的远程调用框架 class与interface

    我们在ice文件中定义的class或interface,slice都会为我们生成stub存根类和skeleton骨架类.在这里要注意slice并没有分别生成两份单独用在客户端或服务端的接口给开发分发. ...

  6. 一个自动修正数据时间和补全缺失数据的MapReduce程序

    原始数据如下图: 程序: Mapper类: public class DemoMapper extends Mapper<LongWritable,Text,IntWritable,Text&g ...

  7. Redis入门,对Redis的理解和基本环境搭建及操作

    Redis入门使用 参考:https://blog.csdn.net/hellozpc/article/details/81267030 一).缓存的用途举例 1.前端页面广告的数据无需每次查询后台系 ...

  8. eNSP仿真软件之配置Trunk口

    实验原理 在以太网中,通过划分VLAN来隔离广播域和增强网络通信的安全性.以太网通常由多台交换机组成,为了使VLAN的数据帧跨越多台交换机传递,交换机之间互连的链路需要配置为干道链路(Trunk Li ...

  9. SQL SERVER中SELECT和SET赋值相同点与不同点

    SELECT和SET在SQL SERVER中都可以用来对变量进行赋值,但其用法和效果在一些细节上有些不同. 1. 在对变量赋值方面,SET是ANSI标准的赋值方式,SELECT则不是.这也是SET方式 ...

  10. js对象的直接赋值、浅拷贝与深拷贝

    最近Vue项目中写到一个业务,就是需要把对话框的表单中的数据,每次点击提交之后,就存进一个el-table表格中,待多次需要的表单数据都提交进表格之后,再将这个表格提交,实现多个表单数据的同时提交,期 ...