IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    emlog自动备份插件泄露整站数据库备份漏洞

    没穿底裤发表于 2015-10-09 07:14:24
    love 0

    作者:phithon

    导致漏洞的是这个插件:http://www.emlog.net/plugin/14 。其id为14,也是emlog存在较早的插件了,作者是emlog大版主KLLER。

    thum-e20d1444323596[1]

    说说漏洞成因。

    这个插件是自动备份用的。它在前端放一个ajax控件,在每次用户访问时请求一次插件,插件检查一下上次备份的文件时间,如果相隔时间超过一定值,那么就再次进行备份。通过这个方法来达到“自动备份”的效果。

    看代码,kl_auto_backup_and_mail_do.php,这就是ajax请求的文件,是不限制权限的。

    $is_reproduct = false;
    echo KL_AUTO_BACKUP_AND_MAIL_THE_TIME."\n";
    if(KL_AUTO_BACKUP_AND_MAIL_LAST_BACKUP_FILE != '' && file_exists(KL_AUTO_BACKUP_AND_MAIL_LAST_BACKUP_FILE))
    {
    	$delay_time = time() - filemtime(KL_AUTO_BACKUP_AND_MAIL_LAST_BACKUP_FILE);
    	if($delay_time > intval(KL_AUTO_BACKUP_AND_MAIL_THE_TIME)) $is_reproduct = true;
    	echo $delay_time;
    }else{
    	$is_reproduct = true;
    }

     

    $is_reproduct表示是否备份,KL_AUTO_BACKUP_AND_MAIL_THE_TIME是临界时间,KL_AUTO_BACKUP_AND_MAIL_LAST_BACKUP_FILE是上次备份的文件名。

    如果KL_AUTO_BACKUP_AND_MAIL_LAST_BACKUP_FILE存在,进入if语句。判断现在时间和上次备份时间的差是否大于临界时间,如果大于则将$is_reproduct设为true。最后会输出$delay_time。

    $delay_time是个很重要的值,它代表着“当前时间”和上次备份的文件的“创建时间”之差。而“当前时间”我们是知道的,通过这里输出的$delay_time,我们就可以计算出上次备份文件的创建时间。

    这个时间很重要,后面会用到。

    往后看代码:

    thum-72ff1444325012[1]

    若$is_reproduct为true则进入if语句,并删除上一次的备份文件(严格来说是上上一次的备份文件,此处不影响后面的漏洞利用过程)。之后,它将此时的时间翻来覆去计算为一个文件名,并将所有数据库data写入了这个文件。

    归根结底,文件名是和时间戳一一对应的。那么反过来,只要知道这个文件的创建时间,那么就可以反推出文件名。

    而通过之前的分析,我们可以得出上一次创建的备份文件的创建时间,那么其实就可以推出他的文件名了。

    那么,这样就造成了一个“备份文件名可被准确计算”的漏洞,造成整站数据库备份泄露。

    但漏洞利用还是有几处不稳定的地方:

    1.备份文件创建时,计算当前时间和最后文件创建好linux系统里的文件mtime不一定相等,因为中间还执行了sql语句耽误了一些时间,所以文件名的时间不一定能准确预测,但差距不会太大,一两秒而已。

    2.利用时http传输消耗一些时间,导致我们获得的now time和服务器上获取的time()不一定相等,有一定误差。

    3.我们的时区和网站服务器的时区不一定相等,而网站所在服务器是怎样设置时区的我们不知道,所以需要一个个尝试。

    这三个不稳定的地方,导致我们的POC需要暴力跑个十几、上百次才能找到最终的备份文件,但跑的成本很低,对攻击者来说压力不大,可以接受。

    KLLER自身不知道为何没有跑出文件,但我手工翻了下emlog论坛,找到了三个受害者:

    thum-7ccb1444325947[1]

    工具跑了差不多50次,跑出了最终的备份文件:

    thum-dc3e1444325944[1]

    thum-7d6b1444325945[1]

    这个洞还属于0day漏洞,影响虽说有限,但威力巨大,一下可以拿到整站的数据库,值得关注。

    解决方法:

    1.暂时删除该插件

    2.服务器/WAF对于所有后缀为.sql的请求都拦截

    3.将$defname修改为随机字符串,如:

    /*
    * getRandStr是emlog自带的随机字符串生成函数,利用随机字符串即可避免此问题
    */
    $defname = 'emlog_'. gmdate('Ymd', time() + $timezone * 3600) . '_' . substr(md5(getRandStr()),0,18);

     


沪ICP备19023445号-2号
友情链接