Xiuno BBS 审计之问题03:附件上传高危风险
贰先生 6小时前

问题:附件上传仅扩展名白名单校验,含 swf/exe 危险类型且无 MIME/内容校验

此文章为XIUNOX版本重构审计时发现问题,分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。

现象

Xiuno BBS 4.0.4 附件上传 (route/attach.php) 仅依据文件名扩展名做白名单校验,既不校验 MIME 类型,也不校验文件内容(magic bytes)。更严重的是,白名单 conf/attach.conf.php 中直接包含 swfexebin 等本身具有风险的扩展名:swf 可承载 ActionScript 实现 XSS,exe/bin 可被用作恶意载荷托管。对于不在白名单的扩展名(如 php),处理方式仅为前缀加 _(变成 _php),该缓解依赖服务端解析器配置,在 Apache 多解析/IIS 路径信息泄露等场景下可能被绕过。

此外 file_ext($name, 7) 对扩展名做 7 字符截断,存在长扩展名被裁剪后意外命中白名单的边角风险。

源码证据

证据 1:上传校验仅扩展名白名单,无 MIME/内容校验 文件:xiunobbs_4.0.4/route/attach.php 行 17-47

$name = param('name');
$data = param('data', '', FALSE, FALSE);
$data = param_base64('data');
// ...
// 111.php.shtmll 
$ext = file_ext($name, 7);
$filetypes = include APP_PATH.'conf/attach.conf.php';
!in_array($ext, $filetypes['all']) AND $ext = '_'.$ext;

$tmpanme = $uid.'_'.xn_rand(15).'.'.$ext;
$tmpfile = $conf['upload_path'].'tmp/'.$tmpanme;
$tmpurl = $conf['upload_url'].'tmp/'.$tmpanme;

$filetype = attach_type($name, $filetypes);

// hook attach_create_save_before.php

file_put_contents($tmpfile, $data) OR message(-1, lang('write_to_file_failed'));

第 35-37 行:$ext = file_ext($name, 7); 取扩展名后 in_array 校验,不在白名单则 $ext = '_'.$ext。全程无 $_FILES['type']finfogetimagesize 等内容/MIME 校验。第 47 行直接 file_put_contents 落盘。

证据 2:白名单含危险扩展名 文件:xiunobbs_4.0.4/conf/attach.conf.php 行 3-6

return array (
	'all'=> array('av','wmv','wav','wma','avi','rm','rmvb','mp4', 'mp3','exe','bin','swf','fla','as','gif','jpg','jpeg','png','bmp','doc','xls','ppt','docx','xlsx','pptx','pdf',
		'c','cpp','cc', 'txt','tar','zip','gz','rar','7z','bz','chm','bt','torrent','ttf','font','fon'
	),

白名单 all 数组中包含 exebin(可执行文件,恶意载荷托管)、swf(Flash,可内嵌 ActionScript 实现 XSS / 跨域请求)。攻击者可直接以 .swf 后缀上传恶意 Flash 文件,在同源环境下触发 XSS。

证据 3:file_ext 扩展名截断逻辑 文件:xiunobbs_4.0.4/xiunophp/misc.func.php 行 1011-1017

function file_ext($filename, $max = 16) {
	$ext = strtolower(substr(strrchr($filename, '.'), 1));
	$ext = xn_urlencode($ext);
	strlen($ext) > $max AND $ext = substr($ext, 0, $max);
	if(!preg_match('#^\w+$#', $ext)) $ext = 'attach';
	return $ext;
}

第 1014 行:扩展名超过 $max(此处为 7)时直接 substr 截断,长扩展名被裁剪后可能产生非预期匹配。

风险等级与结论

风险等级:高危

结论:

  1. 上传校验仅基于文件名扩展名,无 MIME 类型校验、无文件内容(magic bytes)校验,攻击者可任意伪造扩展名上传。
  2. 白名单本身包含 swf/exe/bin 等危险类型,.swf 可直接用于同源 XSS,.exe/.bin 可作为恶意载荷分发入口。
  3. 非白名单扩展名仅加 _ 前缀(_php),该缓解在 Apache mod_mime 多解析、IIS CGI 路径信息、上传目录 .htaccess 失控等场景下可能失效,导致代码执行。
  4. file_ext 7 字符截断存在边角绕过风险。
  5. 修复建议:白名单移除 swf/exe/bin;引入 finfo_file/getimagesize 做内容校验;非白名单扩展名直接拒绝而非加 _ 前缀;上传目录禁止 PHP 解析(.htaccess / Nginx 配置);附件下载强制 Content-Disposition: attachment 并设 X-Content-Type-Options: nosniff
最新回复 (0)
全部楼主
返回