数据库被黑了是如何自救和恢复的

502 阅读9分钟


数据库被黑之后,是如何进行自省和修复的!

背景

好久没登录的搭建的外网,今天登录之后发现不能正常访问了。服务器是阿里云的。看阿里云记录还是ok的。

然后查看数据库发现了不一样的东西。第一次被黑,记录下。

image-20220718103510832

contentemail
如果你不愿意支付一定的费用请不要联系我们,邮件需按格式发送,邮件标题:你的数据库IP地址,邮件内容:恢复数据。对于没有支付的数据,我们会公布数据和组织信息在国内外平台中。wangruiservic@tutanota.com

首先,我先感谢对我的认可啊,认为我这个网站是有价值的。嗯。棒棒哒~

然后我马不停蹄的给对方回复了。但对方一直也没理我哈。因为我也不记得我有多少个数据库和具体内容是啥了。

既然你不回我。那我只能自己找找看了。

一、找入侵痕迹

1.1、检查用户和组

(1)查看/etc/passwd下的异常用户 (2)查看/etc/group组中有无异常 (3)检查空口令,uid为0的用户,和就有登录权限的用户

//查看具有登录权限的用户
awk -F: '($7=="/bin/bash"){print $1}' /etc/passwd   
//查看UID为0的账号,UID为0的用户会自动切换到root用户,所以危害很大正常只有root
awk -F: '($3==0)' /etc/passwd    
 //查看空口令账号,如果存在空口令用户的话必须设置密码
awk -F: '($2=="")' /etc/shadow  

1.2、检查进程

(1)输入top,shift+p按照cpu排序,shift+m按照内存排序,查看下是否有异常的进程占用很高。

img

(2)ps aux | more 检查所有进程,找出不是很常见的进行下排查,这个需要结合一些经验。 查看到pid后检查proc位置检查下的pid路径,找到异常进程的程序文件,kill掉进程,然后删除

使用ll /proc/进程ID 查看exe路径
查看该进程启动的完整命令行: ps eho command -p $PID
查看该进程启动时候所在的目录: readlink /proc/$PID/cwd
查看下pid所对应的进程文件路径:ls -l /proc/$PID/exe
查看该进程启动时的完整环境变量: strings -f /proc/1461/environ | cut -f2 -d ''
列出该进程所打开的所有文件: lsof -p $PID

1.3、检查启动项

(1)检查/etc/init.d/目录,有无异常服务 (2)vi /etc/rc.local 查看有无异常启动项 (3)centos可使用chkconfig查看3为on的服务

1.4、检查计划任务

(1)crontab -l查看有没有被加入异常的计划任务,如果有需要根据文件路径做处理删除 (2)检查/var/spool/cron有无用户的计划任务(部分计划任务是以其他用户添加的) (3)检查/etc/cron.daily/等下面的计划任务,打开查看下, 比如vi /etc/cron.daily/logrotate黑客可以在一些正常的计划任务中添加异常代码,实现异常的启动项。

1.5、检查应用的敏感目录

比如/tmp/ MySQL的运行data目录,有没有被注入大量恶意信息 ,如果发现有很多异常的程序,需要删除下(这种一般不容易清理干净,可以进行下备份恢复) 比如linux系统中出现类似Windows的目录或可执行文件如果判断不是用户自己上传的,很有可能系统被黑或数据库被黑。

cat /var/log/mysqld.log | grep password

image-20220718105249137

看日志应该是有人一直在尝试登录。因为我一直没有登陆,这个他们是怎么登录的呢?

1.6、检查系统日志

在Linux上一般跟系统相关的日志默认都会放到/var/log下面,若是一旦出现问题,用户就可以通过查看日志来迅速定位,及时解决问题。 常用日志文件如下: /var/log/btmp:记录错误登录日志,这个文件是二进制文件,不能直接vi查看,而要使用lastb命令查看。 /var/log/lastlog:记录系统中所有用户最后一次登录时间的日志,这个文件是二进制文件,不能直接vi,而要使用lastlog命令查看。 /var/log/wtmp:永久记录所有用户的登录、注销信息,同时记录系统的启动、重启、关机事件。同样这个文件也是一个二进制文件,不能直接vi,而需要使用last命令来查看。 /var/log/utmp:记录当前已经登录的用户信息,这个文件会随着用户的登录和注销不断变化,只记录当前登录用户的信息。同样这个文件不能直接vi,而要使用w,who,users等命令来查询。 /var/log/secure:记录验证和授权方面的信息,只要涉及账号和密码的程序都会记录,比如SSH登录,su切换用户,sudo授权,甚至添加用户和修改用户密码都会记录在这个日志文件中。

