代码审计-从0到1通读源码
字数 1210 2025-08-09 22:00:49

WodeCMS v1.1 代码审计实战教程

一、环境准备与源码结构分析

1.1 源码获取

  • 下载地址:http://zjdx.down.chinaz.com/201709/wodecms_v1.1.zip
  • 解压后目录结构分析:
    wodecms_v1.1/
    ├── admin/            # 后台管理目录
    ├── api/              # API接口目录
    ├── data/             # 数据存储目录(包含缓存、日志等)
    ├── include/          # 核心包含文件
    │   ├── common.inc.php # 全局公共函数
    │   ├── config.inc.php # 系统配置文件
    │   └── ...          # 其他核心文件
    ├── install/          # 安装程序目录
    ├── template/         # 模板文件
    └── upload/           # 上传目录
    

1.2 MVC架构分析

WodeCMS采用类MVC架构,主要流程:

  1. 用户请求 → index.php
  2. 加载核心文件 → include/common.inc.php
  3. 路由解析 → 根据参数调用对应控制器
  4. 控制器处理 → 调用模型和视图

二、核心文件审计

2.1 全局安全配置审计

include/config.inc.php 关键配置:

// 数据库配置
$dbhost = 'localhost'; 
$dbuser = 'root';
$dbpw = '123456';      // 默认密码弱
$dbname = 'wodecms';
$pconnect = 0;

// 安全配置
$authkey = 'wodecms';  // 固定密钥,存在安全隐患
$cookiepre = 'wode_';

2.2 公共函数审计

include/common.inc.php 关键函数:

输入过滤函数

function _RunMagicQuotes(&$svar) {
    if(!get_magic_quotes_gpc()) {
        if(is_array($svar)) {
            foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v);
        } else {
            $svar = addslashes($svar);
        }
    }
    return $svar;
}

问题:仅使用addslashes过滤,无法防御SQL注入

SQL查询函数

function query($sql) {
    global $db;
    $query = $db->query($sql);
    return $query;
}

问题:直接拼接SQL语句,存在注入风险

文件上传处理

function UploadFile($file, $path, $fname='', $ftype=array(), $fsize=102400) {
    // 检查文件类型
    if(!empty($ftype) && !in_array($file['type'], $ftype)) {
        return false;
    }
    // 检查文件大小
    if($file['size'] > $fsize) {
        return false;
    }
    // 保存文件
    move_uploaded_file($file['tmp_name'], $path.$fname);
    return true;
}

问题:仅检查MIME类型,未检查文件扩展名,存在上传漏洞

三、漏洞挖掘与分析

3.1 SQL注入漏洞

案例1:前台搜索注入

api/search.php 关键代码:

$keyword = $_GET['keyword'];
$sql = "SELECT * FROM `wd_article` WHERE `title` LIKE '%$keyword%'";
$query = query($sql);

漏洞点:直接拼接用户输入到SQL语句

案例2:后台SQL注入

admin/article.php 关键代码:

$id = $_GET['id'];
$sql = "DELETE FROM `wd_article` WHERE `id`=$id";
query($sql);

漏洞点:未过滤数字型参数

3.2 文件上传漏洞

案例1:前台任意文件上传

api/upload.php 关键代码:

$file = $_FILES['file'];
$path = '../upload/';
UploadFile($file, $path, $file['name']);

漏洞点:未限制文件类型和扩展名

案例2:后台模板文件上传

admin/template.php 关键代码:

$file = $_FILES['tplfile'];
$path = '../template/';
UploadFile($file, $path, $file['name'], array('text/html'));

漏洞点:仅检查MIME类型,可伪造

3.3 XSS漏洞

案例1:存储型XSS

admin/article.php 关键代码:

$content = $_POST['content'];  // 未过滤
$sql = "UPDATE `wd_article` SET `content`='$content' WHERE `id`=$id";
query($sql);

案例2:反射型XSS

api/comment.php 关键代码:

$msg = $_GET['msg'];
echo "<script>alert('$msg');</script>";

3.4 CSRF漏洞

全站缺乏CSRF防护,所有表单未添加token验证

3.5 权限绕过漏洞

admin/common.inc.php 关键代码:

if(!isset($_SESSION['adminid'])) {
    header("Location: login.php");
}

问题:仅检查session存在,未验证权限级别

四、漏洞利用与修复建议

4.1 SQL注入修复

建议方案:

// 使用预处理语句
function safe_query($sql, $params = array()) {
    global $db;
    $stmt = $db->prepare($sql);
    if($stmt) {
        if(!empty($params)) {
            $types = str_repeat('s', count($params));
            $stmt->bind_param($types, ...$params);
        }
        $stmt->execute();
        return $stmt->get_result();
    }
    return false;
}

