WordPress权限通过帖子类型升级 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

WordPress权限通过帖子类型升级

申博_安全预警 申博 283次浏览 已收录 0个评论
WordPress权限通过帖子类型升级

WordPress创建博客文章的方式存在逻辑缺陷,允许攻击者访问管理员应该拥有的功能。这导致WordPress核心中的存储XSS和对象注入以及WordPress最受欢迎的插件Contact Form 7和Jetpack中的更严重的漏洞。

技术背景

要注册新的帖子类型,插件会使用新帖子类型register_post_type()的名称和一些元信息进行调用

注册示例帖子类型

123456
// Example post type register_post_type( 'example_post_type', array(
    'label' => 'Example Post Type',     // The name of the type in the front end     'can_export' => true,               // Make it possible to export posts of this type,     'description' => 'Just an example!' // A short description ));

如何保护自定义帖子类型

每种帖子类型都有自己的编辑页面(例如example.com/wordpress/wp-admin/?page=example_post_type_editor)。

WordPress权限通过帖子类型升级
图1:此类页面的示例。这里的帖子类型是联系表格。只有管​​理员才能访问该页面。

 

如果插件开发人员决定只允许管理员使用插件的帖子类型,他只需检查用户是否是页面顶部的管理员,否则结束执行。

/wp-content/plugins/example_plugin/example_post_type_editor.php

123
if(!current_user_is_administrator()) {
    die("You are not an administrator and not allowed to use this post type.");
}

WordPress发布提交

虽然所有已注册的帖子类型都有自己的编辑器,但他们都可以使用WordPress帖子提交API并使用WordPress功能插入和更新帖子wp_write_post()该函数接受用户的输入,例如$_POST[‘post_type’]$_POST[‘post_title’]$_POST[‘post_content’]因此它知道如何处理的帖子。

在WordPress的帖子提交过程的第一步,WordPress必须知道用户是否想要编辑现有帖子或创建新帖子。为此,WordPress会检查用户是否已发送帖子的ID。WordPress将允许$_GET[‘post’]$_POST[‘post_ID’]如果设置了ID,则用户想要编辑具有该ID的现有帖子。否则,用户想要创建新帖子。

/wp-admin/post.php

1234567
if ( isset( $_GET['post'] ) )     $post_id = $post_ID = $_GET['post'];
elseif ( isset( $_POST['post_ID'] ) )     $post_id = $post_ID = $_POST['post_ID'];
    
if($post_id)
    

在下一步中,WordPress必须确定用户尝试创建的帖子类型。如果已发送帖子ID,WordPress将从表中提取post_type数据库中的wp_posts列。如果用户想要创建新帖子,则目标帖子类型将是$_POST[‘post_type’]

/wp-admin/post.php

123456789
if ( isset( $_GET['post'] ) )
    $post_id = $post_ID = $_GET['post'];
elseif ( isset( $_POST['post_ID'] ) )
    $post_id = $post_ID = $_POST['post_ID'];

if($post_id)
 $post_type = get_post_type($post_id); else
 $post_type = $_POST['post_type'];

一旦WordPress知道用户试图创建或编辑的帖子的帖子类型,它将检查用户是否实际上被允许使用该帖子类型。WordPress通过验证只能从相关帖子类型的编辑器页面获取的随机数来完成此操作。

要进行随机数验证,WordPress将使用以下代码:

/wp-admin/post.php

12345678
if($post_id)
    $post_type = get_post_type($post_id);
else
    $post_type = $_POST['post_type'];

$nonce_name = "add-" . $post_type;
if(!wp_verify_nonce($_POST['nonce'], $nonce_name))     die("You are not allowed to use this post type!");

如果$post_type是a post,那$nonce_name就是add-post如果$post_typeexample_post_type,那$nonce_name就是add-example_post_type此nonce只能由具有创建这些帖子类型的用户获取,因为只有这些用户才能访问该帖子类型的编辑器页面,这是获取nonce的唯一方法。

