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

这是我第三次在自己博客里找到致命漏洞了。第一次是一个第三方存储,解决方案是删了。第二次是"EMLOG相册",也就是这篇文章:https://www.leavesongs.com/PENETRATION/emlog-important-plugin-getshell.html。第三次就是这次,我写了一个利用脚本,直接把自己博客的整站备份文件下下来了,包括管理员密码。

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

emlog插件:自动备份并发送到邮箱_-_emlog个人博客系统_基于php的blog博客程序及CMS建站系统.png

说说漏洞成因。

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

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

<?php
$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,我们就可以计算出上次备份文件的创建时间。

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

往后看代码:

kl_auto_backup_and_mail_do_php_—_www.png

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

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

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

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

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

  1. 备份文件创建时,计算当前时间和最后文件创建好linux系统里的文件mtime不一定相等,因为中间还执行了sql语句耽误了一些时间,所以文件名的时间不一定能准确预测,但差距不会太大,一两秒而已。
  2. 利用时http传输消耗一些时间,导致我们获得的now time和服务器上获取的time()不一定相等,有一定误差。
  3. 我们的时区和网站服务器的时区不一定相等,而网站所在服务器是怎样设置时区的我们不知道,所以需要一个个尝试。

这三个不稳定的地方,导致我们的POC需要暴力跑个十几、上百次才能找到最终的备份文件,但跑的成本很低,对攻击者来说压力不大,可以接受。
KLLER自身不知道为何没有跑出文件,但我手工翻了下emlog论坛,找到了三个受害者:

1__phithon_phithon____pro_python_exp_emlog__zsh__和_截图.png

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

1__phithon_phithon____pro_python_exp_emlog__zsh__和_管理中心_-_离别歌.png

1__phithon_phithon____pro_python_exp_emlog__zsh__和_截图 2.png

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

解决方法:

  1. 暂时删除该插件
  2. 服务器/WAF对于所有后缀为.sql的请求都拦截
  3. 将$defname修改为随机字符串,如:
<?php
/*
* getRandStr是emlog自带的随机字符串生成函数,利用随机字符串即可避免此问题
*/
$defname = 'emlog_'. gmdate('Ymd', time() + $timezone * 3600) . '_' . substr(md5(getRandStr()),0,18);

赞赏

喜欢这篇文章,扫码和我成为赞友!

评论

pr0 回复

哈哈哈 看你发了好几篇关于emlog的文章 ,感觉这玩意儿就跟个定时炸弹一样

Test 回复

表示很少用插件.....在服务器写个shell不好喽

奋斗的小白 回复

exp在那?博主求分享。

天空 回复

好文章

captcha