某后台管理系统的审计
字数 1630 2025-08-26 22:11:28

ThinkPHP5后台管理系统安全审计报告

0x01 框架结构分析

  • 系统采用ThinkPHP5框架,版本为5.0.2
  • 默认开启debug模式,存在安全隐患
  • 数据库默认使用PDO连接
  • 已修复ThinkPHP5 RCE通用漏洞
    • 增加了白名单机制,限制了任意方法调用

0x02 Admin.php漏洞分析

任意修改管理员用户名及密码漏洞

漏洞位置admin/controller/Admin.php

漏洞原理

  1. _initialize()方法在任何方法执行前都会执行,包括构造函数
  2. 父类的_initialize()方法为空,导致该方法仅获取Session而不进行权限验证
  3. 因此可以未授权调用管理员方法

关键代码

// doUpdate方法
$user_id = input('user_id');
$data['username'] = input('username');
// 直接使用用户输入而不验证权限

SQL注入漏洞

漏洞位置doUpdate方法中的SQL语句拼接

关键代码

$is_have = Db::name('admin')->where("id != $user_id AND username = '".$data['username']."'")->value('id');

漏洞点

  1. SQL语句直接拼接用户输入,未使用PDO参数绑定
  2. $user_id未使用引号包裹
  3. input()方法默认过滤器为空,未对输入进行过滤

利用方式

  • 可直接使用sqlmap进行自动化注入测试

0x03 Index.php存储型XSS漏洞

漏洞位置api/Index.php

漏洞原理

  1. $data变量未进行任何过滤
  2. 未限制列名,但特定字段会被覆盖
  3. 可控字段:idusernametelephoneacreage
  4. 实际可利用字段:usernameacreage

0x04 Controller.php漏洞分析

任意增删改查数据表内容

漏洞位置

  • admin/controller/Admin.php
  • admin/traits/controller/Controller.php

漏洞原理

  1. index方法通过当前控制器名获取模型对象
  2. 数据库操作基于模型对象,表名默认为模型名
  3. search方法将$param数组添加到where['map']条件中
  4. 不传参数可返回全部数据

关键方法

// edit方法
if ($this->isAjax()) {
    // 处理Ajax请求
}

// isAjax方法
public function isAjax()
{
    return $this->request->param('_ajax') ? true : false;
}

利用方式

  1. 在POST请求中添加_ajax=1参数即可绕过Ajax检测
  2. allowField仅检验列名是否存在,无其他限制
  3. 非Ajax请求时,使用id作为筛选条件

POC示例

  • 查询:GET /admin/Admin/index
  • 修改:POST /admin/Admin/edit?_ajax=1
  • 增加:POST /admin/Admin/add?_ajax=1
  • 删除:POST /admin/Admin/del?_ajax=1

任意文件上传漏洞

漏洞原理

  1. 无任何文件类型过滤
  2. 直接返回上传文件路径

0x05 其他XSS漏洞

漏洞位置

  • Page.php控制器
  • Product.php控制器
  • Service.php控制器
  • Xcxaccount.php控制器

漏洞原理

  1. 这些控制器重写了父类的鉴权方法并置空
  2. 可调用Controller.php中的方法
  3. 可添加带有XSS的文本到数据库中

Base控制器分析

// 基本鉴权方法
// 但被上述控制器重写置空

总结与防御建议

漏洞总结

  1. 未授权访问:多个控制器缺乏有效鉴权
  2. SQL注入:直接拼接用户输入到SQL语句
  3. XSS漏洞:未对用户输入进行过滤
  4. 任意文件上传:无任何文件类型检查
  5. 任意数据操作:缺乏权限控制和输入验证

防御建议

  1. 权限控制

    • 实现完善的权限验证机制
    • 不要重写或置空基类的安全方法
  2. 输入处理

    • 对所有用户输入进行严格过滤
    • 使用PDO参数化查询防止SQL注入
    • 对输出内容进行HTML实体编码
  3. 文件上传

    • 限制上传文件类型
    • 检查文件内容而不仅是扩展名
    • 将上传文件存储在非web可访问目录
  4. 框架配置

    • 生产环境关闭debug模式
    • 及时更新框架到最新安全版本
  5. 安全编码

    • 遵循最小权限原则
    • 实现CSRF防护机制
    • 对敏感操作进行二次验证

