前言
网上目前的很多文章已经总结了redis的利用方式,但是并没有详细解释利用原理和可能出现的问题,在利用时经常遇到一些意想不到的坑,这里主要总结常见的redis攻击方式,以及对网上一些利用工具的研究和改良
redis的getshell方式主要有三种:
- 写文件
- 主从复制
- lua rce
lua rce仅适用3.x以下的版本,且公开内容不多,暂时跳过,主要分析写文件和主从复制。
写文件
写文件常见的方式有:
- 写定时任务
- 写ssh公钥
- 写webshell
这三种思路利用原理完全一致,都是利用redis的持久化机制来写文件
由于redis一般将数据保存在内存中,因此redis提供了RDB和AOF两种持久化机制,防止数据丢失。
redis默认开启rdb持久化机制,即在指定的时间间隔内(也可通过save或bgsave命令触发)将内存中数据以快照方式写入到磁盘上的某个文件中。
命令行中可通过
config set dir xxx
和config set dbfilename xxx
来设置该文件位置。配置文件中可通过dir xxx和dbfilename xxx进行配置。
简单来说向redis中写入数据后再备份,写入的数据会保存到备份文件中,由于备份路径和名字可以任意设置,所以可以向任意位置写入文件。
写入命令如下:
flushall
config set dir {写入的路径}
config set dbfilename {文件名}
set xx "\n\n\n\n {要写入的内容} \n\n\n\n"
save
ps:
-
flushall
问题: 部分文章说写文件第一步要flushall 清空数据库,这个其实不是必要条件,清空的目的是防止数据库文件过大造成在执行这个文件的时候出现异常,如果redis数据不是特别多,其实可以不清空的,不清空的好处是将dir和dbfilename改回去,删除xx键 即可清理入侵痕迹,且不会对目标环境造成影响 - 写入的内容是附带垃圾数据的,所以不适用一些容错性较低的环境,例如在windows环境中只适用写入webshell
- 写入webshell需要知道web路径
- 写入的文件是覆盖写入的,在使用时要考虑覆盖的文件会不会对业务造成影响
- 写入文件的权限 可能由于权限问题无法执行
主从复制
redis为了避免单点故障造成的数据丢失,提供了主从同步功能。
主从同步可实现当一台主数据库中的数据更新后,自动将更新的数据同步到其他从数据库上。
命令格式:
slaveof {host} {port}
通过伪造redis主节点,在目标redis上执行slaveof命令,即可将文件复制到redis服务器上。
主从复制的优点是可以无损写入文件,缺点是必定会清空数据库。所有redis版本都支持主从复制功能
在redis4.x以上版本增加了可扩展module,让用户可以自己根据需求自己扩展redis相关的功能,因此可以加载命令执行模块,使redis直接具有命令执行的功能。
利用工具:
RedisWriteFile:https://github.com/r35tart/RedisWriteFile
ps:
1.写入文件内容太少会报错,可能导致redis服务挂掉
2.测试时发现在利用RedisWriteFile向redis6.2.5写入时会卡住
用nc查看redis的主从复制执行流程:
测试redis6.x流程中多一个回车换行,会导致利用RedisWriteFile脚本无法正常写入
可在脚本上增加个回车换行解决这个问题
利用主从复制命令执行
原理:
- 利用主从复制无损写文件的特点将具有命令执行的模块上传到redis服务器
- redis加载该模块即可执行命令
工具:
redis-rce: https://github.com/Ridter/redis-rce
ps:
- redis6.x以上会提示权限不足
windows下利用主从复制的一些思路
- 写入启动项
- 覆盖劫持DLL文件,快捷方式等
- mof
- …
详细可参考 https://www.redhatzone.com/ask/article/2078.html
工具及改良
xpocsuite3脚本
info模式:
attack模式:
设置了3个必填参数:filepath
、filename
、filecontent
分别为写入路径,写入地址,写入内容
1个可选参数:flushall
可选择True
和False
,用来确定是否清空数据,默认不清空
RedisWriteFile
修复复制结束后未恢复dir的bug
redis-rce
测试时发现这个加载失败挺多的,可能和编译的exp.so有关,暂时未解决,故增加错误检测,发现未加载成功时直接退出