WordPress < 4.7.1用户名枚举漏洞分析(CVE-2017-5487)

WordPress是一种使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站。也可以把 WordPress当作一个内容管理系统来使用。

WordPress 在4.7.0版本之后将REST API插件集成到默认功能之中。REST API为WordPress的使用者提供了一个方便快捷的管理接口。在WordPress 4.7.0版本中,存在着一个越权漏洞,成功的利用这个漏洞,可以绕过管理员权限查看wordpress上所有发布过文章的用户信息列表。

影响版本

WordPress 4.7.0

漏洞分析

在正式的漏洞分析开始前,先来简单介绍下REST API的使用。官网给出的介绍如下:

具体使用详情请参照REST API Handbook

https://developer.wordpress.org/rest-api/

漏洞利用

先从exploitdb上面提供的poc入手

https://www.exploit-db.com/exploits/41497/

POC看起来比较简单,就是调用了wordpress的rest api接口进行users查询,但是在笔者的环境中,需要对这个poc进行一点小改动,如下图,需要加上一个index.php,否则找不到目录。

接下来看一下代码, 请求首先进入get_items_permissions_check模块进行权限检查

看上面的注释可以大概了解这个函数的功能:当请求users参数时,用来检查请求是否有读的权限,否则爆出WP_Error错误。

这个函数一共有三个if判断,这三个if判断都是由两部分组成的,每一个后半部分都是不可控的current_user_can( ‘list_users’ ),经测试,它的值还为false,所以只能使三个if得可控的前半部分不为真,才能最终绕过判定。

我们var_dump下这三个$request值

有意思的事情发生了,我们什么事情也没做,竟然完美的避开了权限检查的三个判定,接下来进入下个环节get_items函数,检索所有的用户。

上面代码省略了些内容,前半部分省略的是一些相关的参数配置,然后读到注释部分了解到下面参数经过过滤,就要进入WP_User_Query()部分了,我们通过给出的链接看一下查询部分的WP_User_Query()是怎么解释的

在跟进WP_User_Query中我们可以看到一个构造方法

在这里可以看到如果$query不为空,则先调用prepare_query(),接着再执行$this->query()

我们看一下prepare_query()是做什么的。

看注释可以了解到,它是准备查询变量的作用,可以看做是对变量的预处理。
接下来往后看$this->query();。跟进query()函数看看它最终执行了什么。

query()函数使用当前变量来执行查询,下面$this->request构造了一个sql查询语句,我们查看下它的值

可以看出这里可以查询的wp_users信息是有约束条件的,这里可以查询的用户必须满足发表过‘publish’类型的文章,并且类型还要是‘post’、‘page’、‘attachment’中的一个

我们分别看一下wp_users表和wp_posts表

wp_posts表

wp_users表

最终通过api返回的用户信息

修补防御

升级wordpress至最新版本。

如果您需要了解更多内容,可以
加入QQ群:570982169
直接询问:010-68438880

发表评论