近期,WordPress 被曝出存在内容注入漏洞,攻击者利用此漏洞可越权对网站文章内容进行修改。
为了让大家更直观的了解漏洞造成的危害,千里目安全实验室倾力录制攻击视频供大家观赏。
千里百科
WordPress 是一种使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设属于自己的网站,也可以把 WordPress 当作一个内容管理系统(CMS)来使用。
REST API 是 WordPress 4.7.0 版本开始默认启用的插件,通过 REST API 可对已发布的文章执行多个修改操作,比如修改日期、标题、作者、内容等等。
影响范围
WordPress 是使用最广泛的建站系统之一,此漏洞影响 WordPress 4.7.0-4.7.1版本。
据 Sucuri 最新报道,漏洞被披露后,黑客开始尝试扫描、利用漏洞,并成功入侵了众多 WordPress 网站。其中入侵网站最多的黑客组织是 “w4l3XzY3”。截止到发稿时间,w4l3XzY3 已成功入侵 18.6w 个网站。
漏洞原理
通过对 WordPress 源代码的深入剖析,发现 REST API 文件中的权限检查逻辑可以被绕过,从而形成文章任意内容的修改漏洞。
首先,在文件 /wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php 中,看下文章(post)的控制类,注册了文章更新的回调函数update_item 和检查更新权限的回调函数 update_item_permissions_check:
我们跟进检查更新权限的回调函数 update_item_permissions_check:
第一个红框,是根据用户传入的 id 参数,使用 get_post() 函数来查找相应的文章。第二个红框是重点,如果文章存在但是没有权限,会返回没有权限操作(Sorry, you are not allowed to edit this post.)。也就是说,如果文章不存在,则会跳过这部分的判断,执行到最后的 return true,从而完成权限检查。这里的逻辑是合理的,如果用户提供的id没有对应的文章,即使获得了更改权限,也没有可用的文章被修改。但是,这只是权限检查阶段。
如果用户提供一个特殊的 id 参数,使得在权限检查时(update_item_permissions_check 函数)没有对应的文章,从而获得修改权限,但在修改文章内容(update_item 函数)时。又能找到该特殊的 id 对应的文章,那么就可以直接修改文章的内容了。这样的 id 参数需要满足两个条件:
1. 使得 get_post() 函数找不到对应的文章
2. 使得 update_item () 函数能找到对应的文章
这样的 id 参数是否存在呢?
我们先看 get_post() 函数
可以看出,只要我们输入的 id 使得 get_instance() 函数返回 false,我们就会得到一个null的返回,也就是找不到对应的文章。继续根跟进 get_instance() 函数,如下图:
这里可以清楚地看到,只要输入的 id 参数不是纯数字,就会 false,从而就会使得找不到对应的文章。
我们再看下修改文章内容的函数 update_item。
红框中的内容是重点中的重点。这里我们需要 get_post() 函数成功执行,找到对应的文章。而上一行的 $id = (int) $request['id'];,会把用户输入的id进行整数类型转换,保证了 get_post() 函数能够执行成功。问题就出现在这个类型转换上,只要我们提供的id参数能还换成整数即可,比如 123abc,进行转换后会变成 123。
我们找到了这样的 id 参数,从而可以实现绕过权限检查,修改文章任意内容。
漏洞复现
下图是默认安装的 WordPress4.7.1,第一篇默认文章 Hello World,其文章 id 为 1.
构造数据包如下图,id 参数为 1a,修改标题和内容,都改为 Content Injection Vulnerability in WordPress:
查看返回状态码为 200,说明已经成功修改。刷新页面,可以看到文章已被修改。
修复方案
2、某公司下一代防火墙用户,请升级 WAF 规则库到 20170207 及其以上版本,可轻松防御针对此漏洞的攻击。