Joomla 3.9.13 二次注入分析(CVE-2019-19846)
字数 1595 2025-08-26 22:11:45

Joomla 3.9.13 二次SQL注入漏洞分析(CVE-2019-19846)教学文档

漏洞概述

本漏洞是Joomla 3.9.13版本中存在的一个需要管理员权限的二次SQL注入漏洞(CVE-2019-19846)。漏洞存在于components/com_content/models/articles.php文件中,由于对用户输入参数date_field未进行充分过滤,导致攻击者可以通过精心构造的输入执行SQL注入攻击。

漏洞分析

漏洞位置

漏洞核心代码位于components/com_content/models/articles.php文件的第458行左右:

$dateFiltering = $this->getState('filter.date_filtering', 'off');
$dateField = $this->getState('filter.date_field', 'a.created');

switch ($dateFiltering) {
    case 'range':
        $startDateRange = $db->quote($this->getState('filter.start_date_range', $nullDate));
        $endDateRange = $db->quote($this->getState('filter.end_date_range', $nullDate));
        $query->where(
            '(' . $dateField . ' >= ' . $startDateRange . ' AND ' . $dateField .
            ' <= ' . $endDateRange . ')'
        );
        break;
    // ...
}

漏洞成因

  1. date_field参数从getState('filter.date_field')获取后未经任何过滤直接拼接到SQL查询中
  2. 虽然默认值为a.created,但可以通过特定方式修改此值
  3. date_filtering设置为range时,构造的恶意SQL会被执行

利用链分析

  1. 漏洞触发点articles模型中的SQL拼接点
  2. 参数来源:通过mod_articles_popularmod_articles_category模块设置
  3. 数据流
    • 攻击者通过后台编辑模块参数
    • 恶意参数被保存到数据库的modules表中
    • 当模块被渲染时,从数据库读取参数并传递给articles模型
    • 恶意参数被拼接到SQL查询中执行

利用条件

  1. 需要超级管理员(super user)权限
  2. 需要能够编辑模块参数
  3. 由于有token校验,无法进行CSRF攻击

详细利用步骤

方法一:通过mod_articles_popular模块

  1. 以管理员身份登录系统
  2. 访问首页模块编辑界面
  3. 找到"热门文章"模块(mod_articles_popular)
  4. 修改以下参数:
    • 设置date_filteringrange
    • 设置date_field为恶意SQL代码
  5. 保存修改

方法二:通过mod_articles_category模块(更优)

  1. 以管理员身份登录系统
  2. 访问首页模块编辑界面
  3. 找到"分类文章"模块(mod_articles_category)
  4. 修改以下参数:
    • 设置date_filteringrange
    • 设置date_field为恶意SQL代码
    • 设置article_ordering1(绕过order by限制)
  5. 保存修改

注入优化

通过mod_articles_category模块可以实现更好的注入效果,因为:

  1. list.ordering参数可控,可以设置为1避免order by错误
  2. 可以实现union注入获取数据回显

补丁分析

在Joomla 3.9.14版本中修复了此漏洞,主要修改是在模块的XML配置文件中为相关字段添加了validate="options"属性:

<field name="date_field" type="list" default="a.created" label="JFIELD_DATE_FIELD_LABEL" description="JFIELD_DATE_FIELD_DESC" validate="options">
    <option value="a.created">JCREATED</option>
    <option value="a.modified">JMODIFIED</option>
    <option value="a.publish_up">JSTART_PUBLISHING</option>
    <option value="a.publish_down">JFINISH_PUBLISHING</option>
</field>

补丁原理

  1. validate="options"会触发OptionsRule验证
  2. 验证时会检查输入值是否在预定义的option列表中
  3. 如果不在列表中,则拒绝保存

验证流程:

  1. 从XML配置中读取所有合法的option值
  2. 使用in_array()array_diff()检查用户输入
  3. 只有输入值在合法列表中时才允许保存

防御建议

  1. 对所有用户输入进行严格的过滤和验证
  2. 使用参数化查询或预处理语句
  3. 遵循最小权限原则,限制管理员权限
  4. 及时更新到最新版本

总结

CVE-2019-19846是一个典型的二次SQL注入漏洞,虽然需要管理员权限才能利用,但仍然存在潜在风险。漏洞的根本原因在于对用户输入缺乏充分验证,直接将用户可控参数拼接到SQL查询中。开发者应引以为戒,对所有用户输入(包括管理员输入)都进行严格验证,并使用安全的数据库查询方式。

Joomla 3.9.13 二次SQL注入漏洞分析(CVE-2019-19846)教学文档 漏洞概述 本漏洞是Joomla 3.9.13版本中存在的一个需要管理员权限的二次SQL注入漏洞(CVE-2019-19846)。漏洞存在于 components/com_content/models/articles.php 文件中,由于对用户输入参数 date_field 未进行充分过滤,导致攻击者可以通过精心构造的输入执行SQL注入攻击。 漏洞分析 漏洞位置 漏洞核心代码位于 components/com_content/models/articles.php 文件的第458行左右: 漏洞成因 date_field 参数从 getState('filter.date_field') 获取后未经任何过滤直接拼接到SQL查询中 虽然默认值为 a.created ,但可以通过特定方式修改此值 当 date_filtering 设置为 range 时,构造的恶意SQL会被执行 利用链分析 漏洞触发点 : articles 模型中的SQL拼接点 参数来源 :通过 mod_articles_popular 或 mod_articles_category 模块设置 数据流 : 攻击者通过后台编辑模块参数 恶意参数被保存到数据库的 modules 表中 当模块被渲染时,从数据库读取参数并传递给 articles 模型 恶意参数被拼接到SQL查询中执行 利用条件 需要超级管理员(super user)权限 需要能够编辑模块参数 由于有token校验,无法进行CSRF攻击 详细利用步骤 方法一:通过mod_ articles_ popular模块 以管理员身份登录系统 访问首页模块编辑界面 找到"热门文章"模块(mod_ articles_ popular) 修改以下参数: 设置 date_filtering 为 range 设置 date_field 为恶意SQL代码 保存修改 方法二:通过mod_ articles_ category模块(更优) 以管理员身份登录系统 访问首页模块编辑界面 找到"分类文章"模块(mod_ articles_ category) 修改以下参数: 设置 date_filtering 为 range 设置 date_field 为恶意SQL代码 设置 article_ordering 为 1 (绕过order by限制) 保存修改 注入优化 通过 mod_articles_category 模块可以实现更好的注入效果,因为: list.ordering 参数可控,可以设置为 1 避免order by错误 可以实现union注入获取数据回显 补丁分析 在Joomla 3.9.14版本中修复了此漏洞,主要修改是在模块的XML配置文件中为相关字段添加了 validate="options" 属性: 补丁原理 validate="options" 会触发 OptionsRule 验证 验证时会检查输入值是否在预定义的option列表中 如果不在列表中,则拒绝保存 验证流程: 从XML配置中读取所有合法的option值 使用 in_array() 或 array_diff() 检查用户输入 只有输入值在合法列表中时才允许保存 防御建议 对所有用户输入进行严格的过滤和验证 使用参数化查询或预处理语句 遵循最小权限原则,限制管理员权限 及时更新到最新版本 总结 CVE-2019-19846是一个典型的二次SQL注入漏洞,虽然需要管理员权限才能利用,但仍然存在潜在风险。漏洞的根本原因在于对用户输入缺乏充分验证,直接将用户可控参数拼接到SQL查询中。开发者应引以为戒,对所有用户输入(包括管理员输入)都进行严格验证,并使用安全的数据库查询方式。