影响 – 攻击者可以做些什么

WordPress的核心是博客软件,允许用户创建和发布帖子。随着时间的推移,引入了不同的帖子类型,例如页面和媒体条目(图像,视频等)。插件可以注册新的帖子类型,例如产品或联系表单。根据插件类型的目的,插件注册,它提供了独特的新功能。例如,联系表单插件可能允许创建具有文件上载字段的联系表单(例如,用于简历)。创建联系表单的用户可以定义应该允许哪些文件类型。邪恶的用户也可以允许上传php文件,然后在他的网站上执行任意代码。这本身不是问题,因为插件可以限制对他们仅向管理员注册的帖子类型的访问,并信任WordPress来处理它们的限制。此处讨论的权限提升允许较低权限的用户绕过WordPress实施的安全检查并创建任何类型的帖子并滥用自定义帖子类型的功能。这导致WordPress核心中的存储XSS和对象注入。根据安装的插件,可以利用更严重的漏洞。例如,当使用WordPress最受欢迎的插件时,使用了具有超过500万个活动安装的Contact Form 7,攻击者能够读取目标Wordpress站点的数据库凭据。大多数顶级WordPress插件都容易受到此权限升级的影响。这导致WordPress核心中的存储XSS和对象注入。根据安装的插件,可以利用更严重的漏洞。例如,当使用WordPress最受欢迎的插件时,使用了具有超过500万个活动安装的Contact Form 7,攻击者能够读取目标Wordpress站点的数据库凭据。大多数顶级WordPress插件都容易受到此权限升级的影响。这导致WordPress核心中的存储XSS和对象注入。根据安装的插件,可以利用更严重的漏洞。例如,当使用WordPress最受欢迎的插件时,使用了具有超过500万个活动安装的Contact Form 7,攻击者能够读取目标Wordpress站点的数据库凭据。大多数顶级WordPress插件都容易受到此权限升级的影响。

WordPress的失败

尽管较低特权的攻击者,例如贡献者角色中的攻击者,无法访问示例帖子类型的页面和随机数,但他总能获得普通帖子的随机数,其具有简单的内部帖子类型post这意味着他可以简单地将帖子ID设置为具有帖子类型的帖子post这将允许他通过nonce验证。

/wp-admin/post.php

 1 2 3 4 5 6 7 8 91011
// Send a post ID of a post of post type 'post' if($post_id)     // This would return 'post'  $post_type = get_post_type($post_id); else
    $post_type = $_POST['post_type'];

// All users can by default create 'posts' and get the nonce to pass this check $nonce_name = "add-" . $post_type; if(!wp_verify_nonce($nonce_name))
    die("You are not allowed to create posts of this type!");

但是,此方法仅允许更新现有帖子,并且无法覆盖post_type帖子。如果设置了帖子ID,WordPress将post_type在更新帖子之前从参数中删除

