1. LmxCMS 漏洞分析与复现

本章节主要针对 LmxCMS 的 MVC 架构特征及其存在的二次 URL 编码 SQL 注入漏洞进行分析。

1.1 MVC 路由特征识别

在对 MVC 框架进行审计时,首先需要识别其路由分发模式。LmxCMS 支持多种 URL 模式,这是构造 Payload 的基础。

  • 1.1.1 路径模式 (Path Info)
    • 结构:/index.php/content/id/1.html/index.php/content/id/1
    • 特征:参数以路径形式传递。
  • 1.1.2 参数模式 (Query String)
    • 结构:/index.php?m=list&a=index&classid=1
    • 特征:传统的 m (Module/Model) 和 a (Action) 参数传递。

1.2 双重 URL 编码注入原理

Tags 模块中,为了绕过某些过滤或满足代码逻辑,需要对 Payload 进行双重 URL 编码。

  • 1.2.1 原始攻击代码 (PoC)

    SQL

    1' and updatexml(0,concat(0x7e,user()),1)#
    
  • 1.2.2 编码流程分析

    1. 一次编码 (%27):如果仅进行一次编码,浏览器可能会将其视为合法字符发送,或者被服务器中间件(如 Apache/Nginx)自动解码,导致进入 PHP 代码时直接变为单引号 ',容易被 GPC 或 WAF 拦截。
    2. 二次编码 (%2527)
      • 客户端发送%2533%31... (对 % 再次编码为 %25)。
      • 中间件层:服务器接收请求时,进行第一次解码,%25 变回 %。此时 PHP 接收到的字符串包含 %27 (即 URL 编码后的单引号)。
      • 应用层:代码逻辑中存在自定义的解码函数或处理逻辑,对 %27 进行了第二次解码,还原为单引号 ',从而触发 SQL 注入。
  • 1.2.3 浏览器行为观测

    • 在 Burp Suite 中可以看到完整的二次编码 Payload。
    • 在浏览器地址栏输入 Payload 回车后,视觉上可能看到结尾变成 %2529%2523,这是浏览器为了用户体验进行的视觉解码,实际发出的请求包需要通过抓包确认。

1.3 代码审计追踪

通过白盒审计追踪漏洞产生的根源。

  • 1.3.1 漏洞入口
    • 文件:TagsModel.class.php
    • 方法:getNameData
    • 关键调用:return parent::oneModel($param);
  • 1.3.2 向上溯源
    • TagsAction.class.php__construct 方法中调用了 getNameData
    • 确定参数 $name 可控且未经过滤直接传入。
  • 1.3.3 向下挖掘
    • 搜索 SQL 关键字 SELECT
    • 定位 db.class.php 中的 $sql="SELECT ..." 语句,确认 $field$We (where条件) 直接拼接了变量。

2. Rockoa MVC SQL 注入审计

本章节记录 Rockoa 系统中基于 insert 操作的 SQL 注入挖掘过程。

2.1 漏洞挖掘思路

采用关键词搜索与调用链追踪相结合的方式。

  • 2.1.1 关键词定位

    • 全局搜索 insert 关键字。

    • 定位到 webmain/task/openapi/opendkqAction.php 中的 addkqjs 方法:

      PHP

      $uarr['id'] = m('kqjsn')->insert($uarr);
      
    • 确认 include/Model.php 中的 insert 方法最终执行了 SQL 语句。

  • 2.1.2 私有方法利用分析

    • 障碍addkqjs 是一个私有或受保护的方法,无法直接通过 URL 访问。
    • 突破口:寻找类内部调用 addkqjs 的位置。

2.2 调用链追踪 (Call Stack)

通过“右击用法”或全局搜索,还原完整的调用路径。

  • 2.2.1 第一层调用

    • 方法:senddata (位于 opendkqAction.php)
    • 代码:$snrs = $this->addkqjs($sn);
    • 状态:senddata 可能仍受访问控制或参数限制。
  • 2.2.2 第二层调用 (Public Entry)

    • 方法:zktimeAction (位于 opendkqAction.php)

    • 代码逻辑:

      PHP

      if(...) {
          $carr = $this->senddata(9);
      }
      
    • 结论:zktime 是对外公开的 Action,只要满足 if 条件,即可触发 senddata,进而触发 addkqjs 中的 SQL 注入。

2.3 Payload 构造

根据 MVC 的路由规则构造最终攻击 URL。

  • 2.3.1 路由格式

    • 域名:http://www.cx770.local:1572
    • 模块与动作:m=opendkq|openapi (对应文件路径 task/openapi/opendkqAction.php),a=zktime
  • 2.3.2 最终 URL 结构

    Plaintext

    /index.php?a=zktime&m=opendkq|openapi&d=task&ajaxbool=true&rnd=717830
    

    (注:具体注入参数需根据 insert 中的 $uarr 数组构造 POST 或 GET 数据)