WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)

介绍

wordpress,它是世界上 最常用的开源CMS之一。在允许开发者自己构建插件和主题来管理网站的时候,由于它的便利性而被大量使用,wordpress的核心会提供插件/主题的功能来调用和使用wordpress提供的数据格式、查询数据库等功能, … 在wordpress提供的类中,我们发现WP提供的查询DB的类中有SQL Injection错误:WP_Query

错误分析

在 5.8.3 版本中,wordpress 已经修复了这个错误,比较提交更改可以在处理变量之前clean_query添加检查的函数中看到。$query['field']$query['terms']

图片[1]-WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)-FancyPig's blog

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

图片[2]-WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)-FancyPig's blog

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

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

图片[3]-WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)-FancyPig's blog

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

(这里的比较是使用==了Loose comparisons的漏洞,在某些情况下这个错误可以用来随意创建一个条件句)。

图片[4]-WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)-FancyPig's blog

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

图片[5]-WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)-FancyPig's blog

所以总而言之,要发生 SQL 注入,必须满足两个条件:

  • $query['field'] 成为 term_taxonomy_id
  • $query['taxonomy'] 空的或 is_taxonomy_hierarchical($query['taxonomy']) === false

流导致以下错误:

图片[6]-WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)-FancyPig's blog

开发

虽然这是wordpress核心的错误,但是wordpress核心使用的方式并没有触发错误,所以我转而寻找插件和主题的错误。WP_Query当您要查询数据库时,插件/主题将调用该类,从源代码中了解错误的方法是在您使用它时,WP_Query($data)并且 $data 是您可以控制的。

例如new WP_Query(json_decode($_POST['query_vars'])),有效负载将具有以下形式:

query_vars={"tax_query":{"0":{"field":"term_taxonomy_id","terms":["<inject>"]}}} 或者query_vars={"tax_query":{"0":{"taxonomy":"nav_menu","field":true,"terms":["<inject>"]}}}

在构建错误测试环境时,启用 DEBUG 功能将可以通过基于错误的方式检测 SQL 注入:

图片[7]-WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)-FancyPig's blog

得出结论

在 wordpress 的补丁中$query['field']首先添加了检查,否则它将转换$query['terms']为整数,因此 SQLI 不会发生。

由于wordpress插件和主题众多,我们团队只专注于寻找下载量> 100k(免费版)的,除了付费插件/主题或下载量< 100k,我们没有时间继续。

结果,发现相当多的插件和主题受到该漏洞的影响(authen 和 unauthen)。

我的团队在 9 月底向 ZDI 报告了此漏洞,3 个月后,Wordpress 在其核心中修复了该漏洞。具体来说,时间线如下:

图片[8]-WordPress 5.8.3 SQL 注入漏洞 (CVE-2022–21661)-FancyPig's blog

感谢阅读^^。

© 版权声明
THE END
喜欢就支持一下吧
点赞28 分享
评论 共1条

请登录后发表评论