WordPress核心框架WP_Query - 带插件SQL注入代码审计复现(CVE-2022–21661)
复现环境
官方源码下载(wordpress 5.7.0)
环境: wampserver + php 8.0.26 + mysql 8.0.31 + apache 2.4.54.2
WordPress核心框架WP_Query - 带插件SQL注入代码审计复现(CVE-2022–21661)
漏洞描述
Wordpress是世界上使用最多的开源 CMS 之一。在允许开发者自己构建插件和主题来管理网站时,使用许多便捷功能,wordpress的核心会提供插件/主题调用和使用wordpress函数的功能,如数据格式、查询数据库等许多选项在提供的众多wordpress ma类中,在提供查询DB的WP服务器类中发现SQL Injection bug: WP_Query。
由于WP_Query中的处理不当,在某些情况下,SQL注入可能通过以某种方式使用它的插件或主题实现。这个问题在WordPress 5.8.3版本中已经修复。
受影响的旧版本也通过安全发布进行了修复,可以向前追溯到3.7.37。强烈建议启用自动更新。
此漏洞最初由GiaoHangTietKiem JSC的ngocnb和khuyn报告给 ZDI。
ngocnb’s end of 2021 twitter
youtube demo:
Demonstrating CVE-2022-21661: An Information Disclosure Bug in WordPress
风险等级
高危
影响版本
wordpress < 5.8.3 且未更新的旧版本
漏洞利用链分析
该漏洞发生在WordPress Query (WP_Query)类中。WP_Query对象用于对WordPress数据库执行自定义查询。这个对象被插件和主题用来创建自定义的帖子显示。
该漏洞发生在插件使用易受攻击类时。Elementor Custom Skin就是这样一个插件。在这里,针对WordPress 5.7.0版本和Elementor Custom Skin 插件3.1.3版本测试了该漏洞。
在这个插件中,易受攻击的WP_Query类被用在ajax-pagination.php的get_document_data方法中:
wordpress/wp-content/plugins/ele-custom-skin/includes/ajax-pagination.php
get_document_data方法在请求发送到wp-admin/admin-ajax.php时被调用,action参数是ecsload。
wordpress/wp-admin/admin-ajax.php
admin-ajax.php页面检查请求是否由经过身份验证的用户发出。如果请求来自未经身份验证的用户,则admin-ajax.php调用未经身份验证的Ajax操作。在这里,发送请求时不进行身份验证,因此调用未经过身份验证的Ajax操作,即wp_ajax_nopriv_ecsload。
搜索字符串”wp_ajax_nopriv_ecsload”会显示它是ajax-pagination.php页面中出现的hook名:
wordpress/wp-content/plugins/ele-custom-skin/includes/ajax-pagination.php
wp_ajax_nopriv_ecsload hook名指的是get_document_data回调函数。这意味着do_action方法调用get_document_data方法。
get_document_data方法创建一个WP_Query对象。WP_Query对象的初始化调用下面的get_posts方法:
wordpress/wp-includes/class-wp-query.php
回到函数clean_query,当这个改动没有做的时候,默认情况下$query[‘terms’]只会删除in的值,然后再调用到$this->transform_query( $query, ‘term_id’ );。
为了避免下降if,它$query[‘taxonomy’]需要为空或is_taxonomy_hierarchical返回false的值。
该函数transform_query将检查$query[‘field’] == $resulting_field,如果为真,则返回并且不做进一步处理,因此如果变量$query[‘field’]为term_taxonomy_id,可以退出函数而不更改变量值$query[‘terms’]。
(这里的比较是使用==并且存在Loose比较的漏洞,在某些情况下这个错误可以用来随意创建条件句)。
get_posts方法首先解析用户提供的参数。接下来,它调用get_sql方法,该方法最终调用get_sql_for_clause从用户提供的数据创建SQL语句的子句。Get_sql_for_clause子句调用clean_query来验证用户提供的字符串。但是,如果taxonomy参数为空,并且字段参数的值是字符串”term_taxonomy_id”,则该方法无法验证terms参数。terms参数的值稍后将在SQL语句中被使用。
wordpress/wp-includes/class-wp-tax-query.php
注意,get_sql()返回的sql变量被附加到sql SELECT语句中,并使用从WP_Tax_Query->get_sql()方法返回的字符串进行拼接。
稍后,在get_posts方法中,该查询由$wpdb->get_col()方法执行,从而满足SQL注入条件。
调用栈如下:
1 | WP_Query->__construct() |
主要参数$query只需要满足以下2个条件,就可以触发SQL注入漏洞:
- $query[‘include_children’]取值为false(或者is_taxonomy_hierarchical($query[‘taxonomy’])取值为false);
- $query[‘field’]取值为term_taxonomy_id
虽然这是wordpress核心的bug,但是wordpress核心的复用方式并不能触发错误,需要在特定插件和主题中联动。
WP_Query当要查询数据库时,插件/主题会调用该类,从源代码中识别bug的方法是在使用WP_Query($data)和$data是可控的。
漏洞修复
在 5.8.3 版本中,wordpress 已经修复了这个错误,查看github的提交更改可以在处理变量之前clean_query添加检查的函数中看到。
在$query[‘terms’]之前新添加了$query[‘field’]的判断
漏洞复现
环境搭建
- 本地下载wordpress 5.7.0
- 首先自己建一个数据库,供wordpress使用。
注意: 自己先建一下数据库,wordpress无权建立数据库,否则会安装不成功。
- wampserver 把wordpress放进去就可以
- 访问http://127.0.0.1/wordpress-5.7/开始安装,选择自己刚才创建的数据库即可。
- 搭建完成。登录后台的记得要注销退出,否则无法复现。
安装Elementor Custom Skin插件,在后台上传压缩包后,激活插件即可。
安装Hello Elementor Theme主题,在后台上传压缩包后,选择主题即可。
安装Elementor Website Builder插件,在后台上传压缩包后,激活插件即可。
修改配置
为了看到报错信息,可以将debug打开,如果不打开只能盲注,延时或者外带
设置断点
断点位置1
断点位置2
断点位置3
断点位置4
burp构造请求包进行报错注入
- request
1 | POST /wordpress-5.7/wp-admin/admin-ajax.php HTTP/1.1 |
- response
1 | HTTP/1.1 500 Internal Server Error |
github exp自动化利用(延时注入猜解字段)
- Wordpress-cve-CVE-2022-21661
- SSI-CVE-2022-21661
1 | python3 sploit.py http://<target-ip>/wp-admin/admin-ajax.php <payload-id> |
CVE-2022-21661
WordPress v4.1~v5.8.2 WP_Query SQL Injection POC
受影响插件分析
1 | 搜索 |
- PS:相当多的插件和主题受到该漏洞的影响(authen 和 unauthen)
总结
对WordPress网站的主动攻击通常集中在可选的插件上,而不是WordPress核心本身。
今年早些时候,当Fancy Product Designer插件中的一个bug被报告为受到主动攻击时Critical 0-day in Fancy Product Designer Under Active Attack,就出现了这种情况。
同样,Trend Micro sensors也检测到Contact Form 7插件中的文件上传漏洞正在被利用。在这种情况下,漏洞是通过插件暴露的,但存在于WordPress本身。虽然这是一个信息泄露而不是代码执行的问题,但任何暴露的数据对攻击者来说都可能是有价值的。在不久的将来,在主动攻击中看到这个错误并不会让人感到惊讶。
特别感谢GiaoHangTietKiem JSC的ngocnb和khuyenn向ZDI报告这一情况。
他们对该漏洞的原始分析SQL Injection in Wordpress core (CVE-2022–21661)。
参考资源
- CVE-2022-21661: EXPOSING DATABASE INFO VIA WORDPRESS SQL INJECTION
- WordPress Core 5.8.2 - ‘WP_Query’ SQL Injection EDB
- WordPress v4.1~v5.8.2 WP_Query SQL Injection POC
- Wordpress 5.8.2 CVE-2022-21661 Vuln enviroment
- wordpress-CVE-2022-21661
- CVE-2022-21661 exploit for Elementor custom skin
- SSI-CVE-2022-21661
- Detailed Static/Dynamic Analysis For (CVE-2022-21661)
- CVE-2022-21661
- 【漏洞复现】CVE-2022–21661 WordPress核心框架WP_Query SQL注入漏洞原理分析与复现
- CVE-2022–21661 WordPress <=5.3 携带WP_QUERY插件SQL注入
- 深度刨析 Wordpress 的 SQL 注入 (CVE-2022–21661)
- LadonExp教程CVE-2022–21661 WordPress漏洞复现
- WordPress SQL注入漏洞|CVE-2022-21661 分析与复现
- WordPress Core SQL注入漏洞(CVE-2022–21661)分析