CVE-2022–21661 WordPress核心框架WP_Query SQL注入漏洞原理分析与复现

VSole2022-01-11 15:45:41

漏洞信息

近日,WordPress官方发布了多个漏洞信息:


其中一处关于`WP_Query`的SQL注入漏洞值得关注,编号为CVE-2022–21661。

`WP_Query`是WordPress提供的一个用于处理复杂SQL查询的类,在WordPress核心框架和插件中使用范围非常广泛,用户可以通过`WP_Query`类完成数据库查询操作,方便构建WordPress的输出内容。

补丁对比

首先进行补丁对比,发现修改的文件不多,最关键的地方位于`class-wp-tax-query.php`文件的函数`clean_query`:


补丁中,对`$query['terms']`的赋值取决于`$query['field']`的取值。

触发点分析

下面分析一下`clean_query`函数:


第559行通过`array_unique`函数移除`$query['terms']`数组中的重复项后,首先进行了一个`if`判断:

if (is_taxonomy_hierarchical($query['taxonomy'])&&$query['include_children'])

可以通过控制`$query['taxonomy']`或者`$query['include_children']`的取值使得`if`判断不成立,这样就直接将`$query['terms']`带入了函数`transform_query`:

可以设置`$query['field']`的值为`term_taxonomy_id`,这样函数会直接返回,也就是说可以通过控制`$query`的取值来绕过`clean_query`函数的处理。下面查找一下`clean_query`函数被调用的情况:

只存在函数`get_sql_for_clause`这唯一的一个调用:

通过`clean_query`处理参数`$clause`的引用对象,然后赋值给`$terms`,当存在`IN`操作时,调用函数`implode`以`,`将数组`$terms`转换为字符串,继续往下走:

将`$terms`字符串拼接进入`$where`,并最终带入SQL查询语句。回顾`get_sql_for_clause`函数的处理过程,可以通过构造特殊`$query`,导致输入参数无过滤处理就直接带入SQL语句,导致出现SQL注入漏洞。

调用链分析

查找函数`get_sql_for_clause`的调用链:

可以构建一条从`WP_Query`构造函数出发,到达`get_sql_for_clause`函数的完整调用链条:

WP_Query#__construct    WP_Query#query        WP_Query#get_posts            WP_Tax_Query#get_sql                WP_Tax_Query#get_sql_clauses                    WP_Tax_Query#get_sql_for_query                        WP_Tax_Query#get_sql_for_clause

漏洞复现

通过前面分析,我们知道参数`$query`只需要满足以下2个条件,就可以触发SQL注入漏洞:

  • `$query['include_children']`取值为`false`(或者`is_taxonomy_hierarchical($query['taxonomy'])`取值为`false`);
  • `$query['field']`取值为`term_taxonomy_id`


分析WordPress核心框架本身的漏洞潜在触发点:

一共找到205处调用,但是比较遗憾的是未能在WordPress核心框架中直接找到满足漏洞触发前提条件的场景。WordPress插件数量众多,应该可以找到一些满足条件的漏洞触发点,有兴趣的小伙伴可以自行去跟踪研究。

为了方面验证漏洞,这里构建一个自定义URL页面模板。修改默认主题样式的`applications.php`,手动增加一个名为`wp_ajax_nopriv_test`的AJAX请求定义:

为了方便测试,开启DEBUG模式,然后构造请求进行发送:

修复方式

回顾前面的补丁对比,新版本`class-wp-tax-query.php`中的函数`clean_query`修改代码如下:

if ( 'slug' === $query['field'] || 'name' === $query['field'] ) {  $query['terms'] = array_unique( (array) $query['terms'] );} else {  $query['terms'] = wp_parse_id_list($query['terms']);}

通过函数`wp_parse_id_list`限制了`$query['terms']`数组元素类型必须是整数。

sql注入wordpress
本作品采用《CC 协议》,转载必须注明作者和本文链接
(20220328-20220403)
2021年9月13日-2021年9月19日 本周漏洞态势研判情况本周信息安全漏洞威胁整体评价级别为中。
2021年8月9日-2021年8月15日 本周漏洞态势研判情况本周信息安全漏洞威胁整体评价级别为中。
未经身份验证的攻击者可能利用跟踪为CVE-2021-24295的WordPress插件中的“基于垃圾邮件保护,AntiSpam,FireWall by CleanTalk的基于时间的盲SQL注入”来访问用户数据。CVE-2021-24295漏洞是一个高严重性问题,已被评为。此外,专家指出,插件代码具有许多功能,这使得成功执行SQL注入攻击更加困难。另一个问题与尝试防止SQL注入使用“ sanitize_text_field”函数有关,并且用户代理已包含在查询中的单引号中。此漏洞已通过版本解决,但研究人员建议将其更新为最新版本的插件。
版本:<= 4.7 测试环境:Ubuntu 18.04 CVE:CVE-2021-24750 CWE:CWE-89 描述: 4.8 之前的 WP 访问者统计(实时流量)WordPress 插件无法正确清理和转义 refDetails AJAX 操作中的 refUrl,任何经过身份验证的用户都可以使用,这可能允许角色低至订阅者的用户执行 SQL 注入攻击。 https://
CVE-2022–21661 WordPress核心框架WP_Query SQL注入漏洞原理分析与复现。
ModSecurity防火墙绕过
SQL 注入 (SQLi) 是一种可以访问敏感或私有数据的隐蔽攻击形式,它们最早是在上世纪末被发现的,尽管它们的年龄很大,但它们经常被用作黑客工具包中的一种有效技术。今天,给大家介绍一下顶级 SQLi 检测工具。 顶级 SQLi 检测工具 有很多 SQLi 检测工具,其中许多是开源的,可在 GitHub 上找到,除了专门的 SQLi 检测工具外,还有更大的套件和专有软件包将 SQLi 作为其整体
VSole
网络安全专家