Redis 学习
基础知识
端口号:6379sentinel.conf 端口号:26379官网:https://redis.io/docs/getting-started/installation/install-redis-on-windows/
Kali 安装 redis
# 卸载 apt-get purge --auto-remove redis-server # 安装 apt install gcc make wget http://download.redis.io/releases/redis-3.2.0.tar.gz tar -zxvf redis-3.2.0.tar.gz rm redis-3.2.0.tar.gz cd redis-3.2.0/ make # 配置 vim redis.conf bind 127.0.0.1 # 注释这行语句,代表任意机器都可以登录 redis protected-mode # 设为 no,代表关闭安全设置 cp redis.conf ./src/redis.conf ./src/redis-server redis.conf # 启动redis-server export PATH=/root/Desktop/redis-3.2.0/src:$PATH # 添加环境变量 netstat -ntulp # 检查服务Ubuntu for Windows 安装 redis
apt-add-repository ppa:redislabs/redis apt-get update apt-get upgrade apt-get install redis-server service redis-server start # 测试 redis-cli 127.0.0.1:6379> ping PONG连接 Redis 服务器
# 交互式方式 redis-cli -h <host> -p <port> # 命令方式 redis-cli -h <host> -p <port> <command>常见命令
# 查看信息 info # 删除所有数据库内容 flushall # 刷新数据库 flushdb # 查看所有键,使用 select num 可以查看键值数据 keys * # 设置变量 set test "who am i" # 设置路径等配置 config set dir dirpath # 获取路径及数据配置信息 config get dir/dbfilename # 保存 save # 变量,查看变量名称 get
Redis未授权访问
未授权访问原因
配置登录策略导致任意机器都可以登录 redis
未设置密码或者设置弱口令
测试
写入文件getshell
利用条件:
未授权访问或密码已知
服务器开启 WEB 服务且 WEB 目录路径已知
写入 webshell
检查 webshell
kali 开启 apache
测试:在浏览器中访问 <redis 服务器IP>:8080/shell.php,成功回显 phpinfo 后用蚁剑进行连接
写入SSH公钥远程连接
利用条件:
redis 以 root 身份运行
未授权访问或密码已知
服务器开放 SSH 服务且允许密钥登录
redis 服务器开启 ssh 服务
修改 redis 服务器密码
攻击机生成 ssh-rsa 密匙
将攻击机的 ssh 密钥写入到 redis 服务器的内存
redis 服务器将内存中的 ssh 密钥导出文件到磁盘(本质是更改 redis 的备份路径)
攻击机登录 redis 服务器的 ssh
计划任务反弹shell
利用条件:
redis 以 root 身份运行
未授权访问或密码已知
攻击端开启监听
写入一句话
或者
主从复制RCE
利用条件:
未授权访问或密码已知
Redis <= 5.0.5
测试版本:
redis-4.0.0.tar.gz原理:
未授权的 redis 会导致 getshell,而这种方式是通过写文件来完成 getshell 的,这种方式的主要问题在于,redis 保存的数据并不是简单的 json 或者是 csv,所以写入的文件都会有大量的无用数据,利用 crontab、ssh key、webshell 这样的文件都有一定容错性,再加上 crontab 和 ssh 服务可以说是服务器的标准的服务,所以在以前,这种通过写入文件的 getshell 方式基本就可以说是很通杀了。
但随着现代的服务部署方式的不断发展,组件化成了不可逃避的大趋势,docker 就是这股风潮下的产物之一,而在这种部署模式下,一个单一的容器中不会有除 redis 以外的任何服务存在,包括 ssh 和 crontab,再加上权限的严格控制,只靠写文件就很难再 getshell 了,在这种情况下,我们就需要其他的利用手段了。
在
Redis 4.x、5.x版本中,提供了主从模式,主从模式指使用一个 redis 作为主机,其他的作为备份机,主机从机数据都是一样的,从机只负责读,主机只负责写。在
Reids 4.x之后,通过外部拓展,可以在 redis 中实现一个新的 redis 命令,构造恶意 .so 文件。在两个 redis 实例设置主从模式的时候,redis 的主机实例可以通过 FULLRESYNC 同步文件到从机上,然后在从机上加载恶意 .so 文件,即可执行命令。
简单的说,攻击者(主机)写一个so文件,然后通过 FULLRESYNC(全局)同步文件到受害人(从机)上。
EXP下载:
注意:目标靶机是不能开启保护模式
反弹shell
本地Redis主从复制RCE或反弹shell
测试版本:
redis-4.0.0.tar.gz原理:
上述的原理是,目标机器的 redis 可以被远程其他的机器登录。然后执行脚本内写死的一些命令,利用这些命令我们就可以执行系统命令。
问题来了,假如目标机器仅仅允许本地进行登录的时候,上述利用就直接暴毙。
这个时候,我们可以通过配合其他漏洞,从目标本地登录 redis。
然后手动执行脚本内写死的一些命令(这些命令的意思是将本机(靶机)redis 作为从机,将攻击机器设置为主机,然后攻击机会自动将一些恶意 so 文件同步给目标机器(从机)),从而来实现对目标机器的远程命令执行。
EXP下载:
将
redis-rogue-server/的 exp.so 文件复制到Awsome-Redis-Rogue-Server/文件夹中使用,因为 exp.so 带 system 模块攻击机配置 Redis 主从同步
反弹shell
关闭主从同步
通过SSRF反弹shell
知识拓展
RESP协议
定义:
redis 客户端与服务端通信,使用 RESP(Redis Serialization Protocal,redis 序列化协议)协议通信,该协议是专门为 redis 设计的通信协议,但也可以用于其它
客户端-服务器通信的场景。RESP 可以用于序列化不同的数据类型,客户端发送请求时,以字符串数组作为待执行命令的参数。
在 Redis 中,协议数据分为不同的类型,每种类型的数据均以 CRLF(\r\n 换行符)结束,通过数据的首字符区分类型。
RESP 协议支持的数据类型:
内联命令(inline command):这类数据表示 Redis 命令,首字符为 Redis 命令的字符,格式为str1 str2 str3 …。如:exists key1, 命令和参数以空格分隔。简单字符串(Simple Strings):首字符为+,后续字符为 string 的内容,且该 string 不能包含 或者 两个字符,最后以\r结束。如:+OK\r,表示OK这个 string 数据。批量字符串(Bulk Strings):bulk string首字符为$,紧跟着的是 string 数据的长度,\r后面是内容本身(包含 、 等特殊字符),最后以\r结束。如:$12\r\nhello\r\nworld\r上面字节串描述了
hello\r\nworld的内容(中间有个换行)。对于" "空串和null,通过$之后的数字进行区分:$0\r\n\r表示空串;$-1\r表示null。
整数(Integers):以:开头,后面跟着整型内容,最后以\r结尾。如::13\r,表示13的整数。数组(Arrays):以
*开头,紧跟着数组的长度,\r之后是每个元素的序列化数据。如:*2\r\n+abc\r\n:9\r表示一个长度为2的数组:["abc", 9]。数组长度为0或-1分别表示空数组或null。数组的元素本身也可以是数组,多级数组是树状结构,采用先序遍历的方式序列化。如:
[[1, 2], ["abc"]],序列化为:*2\r\n*2\r\n:1\r\n:2\r\n*1\r\n+abc\r。
错误数据(Errors)
Gopher协议
定义:在 http 出现之前,访问网页需要输入的是
gopher://gopher.baidu.com/,而不是https://www.baidu.com/,而它被代替的原因一方面是收费,另一方面的原因是它固化的结构没有 HTML 网页灵活。gopher 协议支持 GET&POST 请求,常用于攻击内网 ftp、redis、telnet、smtp 等服务,还可以利用 gopher 协议访问 redis 反弹 shell协议格式:
gopher://<IP>:<port>/_<TCP/IP数据流>,<port>默认为70协议的实现:gopher 会将后面的数据部分发送给相应的端口,这些数据可以是字符串,也可以是其他的数据请求包,比如 GET、POST 请求,redis,mysql 未授权访问等,同时数据部分必须要进行 url 编码,这样 gopher 协议才能正确解析。
支持 gopher 协议的有 curl 和 libcurl
gopher 语句生成工具:https://github.com/tarunkant/Gopherus
在线靶场:https://buuoj.cn/
漏洞复现
目标靶机:
get.php攻击机 nc 监听
攻击机执行脚本
Redis全防护
Redis 的安全设置(设置完后需要重加载配置文件启动 redis)
绑定内网 IP 地址进行访问
requirepass 设置 redis 密码
开启保护模式 protected-mode(默认开启)
修改默认端口
单独为 redis 设置一个普通账号以低权限运行 Redis 服务
禁止一些高危命令
禁止外网访问 Redis
设置防火墙策略
保证 authorized_keys 文件的安全
Last updated