4.2 文件上传修复

建议方案:

function UploadFile($file, $path, $fname='', $ftype=array(), $fsize=102400) {
    // 检查文件扩展名
    $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
    $allow_ext = array('jpg', 'png', 'gif');
    if(!in_array(strtolower($ext), $allow_ext)) {
        return false;
    }
    
    // 生成随机文件名
    $new_name = md5(uniqid()).'.'.$ext;
    
    // 检查文件内容
    $info = getimagesize($file['tmp_name']);
    if(!$info || !in_array($info[2], array(IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF))) {
        return false;
    }
    
    move_uploaded_file($file['tmp_name'], $path.$new_name);
    return $new_name;
}

4.3 XSS防护

建议方案:

function clean_xss($input) {
    if(is_array($input)) {
        return array_map('clean_xss', $input);
    }
    return htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
}

4.4 CSRF防护

建议方案:

// 生成token
function generate_csrf_token() {
    if(empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

// 验证token
function verify_csrf_token($token) {
    if(!empty($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token)) {
        return true;
    }
    return false;
}

五、审计总结

  1. 输入验证不足:全站缺乏统一的输入过滤机制
  2. 输出编码缺失:直接输出用户数据导致XSS
  3. SQL拼接风险:多处直接拼接SQL语句
  4. 会话管理缺陷:权限验证不严格
  5. 文件上传漏洞:类型检查不充分
  6. CSRF防护缺失:全站无防CSRF措施

六、完整审计流程建议

  1. 安装并配置调试环境
  2. 分析目录结构和核心文件
  3. 追踪用户输入流程(GET/POST/COOKIE)
  4. 检查数据库操作点
  5. 检查文件操作点
  6. 检查权限验证逻辑
  7. 检查会话管理机制
  8. 验证所有修复方案的有效性

通过本教程,您应该掌握了WodeCMS v1.1的完整代码审计方法,能够识别和修复常见的安全漏洞。

WodeCMS v1.1 代码审计实战教程 一、环境准备与源码结构分析 1.1 源码获取 下载地址:http://zjdx.down.chinaz.com/201709/wodecms_ v1.1.zip 解压后目录结构分析: 1.2 MVC架构分析 WodeCMS采用类MVC架构,主要流程: 用户请求 → index.php 加载核心文件 → include/common.inc.php 路由解析 → 根据参数调用对应控制器 控制器处理 → 调用模型和视图 二、核心文件审计 2.1 全局安全配置审计 include/config.inc.php 关键配置: 2.2 公共函数审计 include/common.inc.php 关键函数: 输入过滤函数 问题:仅使用addslashes过滤,无法防御SQL注入 SQL查询函数 问题:直接拼接SQL语句,存在注入风险 文件上传处理 问题:仅检查MIME类型,未检查文件扩展名,存在上传漏洞 三、漏洞挖掘与分析 3.1 SQL注入漏洞 案例1:前台搜索注入 api/search.php 关键代码: 漏洞点:直接拼接用户输入到SQL语句 案例2:后台SQL注入 admin/article.php 关键代码: 漏洞点:未过滤数字型参数 3.2 文件上传漏洞 案例1:前台任意文件上传 api/upload.php 关键代码: 漏洞点:未限制文件类型和扩展名 案例2:后台模板文件上传 admin/template.php 关键代码: 漏洞点:仅检查MIME类型,可伪造 3.3 XSS漏洞 案例1:存储型XSS admin/article.php 关键代码: 案例2:反射型XSS api/comment.php 关键代码: 3.4 CSRF漏洞 全站缺乏CSRF防护,所有表单未添加token验证 3.5 权限绕过漏洞 admin/common.inc.php 关键代码: 问题:仅检查session存在,未验证权限级别 四、漏洞利用与修复建议 4.1 SQL注入修复 建议方案: 4.2 文件上传修复 建议方案: 4.3 XSS防护 建议方案: 4.4 CSRF防护 建议方案: 五、审计总结 输入验证不足 :全站缺乏统一的输入过滤机制 输出编码缺失 :直接输出用户数据导致XSS SQL拼接风险 :多处直接拼接SQL语句 会话管理缺陷 :权限验证不严格 文件上传漏洞 :类型检查不充分 CSRF防护缺失 :全站无防CSRF措施 六、完整审计流程建议 安装并配置调试环境 分析目录结构和核心文件 追踪用户输入流程(GET/POST/COOKIE) 检查数据库操作点 检查文件操作点 检查权限验证逻辑 检查会话管理机制 验证所有修复方案的有效性 通过本教程,您应该掌握了WodeCMS v1.1的完整代码审计方法,能够识别和修复常见的安全漏洞。