此文章为XIUNOX版本重构审计时发现问题,XIUNOX版本已优化修复此问题。分享出来方便后续想基于xiuno bbs4.0.4版本制作维护版本或插件模板等需求的开发者和站长参考。
现象
Xiuno BBS 4.0.4 安装、卸载、升级、设置插件时,会直接 include _include(APP_PATH."plugin/$dir/install.php") 等插件自带脚本,且没有任何沙盒、签名校验、函数黑名单。插件作者可以在 install.php 中植入任意代码:删库、写马、读取 conf.php 中的数据库密码、向远程发送站点密钥。即便禁用插件,install.php 已经执行过一次,后门已落地。
源码证据
文件:xiunobbs_4.0.4/admin/route/plugin.php 第 155-175 行(安装时 include install.php)
} elseif($action == 'install') {
plugin_lock_start();
$dir = param_word(2);
plugin_check_exists($dir);
$name = $plugins[$dir]['name'];
plugin_check_dependency($dir, 'install');
plugin_install($dir);
$installfile = APP_PATH."plugin/$dir/install.php";
if(is_file($installfile)) {
include _include($installfile);
}
plugin_lock_end();
}
文件:xiunobbs_4.0.4/admin/route/plugin.php 第 203-223 行(卸载时 include unstall.php)
} elseif($action == 'unstall') {
plugin_unstall($dir);
$unstallfile = APP_PATH."plugin/$dir/unstall.php";
if(is_file($unstallfile)) {
include _include($unstallfile);
}
}
文件:xiunobbs_4.0.4/admin/route/plugin.php 第 277-310 行(升级时 include upgrade.php)
} elseif($action == 'upgrade') {
plugin_install($dir);
$upgradefile = APP_PATH."plugin/$dir/upgrade.php";
if(is_file($upgradefile)) {
include _include($upgradefile);
}
}
文件:xiunobbs_4.0.4/admin/route/plugin.php 第 317-324 行(设置页 include setting.php)
} elseif($action == 'setting') {
$dir = param_word(2);
plugin_check_exists($dir);
$name = $plugins[$dir]['name'];
include _include(APP_PATH."plugin/$dir/setting.php");
}
文件:xiunobbs_4.0.4/admin/route/plugin.php 第 388-434 行(plugin_download_unzip 直接解压到 plugin/ 目录,无签名)
function plugin_download_unzip($dir) {
global $conf;
$url = PLUGIN_OFFICIAL_URL."plugin-download-$dir-$siteid-$app_url.htm";
$s = http_get($url);
$zipfile = $conf['tmp_path'].'plugin_'.$dir.'.zip';
$destpath = APP_PATH."plugin/";
file_put_contents($zipfile, $s);
rmdir_recusive(APP_PATH."plugin/$dir/hook/", 1);
rmdir_recusive(APP_PATH."plugin/$dir/overwrite/", 1);
xn_unzip($zipfile, $destpath);
}
风险等级与结论
风险等级:严重(Critical)|生态缺陷
危害:
- 安装任意插件 = 执行任意 PHP,无沙盒、无签名、无函数黑名单。
- install.php 可读取
conf/conf.php 中的 DB 密码、auth_key,外传给攻击者。
- install.php 可写文件到
upload/、tmp/、view/,植入持久化 webshell。
- 官 方源
plugin.xiuno.com 已失效(见独立缺陷),用户被迫从第三方下载,供应链攻击面巨大。
- 即便用户事后禁用、卸载插件,install.php 已执行过的副作用(删表、改密码、写马)无法回滚。
修复建议:
- 引入插件签名机制:插件包必须附
conf.json.sig(Ed25519),plugin_download_unzip 解压后立即校验签名,不匹配则拒绝安装。
- install/unstall/upgrade/setting.php 在受限沙盒中执行:禁用
exec/system/eval/file_put_contents/unlink/mysql_query 等危险函数(通过 disable_functions ini 临时注入)。
- 限制 install.php 只能调用 BBS 提供的
plugin_install_hook() API 完成数据库变更,禁止直接 SQL。
- 安装前展示 install.php 源码摘要给管理员审阅,并扫描危险关键字(
eval、exec、file_put_contents、fopen、mysql、$_POST、$_GET、base64_decode)。
- 强制 install.php 通过
_include() 编译时附加 <?php exit; 前缀防直接访问,但执行前去除(已有此机制,但仅对 hook 生效,install.php 未应用)。