但是,$post_type如果$_POST[‘post_ID’]设置了,WordPress将仅删除参数攻击者可以通过$_POST[‘post_ID’]  发送帖子ID $_GET[‘post’]如果攻击者通过$_GET[‘post’]以下方式发送帖子ID ,则会发生:

  1. WordPress看到设置了帖子ID并从数据库中提取其帖子类型。
  2. WordPress会检查攻击者是否为该帖子类型发送了一个有效的nonce(他总是可以获得正常的post
  3. 一旦nonce检查通过,WordPress将确定是否应该调用wp_update_post()wp_insert_post()它通过检查是否$_POST[‘post_ID’]已设置来完成此操作如果是,则将调用wp_update_post并$post_type删除参数,从而不允许攻击者覆盖帖子类型。如果未设置,WordPress将调用wp_insert_post()$_POST[‘post_type’]用作新帖子的帖子类型。

因为WordPress忘记$_GET[‘post’]了第三步检查,攻击者可以通过nonce验证并创建一个具有任意帖子类型的新帖子。显示的代码片段被简化和抽象化,真实代码跨越多个文件和函数调用,这使得该过程容易出现这样的缺陷。

/wp-admin/post.php

 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536
// An attacker sets $_GET['post'] to a post of a post type he can access if ( isset( $_GET['post'] ) )     $post_id = $post_ID = $_GET['post'];
elseif ( isset( $_POST['post_ID'] ) )
    $post_id = $post_ID = $_POST['post_ID'];

if($post_id)
    // The post type is now 'post'  $post_type = get_post_type($post_id); else
    $post_type = $_POST['post_type'];

// Since the attacker has access to that post type, he can get the nonce and // pass the nonce verification check $nonce_name = "add-" . $post_type; if(!wp_verify_nonce($nonce_name))     die("You are not allowed to create posts of this type!");

$post_details = array(
  'post_title' => $_POST['post_title'],
  'post_content' => $_POST['post_content'],
  'post_type' => $_POST['post_type']
);

// WordPress only unsets the post_type if $_POST['post_ID'] is set and forgets to // check $_GET['post'] if(isset($_POST['post_ID'])) {     
 unset($post_details['post_type']);     $post_details['ID'] = $post_id;
    wp_update_post($post_details);
} else {
    // If we just set $_GET['post'] we will enter this branch and can set the     // post type to anything we want it to be!  wp_insert_post($post_details); }

利用:通过Contact Forms 7阅读wp-config.php

到目前为止,您应该了解较低权限的用户可以滥用此错误来创建任何类型的帖子,并且对目标站点的影响取决于安装的插件以及安装的插件提供的帖子类型的功能。

举一个具体的例子,作为贡献者角色的攻击者有可能滥用WordPress最流行的插件Contact Form 7中的一个功能来读取目标站点的wp-config.php文件的内容。此文件包含数据库凭据和加密密钥。

在Contact Forms 7的5.0.3版本中,可以设置本地文件附件。当管理员创建联系表单并且页面的访问者通过它联系他时,会向管理员发送一封电子邮件,其中包含用户输入的所有数据。本地文件附件是联系表单的设置,管理员可以在其中定义要作为每封电子邮件附件发送的本地文件。

这意味着攻击者可以简单地创建一个新的联系表单,设置本地文件附件../wp-config.php并设置应将数据发送到他自己的电子邮件,提交表单然后读取最重要的WordPress文件的内容。

修复插件开发人员

插件开发人员应该通过在调用时显式设置capabilitycapability_type参数来进一步加强其插件的安全性register_post_type()

注册更安全的帖子类型

12345678
// Example post type register_post_type( 'example_post_type', array(
    'label' => 'Example Post Type',     
    
 'capability_type' => 'page' // capability_type of page makes sure that                                     // only editors and admins can create posts of                                     // that type ));

请阅读有关使用register_post_type 保护帖子类型的WordPress文档

WordPress的XMLRPC和REST API

可以通过XMLRPC和WordPress的REST API创建帖子,这些帖子不对特定帖子类型执行随机数验证。但是,通过这些API创建帖子时,无法设置任意post meta字段。我们发现的插件中的大多数漏洞只有在用户可以设置这些后置元字段时才可以利用。

摘要

具有低于贡献者的用户角色的攻击者(WordPress中第二低的角色)可以创建他们通常无法访问的帖子类型的帖子。这使攻击者可以访问仅供管理员使用的功能。到目前为止,我们已经在WordPress的Top 5 Popular插件中发现了2个漏洞。我们估计有数千个插件可能容易受到攻击。此外,在WordPress的一个内部帖子类型中识别出存储的XSS和对象注入。存储的XSS可以通过点击顶升攻击来触发。执行JavaScript后,可以进行完整的站点接管。

 

申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明WordPress权限通过帖子类型升级
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址