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

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

缺陷编号:wooyun-2015-092061

漏洞标题:hdcms 任意文件包含漏洞

相关厂商:HDPHP

漏洞作者: 路人甲

提交时间:2015-01-16 19:21

修复时间:2015-04-16 19:22

公开时间:2015-04-16 19:22

漏洞类型:文件包含

危害等级:低

自评Rank:5

漏洞状态:未联系到厂商或者厂商积极忽略

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-01-16: 积极联系厂商并且等待厂商认领中,细节不对外公开
2015-04-16: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

案例
[CMS案例] 四平市教育学院 浏览:595 12-19
[CMS案例] 四川天锐科技有限公司 浏览:328 12-19
[CMS案例] 武汉高能激光设备制造有限公司 浏览:141 12-19
[CMS案例] 四川智诚永信电子工程有限公司 浏览:124 12-19
[CMS案例] 十环大数据 浏览:159 12-19
[CMS案例] 广东陈村花卉世界有限公司 浏览:145 12-19
[CMS案例] 北京合悦达科技有限公司 浏览:96 12-19
[CMS案例] 北京合悦达科技有限公司 浏览:89 12-19
[CMS案例] 包头启博科技 浏览:137 12-19
[CMS案例] 成都市百芬百美容有限公司 浏览:73 12-19
[框架案例] hdphp真强悍 浏览:178 12-19
[CMS案例] 俯瞰航拍科技 浏览:279 12-16
[CMS案例] 锦庐艺术馆 浏览:217 12-16
[CMS案例] 武汉高能激光设备制造有限公司 浏览:183 12-16
[CMS案例] 乐左网-致力做最全的分享平台,最优的技术博客 浏览:235 12-16
[CMS案例] 昆明婚庆公司 浏览:247 12-16

详细说明:

整个程序是thinkphp的改版

