参考资料

【应急响应实战笔记】:https://github.com/Bypass007/Emergency-Response-Notes

一. 情况

2022年12月4日,我和平日一样打开了电脑,准备连上云服务器(腾讯云,深圳)的MySQL数据库继续学习微服务组件时,发现Navicat报告连接错误,如下图所示。

Navicat连接云服务器MySQL数据库失败

从错误信息可以看到many connection errors字样,这也是我第一次遇到这种情况。

巧合的是,我的一个同学的云服务器(阿里云,深圳)数据库在今天遭到了攻击,所有数据库和表都被删除,且无法创建新的表。攻击者在数据库留下了一条信息:

以下数据库已被删除:arduino_test, temprature。 我们有完整的备份。 要恢复它,您必须向我们的比特币地址bc1qzzgavg2cft0h6hplup5r27hnffluf2fk6famcw支付0.028比特币(BTC)。 如果您需要证明,请通过以下电子邮件与我们联系。 cheng8925@tutanota.com 。 任何与付款无关的邮件都将被忽略!

这让我不禁将这两件事联想在一起,我的MySQL数据库极有可能遭到了暴力破解攻击(不断尝试可能的密码)。

接着,我通过终端登录云服务器,查询Aborted_connects,这个参数指的是连接失败的次数,如下图所示。

Aborted_connects查询

可以看到,数据库总共记录了24066次失败的连接,也就是说有人尝试了两万多次密码进行连接,也证实了数据库遭到了攻击(这个参数在重启数据库后会清零)。

我同学查询该字段,只有56次,说明他的密码直接就被猜出来了。事实也是如此,他的数据库用户名密码分别是root和123456,过于简单。这也说明使用安全级别更高的密码,并且不要使用默认的root用户名有多么重要。

攻击者很可能是对云服务器的IP段进行遍历,逐个扫描3306端口,使用默认用户名root,若干个密码尝试连接。如果连接上了,攻击者就会删除掉所有数据进行比特币勒索。如果遭遇到了这种情况,切勿盲目转账至攻击者的账户(攻击者可能会加大勒索力度,所以不一定能拿回数据),应第一时间找到专业的数据恢复机构。

二. 数据库情况查询

通过以下命令,可以查看数据库的一些基本情况。

查询所有用户的连接

1
mysql> show processlist;

查询总体情况

1
2
mysql> show status;
mysql> show status like '%变量%'; # 例如:show status like '%Aborted_connects%';

变量描述如下:

Aborted_clients 由于客户没有正确关闭连接已经死掉,已经放弃的连接数量。

Aborted_connects 尝试已经失败的MySQL服务器的连接的次数。

Connections 试图连接MySQL服务器的次数。

Created_tmp_tables 当执行语句时,已经被创造了的隐含临时表的数量。

Delayed_insert_threads 正在使用的延迟插入处理器线程的数量。

Delayed_writes 用INSERT DELAYED写入的行数。

Delayed_errors 用INSERT DELAYED写入的发生某些错误(可能重复键值)的行数。

Flush_commands 执行FLUSH命令的次数。

Handler_delete 请求从一张表中删除行的次数。

Handler_read_first 请求读入表中第一行的次数。

Handler_read_key 请求数字基于键读行。

Handler_read_next 请求读入基于一个键的一行的次数。

Handler_read_rnd 请求读入基于一个固定位置的一行的次数。

Handler_update 请求更新表中一行的次数。

Handler_write 请求向表中插入一行的次数。

Key_blocks_used 用于关键字缓存的块的数量。

Key_read_requests 请求从缓存读入一个键值的次数。

Key_reads 从磁盘物理读入一个键值的次数。

Key_write_requests 请求将一个关键字块写入缓存次数。

Key_writes 将一个键值块物理写入磁盘的次数。

Max_used_connections 同时使用的连接的最大数目。

Not_flushed_key_blocks 在键缓存中已经改变但是还没被清空到磁盘上的键块。

Not_flushed_delayed_rows 在INSERT DELAY队列中等待写入的行的数量。

Open_tables 打开表的数量。

Open_files 打开文件的数量。

Open_streams 打开流的数量(主要用于日志记载)

Opened_tables 已经打开的表的数量。

Questions 发往服务器的查询的数量。

Slow_queries 要花超过long_query_time时间的查询数量。

Threads_connected 当前打开的连接的数量。

Threads_running 不在睡眠的线程数量。

Uptime 服务器工作了多少秒

三. 开启日志进行预防

使用命令行登录MySQL:

1
2
3
4
5
6
7
8
9
10
11
# 1、查看log配置信息,包括日志路径
show variables like '%general%';
# 2、开启日志
SET GLOBAL general_log = 'On';
# 3、返回值
+------------------+-------------------------------------+
| Variable_name | Value |
+------------------+-------------------------------------+
| general_log | ON |
| general_log_file | /www/server/data/VM-8-11-centos.log |
+------------------+-------------------------------------+

我们尝试使用错误的密码进行几次连接,然后使用Shell进入日志所在的目录(我的日志文件是VM-8-11-centos.log)。

有哪些IP在爆破?

1
grep "Access denied" VM-8-11-centos.log |cut -d "'" -f4|uniq -c|sort -nr

返回结果如下:

1
2
49 117.26.104.82
3 183.233.227.38

说明117.26.104.82发生了49次连接失败,183.233.227.38(我自己)发生了3次连接失败。

这还是我情况日志后抓取的,说明我在写这篇文章的时候数据库又受到几十次不明意图的连接尝试。

爆破的用户名有哪些?

1
grep "Access denied" VM-8-11-centos.log |cut -d "'" -f2|uniq -c|sort -nr

返回结果如下:

1
52 root

说明有52次尝试,用户名都是root。

四. 总结

在日志分析中,特别需要注意一些敏感的操作行为,比如删表、备库,读写文件等。关键词:drop table、drop function、lock tables、unlock tables、load_file() 、into outfile、into dumpfile。

重要的数据库不要对公网开放3306端口,建议配置指定的IP才可以访问。

未解决的问题:能否记录攻击者尝试的密码?