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

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

缺陷编号:wooyun-2014-062266

漏洞标题:WeCenter社交化问答社区有趣的逻辑性sql注入漏洞(冗余安全机制造成的风险)

相关厂商:www.wecenter.com

漏洞作者: 寂寞的瘦子

提交时间:2014-05-28 19:53

修复时间:2014-08-26 19:54

公开时间:2014-08-26 19:54

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:10

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-05-28: 细节已通知厂商并且等待厂商处理中
2014-05-29: 厂商已经确认,细节仅向厂商公开
2014-06-01: 细节向第三方安全合作伙伴开放
2014-07-23: 细节向核心白帽子及相关领域专家公开
2014-08-02: 细节向普通白帽子公开
2014-08-12: 细节向实习白帽子公开
2014-08-26: 细节向公众公开

简要描述:

感觉这个漏洞有点意思~~,绕了我半天。
PS:开不开gpc无所谓的

详细说明:

在/system/init.php的59行

if (function_exists('get_magic_quotes_gpc'))
{
if (@get_magic_quotes_gpc()) // GPC 进行反向处理
{
if (! function_exists('stripslashes_gpc'))
{
function stripslashes_gpc(&$value)
{
$value = stripslashes($value);
}
}


如果你服务器开了gpc我就使用stripslashes,就是说初始进入的数据都是没有转义的。很好,适应将来嘛(因为php6已经移除这个get_magic_quotes_gpc()函数)。
在文件/system/aws_model.inc.php的978行,

public function quote($string)
{
if (is_object($this->db()))
{
//下面return有点意思的,我们去踪$this->db()->quote($string),俩个quote是不一样,不要以为是递归,不然溢出了
return trim($this->db()->quote($string), "'");
}

if (function_exists('mysql_escape_string'))
{
$string = @mysql_escape_string($string);
}
else
{
$string = addslashes($string);
}
return $string;
}


采用的是zend框架。/system/Zend/Db/Adapter/Abstract.php的859行

public function quote($value, $type = null)
{
$this->_connect();
if ($value instanceof Zend_Db_Select) {
return '(' . $value->assemble() . ')';
}
if ($value instanceof Zend_Db_Expr) {
return $value->__toString();
}
if (is_array($value)) {
foreach ($value as &$val) {
$val = $this->quote($val, $type);
}
return implode(', ', $value);
}
if ($type !== null && array_key_exists($type = strtoupper($type), $this->_numericDataTypes)) {
$quotedValue = '0';
switch ($this->_numericDataTypes[$type]) {
case Zend_Db::INT_TYPE: // 32-bit integer
$quotedValue = (string) intval($value);
break;
case Zend_Db::BIGINT_TYPE: // 64-bit integer
// ANSI SQL-style hex literals (e.g. x'[\dA-F]+')
// are not supported here, because these are string
// literals, not numeric literals.
if (preg_match('/^(
[+-]? # optional sign
(?:
0[Xx][\da-fA-F]+ # ODBC-style hexadecimal
|\d+ # decimal or octal, or MySQL ZEROFILL decimal
(?:[eE][+-]?\d+)? # optional exponent on decimals or octals
)
)/x',
(string) $value, $matches)) {
$quotedValue = $matches[1];
}
break;
case Zend_Db::FLOAT_TYPE: // float or decimal
$quotedValue = sprintf('%F', $value);
}
return $quotedValue;
}
return $this->_quote($value);
}


这里return回来的是_quote函数,看名字大概就知道了哇同一文件839行

protected function _quote($value)
{
if (is_int($value)) {
return $value;
} elseif (is_float($value)) {
return sprintf('%F', $value);
}
return "'" . addcslashes($value, "\000\n\r\\'\"\032") . "'";
}


就是进行addslashes处理。好了我们转义了一次。然后return回来到外层的quote函数,再看看这句return trim($this->db()->quote($string), "'");
主要看trim了去掉两边的',假如一开始我们输入了’,那么处理到了这里之后剩下\。哈哈,想必你也看出来了。当sql语句执行的时候\就去转义最后包含字符串的反引号了,后面带入查询的函数我就不贴了啊。
使用的是mysql预处理语句,执行的时候都是prepare和execute,和一般的还真的是不一样啊,恶补了下,还是不太懂,zend框架也没去玩过。。
这个bug真是坑爹..

漏洞证明:

官网演示下http://wenda.wecenter.com/explore/
写个私信

QQ图片20140525133211.jpg

修复方案:

版权声明:转载请注明来源 寂寞的瘦子@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:15

确认时间:2014-05-29 11:54

厂商回复:

谢谢,我们马上修正。

最新状态:

2014-05-29:经测试为 trim 删除了连续的单引号引起的错误,但是无法注入

2014-05-30:已经发布新版 http://wenda.wecenter.com/question/17683