本审计报告展示了该后台管理系统存在的多个高危漏洞,开发人员应按照防御建议进行全面修复,以保障系统安全。

ThinkPHP5后台管理系统安全审计报告 0x01 框架结构分析 系统采用ThinkPHP5框架,版本为5.0.2 默认开启debug模式,存在安全隐患 数据库默认使用PDO连接 已修复ThinkPHP5 RCE通用漏洞 增加了白名单机制,限制了任意方法调用 0x02 Admin.php漏洞分析 任意修改管理员用户名及密码漏洞 漏洞位置 : admin/controller/Admin.php 漏洞原理 : _initialize() 方法在任何方法执行前都会执行,包括构造函数 父类的 _initialize() 方法为空,导致该方法仅获取Session而不进行权限验证 因此可以未授权调用管理员方法 关键代码 : SQL注入漏洞 漏洞位置 : doUpdate 方法中的SQL语句拼接 关键代码 : 漏洞点 : SQL语句直接拼接用户输入,未使用PDO参数绑定 $user_id 未使用引号包裹 input() 方法默认过滤器为空,未对输入进行过滤 利用方式 : 可直接使用sqlmap进行自动化注入测试 0x03 Index.php存储型XSS漏洞 漏洞位置 : api/Index.php 漏洞原理 : $data 变量未进行任何过滤 未限制列名,但特定字段会被覆盖 可控字段: id 、 username 、 telephone 、 acreage 实际可利用字段: username 和 acreage 0x04 Controller.php漏洞分析 任意增删改查数据表内容 漏洞位置 : admin/controller/Admin.php admin/traits/controller/Controller.php 漏洞原理 : index 方法通过当前控制器名获取模型对象 数据库操作基于模型对象,表名默认为模型名 search 方法将 $param 数组添加到 where['map'] 条件中 不传参数可返回全部数据 关键方法 : 利用方式 : 在POST请求中添加 _ajax=1 参数即可绕过Ajax检测 allowField 仅检验列名是否存在,无其他限制 非Ajax请求时,使用 id 作为筛选条件 POC示例 : 查询: GET /admin/Admin/index 修改: POST /admin/Admin/edit?_ajax=1 增加: POST /admin/Admin/add?_ajax=1 删除: POST /admin/Admin/del?_ajax=1 任意文件上传漏洞 漏洞原理 : 无任何文件类型过滤 直接返回上传文件路径 0x05 其他XSS漏洞 漏洞位置 : Page.php 控制器 Product.php 控制器 Service.php 控制器 Xcxaccount.php 控制器 漏洞原理 : 这些控制器重写了父类的鉴权方法并置空 可调用 Controller.php 中的方法 可添加带有XSS的文本到数据库中 Base控制器分析 : 总结与防御建议 漏洞总结 未授权访问:多个控制器缺乏有效鉴权 SQL注入:直接拼接用户输入到SQL语句 XSS漏洞:未对用户输入进行过滤 任意文件上传:无任何文件类型检查 任意数据操作:缺乏权限控制和输入验证 防御建议 权限控制 : 实现完善的权限验证机制 不要重写或置空基类的安全方法 输入处理 : 对所有用户输入进行严格过滤 使用PDO参数化查询防止SQL注入 对输出内容进行HTML实体编码 文件上传 : 限制上传文件类型 检查文件内容而不仅是扩展名 将上传文件存储在非web可访问目录 框架配置 : 生产环境关闭debug模式 及时更新框架到最新安全版本 安全编码 : 遵循最小权限原则 实现CSRF防护机制 对敏感操作进行二次验证 本审计报告展示了该后台管理系统存在的多个高危漏洞,开发人员应按照防御建议进行全面修复,以保障系统安全。