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

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

缺陷编号:wooyun-2014-086968

漏洞标题:ThinkPHP补丁修复不当导致SQL注入

相关厂商:ThinkPHP

漏洞作者: phith0n

提交时间:2014-12-12 21:24

修复时间:2015-01-18 21:26

公开时间:2015-01-18 21:26

漏洞类型:设计错误/逻辑缺陷

危害等级:高

自评Rank:12

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

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-12-12: 细节已通知厂商并且等待厂商处理中
2014-12-13: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2015-02-06: 细节向核心白帽子及相关领域专家公开
2015-02-16: 细节向普通白帽子公开
2015-02-26: 细节向实习白帽子公开
2015-01-18: 细节向公众公开

简要描述:

放学回寝室,发现大家都在吐槽这个补丁。
这补丁我也是看醉了。逻辑有问题啊。。

详细说明:

这是ThinkPHP对这次注入的补丁:https://github.com/liu21st/thinkphp/commit/23c6e130ce75f2132e5b48699363a75ed28e15b2

}elseif(is_array($val) && isset($_REQUEST[$key]) && is_array($_REQUEST[$key])){
$options['where'][$key] = (string)$val;


这逻辑……
简单说一下他的逻辑:$key是数据库字段名字,$val是我传入的参数。
当$val是一个数组,而且$_REQUEST[$key]存在并且$_REQUEST[$key]是一个数组,则强制将我传入的参数$val转换成字符串。
可是,$_REQUEST[$key]和我传入的$val有直接关系吗?
例如

$map['username'] = $_POST['name'];
M('user')->where($map)->find();


这时候$key是username,但实际我传入的是$_POST['name'],是name。thinkphp的开发者是不是把两个“key”给弄混了?是被我找的onethink的例子误导了吗?
我就不找实例了,举个简单例子吧。
如果代码这样写(POST中的key和数据库的key相同,都是uname)

public function test()
{

$u = M('user')->where(array(
'uname' => I('post.uname', '', 'trim')
))->find();
dump($u);
}


按这个确实可以防御,可见:

01.jpg


不过如果两个key不一样:

public function test()
{

$u = M('user')->where(array(
'uname' => I('post.name', '', 'trim')
))->find();
dump($u);
}


继续注入啊:

02.jpg

漏洞证明:

见详情。。。

修复方案:

我自己也没想好。。。

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


漏洞回应

厂商回应:

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

忽略时间:2015-01-18 21:26

厂商回复:

感谢作者,不过鉴于还是前面一个漏洞的补遗,就不再重复确认了。参考前面漏洞的说明和更新~ 官方会更新漏洞补丁

漏洞Rank:10 (WooYun评价)

最新状态:

暂无