WP Statistics 是一个非常强大的统计分析插件,通过这个插件用户可以比较详细地了解到访问网站的运行信息,比如访问量、来源、阅读量等。该插件13.1.4及以前版本存在CVE-2022-0513认证前SQL注入漏洞。
安装wordpress,这里使用版本5.8.3:
安装`wp-stastics`插件,版本为13.1.3:
该漏洞需启用`Recored Exclusions`功能,默认不开放:
根据漏洞描述,在`Record Exclusions`功能开启后漏洞方能触发成功。`WP Statistics`插件通过`/wp-json/wp-statistics/v2/*` URL注册REST API:
通过`/wp-json/wp-statistics/v2/hit`调用可以触发`hit_callback`函数:
`hit_callback`函数调用了`Hits::record`:
当`$exclusioin[‘exclusion_match’]`值为true时,数据被传入`Exclusion::record`函数执行:
`Exclusion::record`函数检查输入,当例外匹配(`exclusion_match`)存在于数据库中时,该函数更新计数匹配,当不存在时则添加`exclusion_reason`数据。注意到SQL查询时`exclusion[‘exlusion_reason’]`并没有进行转义或安全检查,会导致SQL注入产生:
根据burpsuite流量包构造指向`/wp-json/wp-statistics/v2/hit`的请求并断点调试:
`Exclusion::record`函数`exclusion_reason`被设置为`user_role`:
`user_role`为WP-Statistics自带的例外排除选项,接下来如何注入`exclusion_reason`呢?经过审计代码,最终成功构造了SQL注入Payload如下:
接下来通过动态调试分析漏洞触发过程。首先看`Hits`类构造函数,当通过`is_rest_hist`检查后调用`set_params`方法设置`rest_hits`:
`is_rest_hit`函数检查请求URL是否以`wp-json`开头,且参数必须包含`wp_statistics_hit_rest`字段:
`rest_params`函数读取请求参数并赋值给`rest_hits`:
之后请求报文里的`rest_hits`内容被写入:
`Exclusion::check`函数经过一系列复杂处理最终调用`set_exclusion`设置例外:
最后在`Exclusion::check`后获取到新的`exclusion_reason`:
最后完成SQL语句的注入,语句格式为:
UPDATE wp_statistics_exclusions SET `count` = `count` + 1 WHERE `date` = '2022-02-24' AND `reason` = '[REASON]'
由于注入没有回显,可使用时间延迟注入进行测试:
根据CVE描述,该漏洞是无需用户认证的,使用普通SESSION提示`rest_cookie_invalid_nonce`:
`wp-includs/rest-api.php`对wp_verify_nonce进行检查:
其hash检查判断中仅`$i`是变化的,其余均是固定值,但搜了很多文章,写了测试代码发现无法绕过:
只要攻击者获取一个有效的wpnonce即可实现认证前SQL注入,从网上公开文章来看,当`$_SERVER[‘REQUEST_URI]`中包含`wp-json/`时,`is_rest_request`返回true,因此无需缓存插件就能绕过wpnonce检查访问API,这里验证并未成功:
本漏洞是一个比较典型的SQL注入漏洞,需插件开启特定配置。修补漏洞后,`set_exclusion`函数检查用户输入`exclusion_reason`参数是否在默认配置中:
由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用本人负责,且听安全团队及文章作者不为此承担任何责任。
点关注,不迷路!
关注公众号回复“漏洞”获取研究环境或工具
原文始发于微信公众号(且听安全):【最新漏洞预警】CVE-2022-0513 全球600w+量级插件WP Statistics SQL注入漏洞不完整分析之旅