这里没查到啥问题啊。应该是阿里云给挡住了。服务器没有攻破,数据库被攻击了。

二、找不到就重新搞吧。卸载旧的,又重新安装

数据库按理说不用重装,改密码,限制权限应该也没问题。但我就是不放心,就这个重来了。

2.1.卸载旧的

查询是否有mysql的安装:rpm -qa | grep mysql 查询是否有Mariadb的安装:rpm -qa | grep mariadb 如果有卸载掉:yum -y remove 文件名

2.2.下载新的

将tar包解压到指定目录:tar xvf xx.tar -C ./x

我下载的文件地址为:downloads.mysql.com/archives/ge…

2.3|安装:

rpm -ivh mysql-community-common-5.7.36-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.36-1.el7.x86_64.rpm 
rpm -ivh mysql-community-client-5.7.36-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.36-1.el7.x86_64.rpm

2.4|启动mysql服务:

systemctl start mysqld

2.5|在日志中查询初始密码

(最后面的一串大概12位就是):cat /var/log/mysqld.log | grep password

2022-07-15T15:39:51.594053Z 1 [Note] A temporary password is generated for root@localhost: 9.,>=G<p,ai:
​
​
密码: 9.,>=G<p,ai:

2.6 修改初始密码

修改密码,直接修改会有一个密码复杂度校验,

关闭这个校验,编辑文件my.cnf:

vim /etc/my.cnf 在[mysqld]下一行加入:

validate_password=off

重启mysql服务:

systemctl restart mysqld

重新进入sql修改密码:

mysql -uroot -p
9.,>=G<p,ai:
​
alter user 'root'@'localhost' identified by '123456';
​
update mysql.user set authentication_string = password ('123456') where user = 'root' and host = 'localhost';

三、禁止远程连接

3.1默认是禁止远程连接的。如何开启

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY 'zb-000#123' WITH GRANT OPTION;
flush privileges;

3.2如何关闭

update mysql.user set host='localhost' where user='root';
delete from mysql.user where host='%' and user='root';
flush privileges;

四、设置免密登录

4.1设置mysql登陆用户和密码:

mysql_config_editor set --login-path=root --user=root --host=localhost --password="zb-000#123"

4.2、输入密码:

Enter password:  zb-000#123

若密码中包含“#”,请在密码外添加双引号,如:

"test!@#"

4.3、查看配置的免密登陆用户

mysql_config_editor print --all

4.4、免密登陆

mysql --login-path=root

4.5、删除免密登陆配置

mysql_config_editor remove --login-path=root

五、开启binlog 日志

5.1打开log-bin日志

mysql>  show variables like '%log_bin%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin                         | OFF   |
| log_bin_basename                |       |
| log_bin_index                   |       |
| log_bin_trust_function_creators | OFF   |
| log_bin_use_v1_row_events       | OFF   |
| sql_log_bin                     | ON    |
+---------------------------------+-------+
6 rows in set (0.01 sec)

5.2开启log日志 编辑my.cnf 日志

将如下内容,添加到文件最后

#节点Id,注意集群中不能重复,单节点不配置也可以
server-id=123
#开启binlog日志,指定其存放位置
log-bin=/var/lib/mysql/mysql-bin
#开启binlog自动过期
expire_logs_days=3

5.3重启数据库mysql

systemctl restart mysqld

查看log日志是否开始成功

mysql> show variables like '%log_bin%';
+---------------------------------+--------------------------------+
| Variable_name                   | Value                          |
+---------------------------------+--------------------------------+
| log_bin                         | ON                             |
| log_bin_basename                | /var/lib/mysql/mysql-bin       |
| log_bin_index                   | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF                            |
| log_bin_use_v1_row_events       | OFF                            |
| sql_log_bin                     | ON                             |
+---------------------------------+--------------------------------+
6 rows in set (0.00 sec)

/var/lib/mysql/mysql-bin 是日志文件

/var/lib/mysql/mysql-bin.index 是索引

查看日志索引和事件位置
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      510 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql-bin是日志文件

000001是索引

pos=510是事件位置也可以叫偏移值

六、binlog命令和恢复日志

6.1 查看所有binlog日志列表

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       510 |
+------------------+-----------+
1 row in set (0.00 sec)

6.2查看master状态

即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      510 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

6.3flush刷新log日志,自此刻开始产生一个新编号的binlog日志文件

mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       510 |
+------------------+-----------+
1 row in set (0.00 sec)
​
#重置(清空)所有binlog日志
mysql> reset master;
​
# flush logs 重新记录新的bin log 日志
​

