欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

通过Post Types进行WordPress提权

来源:本站整理 作者:佚名 时间:2018-12-21 TAG: 我要投稿

研究人员发现WordPress创建博客的方式存在逻辑漏洞,攻击者利用该漏洞可以访问只有管理员才可以访问的特征。这会导致WordPress内核产生存储型XSS和对象注入等漏洞。
影响
WordPress是博客软件的核心,允许用户创建和发布博客。随着时间的推移,产生了不同的post类型,比如页面和图像、视频等。插件可以注册新的post类型,比如产品和联系人表单。根据插件注册的post type的类型,可以提供不同的特征。比如通讯录form插件可能允许用户用文件上传域来常见一个联系人form。创建联系人form的用户可以定义允许上传的文件类型。恶意用户可以允许上传php文件,然后在站点上执行任意代码。但这并不是一个问题,因为插件可以限制对post类型的访问。下面要讲的权限提升就允许低权限用户绕过wordpress应用的安全检查,并创建任意类型的post,误用定制的post类型的特征。最终导致WordPress core产生存储型XSS和对象注入漏洞。根据安装的插件,还有更严重的漏洞可以利用。
技术背景
为注册新的post类型,插件必须要用新的post类型和一些meta信息来调用register_post_type()。

为什么定制的post类型是安全的?
每个post类型都有自己的编辑页面,比如 example.com/wordpress/wp-admin/?page=example_post_type_editor

图1: post type为联系人表单,只有管理员可以访问该页面
如果插件开发者决定只有管理员可以使用插件的post类型,那么就可以检查如果用户是不是管理员,然后执行。

WordPress post提交
虽然所有注册的post类型都有自己的编辑页,但是都可以用WordPress post提交API,用WordPress函数wp_write_post()插入和更新post。该函数的输入类型为$_POST[‘post_type’], $_POST[‘post_title’], $_POST[‘post_content’],因此知道如何处理post。在WordPress post提交过程中,WordPress必须首先了解用户想要编辑已有的post还是创建一个新的post。因此WordPress要检查用户是否发送过该post的ID。WordPress允许$_GET[‘post’]或$_POST[‘post_ID’]。如果ID存在,用户就可以用已有的ID去编辑post;如果ID不存在,就是要创建新的post。

然后WordPress要确定用户在创建那种post类型。如果post ID已经发送了,WordPress就会从wp_posts table中的数据库中取出post_type列。如果用户想要创建新的post,目标post类型应该是 $_POST[‘post_type’]。

WordPress在知道了用户要创建或编辑的post的post类型后,会检查用户是否有权限使用该post类型。这一过程是通过一个只能从编辑页获得的随机数来确认的。用随机数来确认的代码如下:

如果$post_type 是post,$nonce_name就是add-post。如果$post_type是example_post_type, $nonce_name就是add-example_post_type。随机数只能由可以创建这些post类型的用户获取,因为只有这些用户可以访问该post类型的编辑页,这也是唯一严重获得随机数的方法。
WordPress的失败
虽然低权限的攻击者不能访问该页面和示例post类型的随机数,但攻击者仍然可以获取正常post的随机数。也就是说攻击者可以讲post ID设置为有post type post的post,这样就可以绕过随机数验证。

但是该方法只能更新已有的post,无法覆写新的post的post_type。如果post ID已经存在了,WordPress就会在更新post之前从参数中移除post_type。但WordPress只会移除设置了$_POST[‘post_ID’]的$post_type参数。攻击者就可以通过 $_POST[‘post_ID’]或$_GET[‘post’]发送一个post ID。如果攻击者通过$_GET[‘post’]发送了post ID:1、WordPress就会看到一个设置了的post ID,然后从数据库中拿出其post type。2、WordPress会检查攻击者是否为该post type发送了有效的随机数。3、通过随机数检查后,WordPress会决定应该调用wp_update_post()还是wp_insert_post()。这一过程是通过设置$_POST[‘post_ID’]实现的。如果设置了,就调用wp_update_post并移除$post_type参数,这样攻击者就不能覆写post type了。如果没有设置,WordPress就调用wp_insert_post(),并用$_POST[‘post_type’]作为新post的post type。
因为WordPress没有检查第3步的$_GET[‘post’],攻击者可以绕过随机数验证,并且创建一个任意post type的新post。

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载