/**
* 初始化应用
*/
static public function init()
{
//加载应用配置
is_file(APP_CONFIG_PATH . 'config.php') and C(require(APP_CONFIG_PATH . 'config.php'));
is_file(APP_LANGUAGE_PATH . C('LANGUAGE') . '.php') and L(require APP_LANGUAGE_PATH . C('LANGUAGE') . '.php');
//解析路由
Route::parseUrl();


首先是初始化应用,里面包含一个路由解析Route::parseUrl();

static public function parseUrl()
{
//请求内容
if (C('URL_TYPE') == 3 && isset($_GET[C("PATHINFO_VAR")])) {
$query = $_GET[C("PATHINFO_VAR")];
} else if (C('URL_TYPE') == 1 && isset($_SERVER['PATH_INFO'])) {
$query = $_SERVER['PATH_INFO'];
} else if (isset($_SERVER['PATH_INFO'])) {
$query = $_SERVER['PATH_INFO'];
} else {
$query = $_SERVER['QUERY_STRING'];
}
//分析路由 && 清除伪静态后缀
$url = self::parseRoute($query);
//拆分后的GET变量
$gets = '';
if ((C('URL_TYPE') == 1 && isset($_SERVER['PATH_INFO'])) || (C('URL_TYPE') == 3 && isset($_GET[C("PATHINFO_VAR")]))) {
$url = str_replace(array('&', '='), C("PATHINFO_DLI"), $url);
$args = explode(C("PATHINFO_DLI"), $url);
//模块
if (empty($args[0])) {
$_GET[C("VAR_MODULE")] = C("DEFAULT_MODULE");
} else {
if ($args[0] == C("VAR_MODULE")) {
$_GET[$args[0]] = $args[1];
array_shift($args);
array_shift($args);
} else {
$_GET[C("VAR_MODULE")] = $args[0];
array_shift($args);
}
}
//控制器
if (empty($args[0])) {
$_GET[C('VAR_CONTROLLER')] = C('DEFAULT_CONTROLLER');
} else {
if ($args[0] == C('VAR_CONTROLLER')) {
$_GET[$args[0]] = $args[1];
array_shift($args);
array_shift($args);
} else {
$_GET[C('VAR_CONTROLLER')] = $args[0];
array_shift($args);
}
}
//动作
if (empty($args[0])) {
$_GET[C('VAR_ACTION')] = C('DEFAULT_ACTION');
} else {
if ($args[0] == C('VAR_ACTION')) {
$_GET[$args[0]] = $args[1];
array_shift($args);
array_shift($args);
} else {
$_GET[C('VAR_ACTION')] = $args[0];
array_shift($args);
}
}
//其他$_GET数据
if (!empty($args[0]) && count($args) % 2 == 0) {
$count = count($args);
for ($i = 0; $i < $count;) {
$_GET[$args [$i]] = isset($args [$i + 1]) ? $args [$i + 1] : '';
$i += 2;
}
}
} else {
//解析URL
parse_str($url, $gets);
$_GET = array_merge($_GET, $gets);
//模块
if (!isset($_GET[C("VAR_MODULE")])) {
$_GET[C("VAR_MODULE")] = C("DEFAULT_MODULE");
}
//控制器
if (!isset($_GET[C("VAR_CONTROLLER")])) {
$_GET[C('VAR_CONTROLLER')] = C('DEFAULT_CONTROLLER');
}
//动作方法
if (!isset($_GET[C("VAR_ACTION")])) {
$_GET[C('VAR_ACTION')] = C('DEFAULT_ACTION');
}
}
//转模块名大小写
$_GET[C('VAR_MODULE')] = ucwords($_GET[C('VAR_MODULE')]);
//以下划线分隔的模块名称改为pascal命名如hdphp_user=>HDPhpUser
$_GET[C('VAR_CONTROLLER')] = str_replace('!', '', ucwords(str_replace('_', '!', $_GET[C('VAR_CONTROLLER')])));
//兼容模式删除其变量
if (C('URL_TYPE') == 2) {
unset($_GET[C('PATHINFO_VAR')]);
}
$_REQUEST = array_merge($_REQUEST, $_GET);
//设置常量
self::setConst();
}


这里$_GET[C("VAR_MODULE")] 就是module值,$_GET[C('VAR_CONTROLLER')] 是controller值,$_GET[C('VAR_ACTION')]就是action值。最后调用了一个serconst方法

/**
* 设置常量
*/
static private function setConst()
{
。。。。。。
//应用
defined('APP') or define('APP', basename(APP_PATH));
//模块
defined('MODULE') or define("MODULE", ucfirst($_GET[C('VAR_MODULE')]));
//控制器
defined('CONTROLLER') or define("CONTROLLER", ucfirst($_GET[C('VAR_CONTROLLER')]));
//方法
defined('ACTION') or define("ACTION", $_GET[C('VAR_ACTION')]);
。。。。。。。。
}


这里面定义了MODULE,CONTROLLER,ACTION。 到这里为止,MODULE,CONTROLLER,ACTION都没有任何过滤。
在继续看init方法中后面部分:

if(!defined('MODULE_PATH')){
if(empty($_GET[C('VAR_GROUP')])){
//普通模块
define('MODULE_PATH',APP_PATH.MODULE.'/');
}else if($_GET[C('VAR_GROUP')]=='Addon'){
//插件模块
define('MODULE_PATH',APP_ADDON_PATH.MODULE.'/');
}else{
//根据应用组目录识别模块
define('MODULE_PATH',APP_PATH.$_GET[C('VAR_GROUP')].'/'.MODULE.'/');
}
}
defined('MODULE_CONTROLLER_PATH') or define('MODULE_CONTROLLER_PATH', MODULE_PATH . 'Controller/');
defined('MODULE_MODEL_PATH') or define('MODULE_MODEL_PATH', MODULE_PATH . 'Model/');
defined('MODULE_CONFIG_PATH') or define('MODULE_CONFIG_PATH', MODULE_PATH . 'Config/');
defined('MODULE_HOOK_PATH') or define('MODULE_HOOK_PATH', MODULE_PATH . 'Hook/');
defined('MODULE_LANGUAGE_PATH') or define('MODULE_LANGUAGE_PATH', MODULE_PATH . 'Language/');
defined('MODULE_TAG_PATH') or define('MODULE_TAG_PATH', MODULE_PATH . 'Tag/');
defined('MODULE_LIB_PATH') or define('MODULE_LIB_PATH', MODULE_PATH . 'Lib/');
//应用配置
is_file(MODULE_CONFIG_PATH . 'config.php') and C(require(MODULE_CONFIG_PATH . 'config.php'));
is_file(MODULE_LANGUAGE_PATH . C('LANGUAGE') . '.php') and L(require MODULE_LANGUAGE_PATH . C('LANGUAGE') . '.php');


首先定义了modulepath :
define('MODULE_PATH',APP_PATH.$_GET[C('VAR_GROUP')].'/'.MODULE.'/');
这样MODULE_PATH可以被控制了,再看后面的define操作:
define('MODULE_CONFIG_PATH', MODULE_PATH . 'Config/');
is_file(MODULE_CONFIG_PATH . 'config.php') and C(require(MODULE_CONFIG_PATH . 'config.php'));
这里require(MODULE_CONFIG_PATH . 'config.php') 就可以被直接利用实现文件包含
poc:index.php?m=../test.jpg%00

BaiduHi_2015-1-15_16-20-44.png

漏洞证明:

poc:index.php?m=../test.jpg%00

BaiduHi_2015-1-15_16-20-44.png

修复方案:

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

未能联系到厂商或者厂商积极拒绝