注意:每当mysqld服务重启时,会自动执行此命令,刷新binlog日志;在mysqldump备份数据时加 -F 选项也会刷新binlog日志;

6.4:使用mysqlbinlog自带查看命令法:

show binlog events in 'mysql-bin.000001'; 

6.5:通过Binlog恢复数据

/usr/bin/mysqlbinlog --database=hello /var/lib/mysql/mysql-bin.000001 | /usr/bin/mysql -uroot -p123456zy -v hello
​
/usr/bin/mysqlbinlog 为binlog命令
--database=hello 指定数据库为hello的日志
/var/lib/mysql/bin-log-1.000001 为binlog日志
​
| 为管道符
​
/usr/bin/mysql -uroot -p123456zy -v hello 连接mysql、并指定需要恢复的数据库 -v 为显示详细信息

6.6通过指定位置恢复数据

# linux命令行:
/usr/bin/mysqlbinlog --start-position=573 --stop-position=718 --database=hello /var/lib/mysql/mysql-bin.000001 | /usr/bin/mysql -uroot -p123456zy -v hello
​
--start-position=573 开始位置
--stop-position=718  结束位置
# 查看位置信息:
show binlog events in 'mysql-bin.000001'; 

6.7通过指定时间恢复数据

# linux命令行:
/usr/bin/mysqlbinlog --start-datetime="2022-07-18 10:28:18" --stop-datetime="2022-07-18 10:28:35" --database=hello /var/lib/mysql/bin-log-1.000001 | /usr/bin/mysql -uroot -p123456zy -v hello
--start-datetime="2022-07-18 10:28:18" 开始时间
--stop-datetime="2022-07-18 10:28:35" 结束时间
# 查看时间信息 linux命令行:
/usr/bin/mysqlbinlog --no-defaults /var/lib/mysql/mysql-bin.000001

7、补充

7.1应该在禁用端口的

在阿里云禁用端口。

防火墙在禁用端口

更甚者连远程访问端口都禁用他。直接使用阿里云的web登录界面,每次去那里登录。或者每次动态开启和关闭

最后: 多注意安全吧。长看看状态,做好备份。即使丢了也能很快恢复。

binlog的常见命令

2.1 查看所有binlog日志列表
mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       510 |
+------------------+-----------+
1 row in set (0.00 sec)
2.2查看master状态

即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      510 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
2.3flush刷新log日志,自此刻开始产生一个新编号的binlog日志文件
mysql> show master logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       510 |
+------------------+-----------+
1 row in set (0.00 sec)
​
#重置(清空)所有binlog日志
mysql> reset master;
​
# flush logs 重新记录新的bin log 日志
​

注意:每当mysqld服务重启时,会自动执行此命令,刷新binlog日志;在mysqldump备份数据时加 -F 选项也会刷新binlog日志;

2.4:使用mysqlbinlog自带查看命令法:
show binlog events in 'mysql-bin.000001'; 

2.5:通过Binlog恢复数据

/usr/bin/mysqlbinlog --database=hello /var/lib/mysql/mysql-bin.000001 | /usr/bin/mysql -uroot -p123456zy -v hello
​
/usr/bin/mysqlbinlog 为binlog命令
--database=hello 指定数据库为hello的日志
/var/lib/mysql/bin-log-1.000001 为binlog日志
​
| 为管道符
​
/usr/bin/mysql -uroot -p123456zy -v hello 连接mysql、并指定需要恢复的数据库 -v 为显示详细信息

2.6通过指定位置恢复数据

# linux命令行:
/usr/bin/mysqlbinlog --start-position=573 --stop-position=718 --database=hello /var/lib/mysql/mysql-bin.000001 | /usr/bin/mysql -uroot -p123456zy -v hello
​
--start-position=573 开始位置
--stop-position=718  结束位置
# 查看位置信息:
show binlog events in 'mysql-bin.000001'; 

2.7通过指定时间恢复数据

# linux命令行:
/usr/bin/mysqlbinlog --start-datetime="2022-07-18 10:28:18" --stop-datetime="2022-07-18 10:28:35" --database=hello /var/lib/mysql/bin-log-1.000001 | /usr/bin/mysql -uroot -p123456zy -v hello
--start-datetime="2022-07-18 10:28:18" 开始时间
--stop-datetime="2022-07-18 10:28:35" 结束时间
# 查看时间信息 linux命令行:
/usr/bin/mysqlbinlog --no-defaults /var/lib/mysql/mysql-bin.000001

\