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

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

缺陷编号:wooyun-2013-046843

漏洞标题:PHPSHE SQL注入1(登录绕过)

相关厂商:phpshe.com

漏洞作者: xfkxfk

提交时间:2013-12-24 10:22

修复时间:2014-03-21 10:23

公开时间:2014-03-21 10:23

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

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

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-12-24: 细节已通知厂商并且等待厂商处理中
2013-12-29: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2014-02-22: 细节向核心白帽子及相关领域专家公开
2014-03-04: 细节向普通白帽子公开
2014-03-14: 细节向实习白帽子公开
2014-03-21: 细节向公众公开

简要描述:

PHPSHE SQL注入,导致任意用户登录,包括管理员。

详细说明:

/module/index/user.php第13行,判断登录时用户输入的用户名密码。

//#####################@ 用户登录 @#####################//
case 'login':
if (isset($_p_pesubmit)) {
$_p_info['user_pw'] = md5($_p_info['user_pw']);
if ($info = $db->pe_select('user', pe_dbhold($_p_info))) {//问题在这里,当这里的条件返回为true,则进入下面操作,登陆成功
$db->pe_update('user', array('user_id'=>$info['user_id']), array('user_ltime'=>time()));
$_SESSION['user_idtoken'] = md5($info['user_id'].$pe['host_root']);
$_SESSION['user_id'] = $info['user_id'];
$_SESSION['user_name'] = $info['user_name'];
//未登录时的购物车列表入库
...........
pe_success('用户登录成功!', $_g_fromto);


这里判断,如果然会的$info部位空,即查询结果返回不为空就登录成功了。
进入pe_dbhold函数,在/include/function/global.func.php文件31行:

//数据库安全
function pe_dbhold($str, $exc=array())
{
if (is_array($str)) {
foreach($str as $k => $v) {
$str[$k] = in_array($k, $exc) ? pe_dbhold($v, 'all') : pe_dbhold($v);
}
}
else {
$str = $exc == 'all' ? mysql_real_escape_string($str) : mysql_real_escape_string(htmlspecialchars($str));
}
return $str;
}


这里对我们输入的内容进行了转义。
继续看pe_select函数,在/include/class/db.class.php文件135行:

public function pe_select($table, $where = '', $field = '*')
{
//处理条件语句
$sqlwhere = $this->_dowhere($where);
return $this->sql_select("select {$field} from `".dbpre."{$table}` {$sqlwhere} limit 1");
}
//处理条件语句
protected function _dowhere($where)
{
if (is_array($where)) {
foreach ($where as $k => $v) {
if (is_array($v)) {
$where_arr[] = "`{$k}` in('".implode("','", $v)."')";
}
else {
in_array($k, array('order by', 'group by')) ? ($sqlby = " {$k} {$v}") : ($where_arr[] = "`{$k}` = '{$v}'");
}
}
$sqlwhere = is_array($where_arr) ? 'where '.implode($where_arr, ' and ').$sqlby : $sqlby;
}
else {
$where && $sqlwhere = (stripos(trim($where), 'order by') === 0 or stripos(trim($where), 'group by') === 0) ? "{$where}" : "where 1 {$where}";
}
return $sqlwhere;
}


这里对我们输入的内容进行了处理,因为输入的是键值对,对键值$k用反引号`括起来了,
然后带入sql语句进行查询。
问题就出在这个里的反引号。
因为在pe_dbhold函数中,对用户输入的内容进行转义,但是这里的转义是不会转义反引号的,而且这里的$k,也就是键值,我们是可控的,所以我们的反引号是可以带入sql语句的。
次漏洞,在后台管理员登录时同样存在,具体利用见漏洞证明。

漏洞证明:

1、正常的用户登录输入内容,及数据库执行语句如下图:

5.png


这里的$k就是post_data里面的user_name字段,再进入sql语句时,加上了反引号。
再来看看我们构造的输入,及数据库执行语句如下图:

6.png


没有被过滤,成功带入数据库执行。
而这条语句在数据库中执行的返回为非空,正好符合user.php中的判断,成功登陆了。

7.png


2、目前通杀。那官方的经典案例演示一下:

11.png


找到后台:

12.png


随便输入一个用户名密码,然后抓包,修改数据:

13.png


从返回的数据,及跳转的地址可以看出,已经登陆成功了。

14.png


3、后台登陆绕过利用方法
在前台会员登录时,抓包,修改如下:

9.png


在后台登陆管理员时,抓包,修改如下:

10.png


本来这里是admin_name,但是admin_name带入数据库查询返回为空,修改为admin_id返回为非空,成功绕过登陆后台。

修复方案:

过滤。
修改逻辑。

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


漏洞回应

厂商回应:

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

忽略时间:2014-03-21 10:23

厂商回复:

最新状态:

2014-05-19:感谢@xfkxfk 提供代码审计,sql注入漏洞已修复!