Xiuno BBS 审计之问题08:install/index.php 中存在 SQL 注入
贰先生 4小时前

问题:install/index.php 中 CREATE DATABASE 语句直接拼接用户输入,存在 SQL 注入

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

现象

安装脚本 install/index.php 在初始化数据库时,将用户从 POST 表单提交的数据库名 $name、数据库用户 $user 等参数直接拼接进 CREATE DATABASE SQL 语句并执行。param('name') 默认只做 htmlspecialchars 处理(不会转义单引号),未做 addslashes 或预处理,攻击者可在数据库名中注入单引号及后续 SQL 语句,导致任意 SQL 执行。

安装脚本位于 install/ 目录,根据另案审计结论该目录在安装完成后并未被自动清理,且 DEBUG == 2 时跳过 conf.php 已存在的检测,意味着该注入入口在已部署站点上仍可被远程访问,构成实际可达攻击面。

源码证据

文件:xiunobbs_4.0.4/install/index.php 行 92-102(接收用户提交的数据库连接参数)

$type = param('type');	
$engine = param('engine');	
$host = param('host');	
$name = param('name');	
$user = param('user');
$password = param('password');
$force = param('force');

$adminemail = param('adminemail');
$adminuser = param('adminuser');
$adminpass = param('adminpass');

文件:xiunobbs_4.0.4/install/index.php 行 133-152(直接拼接 SQL 执行 CREATE DATABASE)

if($errno == 1049 || $errno == 1045) {
    if($type == 'mysql') {
        mysql_query("CREATE DATABASE $name");           // 直接拼接 $name
        $r = db_connect($db);
    } elseif($type == 'pdo_mysql') {
        if(strpos(':', $host) !== FALSE) {
            $arr = explode(':', $host);
            $host = $arr[0];
            $port = $arr[1];
        } else {
            //$host = $host;
            $port = 3306;
        }
        try {
            $attr = array(
                PDO::ATTR_TIMEOUT => 5,
            );
            $link = new PDO("mysql:host=$host;port=$port", $user, $password, $attr);
            $r = $link->exec("CREATE DATABASE `$name`");   // 直接拼接 $name
            // ...

文件:xiunobbs_4.0.4/xiunophp/misc.func.php 行 73-84(param 默认仅做 htmlspecialchars,不转义单引号)

function param($key, $defval = '', $htmlspecialchars = TRUE, $addslashes = FALSE) {
    if(!isset($_REQUEST[$key]) || ($key === 0 && empty($_REQUEST[$key]))) {
        // ...
    }
    $val = $_REQUEST[$key];
    $val = param_force($val, $defval, $htmlspecialchars, $addslashes);
    return $val;
}

文件:xiunobbs_4.0.4/install/index.php 行 29(已安装检测在 DEBUG==2 时被绕过)

is_file(APP_PATH.'conf/conf.php') AND DEBUG != 2 AND message(0, jump(lang('installed_tips'), '../'));

文件:xiunobbs_4.0.4/install/index.php 行 3(DEBUG 在本文件内被硬编码为 2)

define('DEBUG', 2);

风险等级与结论

高危

危害后果:

  • 攻击者构造 name=x'; SELECT ...; --  name=x; DROP DATABASE bbs; --` 形式的数据库名,可在安装请求中执行任意 SQL,包括创建恶意表、写入 webshell 到文件、提权到数据库 root 等。
  • 由于 install/index.php 自身 define('DEBUG', 2),绕过了已安装检测,使得即使站点已完成安装,该注入入口依旧可达。
  • 攻击者无需任何鉴权即可访问 install/index.php,配合上一条等于无门槛 RCE 入口。

修复建议:

  1. install/index.php 接收的 $name$user$host$port 等参数需用白名单正则 ^[a-zA-Z0-9_\-\.]+$ 严格校验后再拼接。
  2. CREATE DATABASE 语句改为 PDO prepare:$link->prepare("CREATE DATABASE \?`")->execute([$name])`(注意 PDO 对 DDL 支持有限,更稳妥是白名单校验)。
  3. 安装脚本完成后强制删除 install/ 目录或写入 .lock 文件,所有请求检测到锁文件即 exit('Access Denied')
  4. 移除 define('DEBUG', 2) 与已安装检测中 DEBUG != 2 的旁路条件,安装完成后无条件拒绝访问。
  5. 安装脚本独立鉴权(如安装令牌),禁止任意匿名访问。
最新回复 (0)
全部楼主
返回