Wordpress contact_form_7_v5.0.3 插件 权限提升、任意文件读取漏洞分析

栏目: 编程工具 · 发布时间: 5年前

内容简介:作者:看到了国外有大佬发了关于WordPress的一个非常有名的插件,contact form 7的漏洞,之前见到过很多WordPress站点使用这个插件,大佬写的比较笼统,一些详细的利用方式没有说的太明白.这个漏洞是由于插件开发者对WordPress的使用不当造成的,其实跟WordPress的逻辑有一定的关系,导致了可以发布普通文章的用户,可以绕过权限认证,进行发表原本插件作者只允许管理员创建和修改的自定义类型的"post"。

作者: i9n0re

简介

看到了国外有大佬发了关于WordPress的一个非常有名的插件,contact form 7的漏洞,之前见到过很多WordPress站点使用这个插件,大佬写的比较笼统,一些详细的利用方式没有说的太明白.

漏洞成因

这个漏洞是由于插件开发者对WordPress的使用不当造成的,其实跟WordPress的逻辑有一定的关系,导致了可以发布普通文章的用户,可以绕过权限认证,进行发表原本插件作者只允许管理员创建和修改的自定义类型的"post"。

漏洞作者发现了contact from 7插件存在这样的缺陷,导致了任意一个可以发表普通文章的用户,可以新建一个contact,而且在5.0.3版本下,附件可以跨目录进行添加文件,进而可以读取网站的 wp-config.php

相关的技术点

nonce

首先我们了解下什么是nonce?nonce相当于 csrf token 是WordPress用来防御csrf问题的,并进行了相关的权限验证。

post_type

post_type 是插件作者注册的自定义 post 类型,与WordPress的文章类似,插件作者要实现一个页面来进行管理文章类型。只有在后台的新建或者编辑页面当中可以获取到 nonce 随机数,提交的时候只有代入了nonce才能进行相应的操作。

漏洞详情

以contact form 7 v5.0.3为例。

插件作者只允许WordPress的 editor 才能新建和编辑contact。

Wordpress contact_form_7_v5.0.3 插件 权限提升、任意文件读取漏洞分析

如果是文章的发布者,就没有修改和创建权限,会显示下面的页面。

Wordpress contact_form_7_v5.0.3 插件 权限提升、任意文件读取漏洞分析

contact form 7也是一种自定义类型的 post ,数据里面都是存在了 wp_posts 表当中,通过 post_type 进行区分。

Wordpress contact_form_7_v5.0.3 插件 权限提升、任意文件读取漏洞分析

正常情况,插件作者是通过 current_user_can('publish_pages') 进行权限的判定,也就是说editor以上的权限可以编辑,防止普通用户打开新建和修改文章的页面。

但是用户仍可以操作普通的文档,通过请求接口 wp-admin/post.php 的方式进行新建和编辑文章,只不过 post_type 变为了 post 等普通文档类型。由于插件作者在 register_post_type 的时候没有进行相关权限的配置,仅仅依靠了 current_user_can('publish_pages') 验证用户编辑权限,出现了安全问题。

接下来我们来看看普通文档的新建、编辑流程。

正常流程上,普通文档上传接口是请求 post-new.php后先生成一个 post ,然后再进行编辑,请求post.php,设置参数 actioneditpost

// wp-admin/post.php
case 'editpost':
    check_admin_referer('update-post_' . $post_id);

    $post_id = edit_post();

    // Session cookie flag that the post was saved
    if ( isset( $_COOKIE['wp-saving-post'] ) && $_COOKIE['wp-saving-post'] === $post_id . '-check' ) {
        setcookie( 'wp-saving-post', $post_id . '-saved', time() + DAY_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN, is_ssl() );
    }

    redirect_post($post_id); // Send user on their way while we keep working

    exit();

通过函数 check_admin_referer 检测nonce是否合法。

// wp-includes/pluggable.php
    // Nonce generated 0-12 hours ago
    $expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10 );
    if ( hash_equals( $expected, $nonce ) ) {
        return 1;
    }

    // Nonce generated 12-24 hours ago
    $expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
    if ( hash_equals( $expected, $nonce ) ) {
        return 2;
    }

漏洞利用的地方是通过传入action为 post ,调用下面这个逻辑。

// wp-admin/post.php
case 'post':
    check_admin_referer( 'add-' . $post_type );
    $post_id = 'postajaxpost' == $action ? edit_post() : write_post();
    redirect_post( $post_id );
    exit();

其中 post_type 是通过传入的 post_id 去数据库里面查询得到。

// wp-admin/post.php
if ( $post_id )
    $post = get_post( $post_id );

if ( $post ) {
    $post_type = $post->post_type;
    $post_type_object = get_post_type_object( $post_type );
}

可以看到,如果传入的 post_id 为正常帖子创建请求,这个地方的 nonce 普通用户就可以通过页面进行获取了。

绕过nonce检测

可以看到 post_id 是通过 $_GET['post'] 或者 $_POST['post_ID'] 两种方式获取。

// wp-admin/post.php
if ( isset( $_GET['post'] ) )
    $post_id = $post_ID = (int) $_GET['post'];
elseif ( isset( $_POST['post_ID'] ) )
    $post_id = $post_ID = (int) $_POST['post_ID'];
else
    $post_id = $post_ID = 0;

所以如果我们构建一个存在的并且 post_typepost 的帖子ID作为参数传入的话, check_admin_referer 的参数变为了固定值 add-post 这样的话,如果我们拿到了nonce就可以绕过了检测。有同学会问,怎么得到这个nonce呢?通过跟代码,我发现在 dashboard 页面当中,下面这个功能里面就有我们需要的nonce,通过查看源代码,获取这个表单的input这样就绕过了检测。

<input type="hidden" id="_wpnonce" name="_wpnonce" value="xxx" />

Wordpress contact_form_7_v5.0.3 插件 权限提升、任意文件读取漏洞分析

创建自定义类型的post

绕过了nonce检测后,我们来看 post 那个case,流程会进入到 write_post 函数,然后我们看到这个逻辑。

// wp-includes/post.php
    if ( !current_user_can( $ptype->cap->edit_posts ) ) {
        if ( 'page' == $ptype->name )
            return new WP_Error( 'edit_pages', __( 'Sorry, you are not allowed to create pages on this site.' ) );
        else
            return new WP_Error( 'edit_posts', __( 'Sorry, you are not allowed to create posts or drafts on this site.' ) );
    }

问题就出现在这,因为作者在注册post_type的时候没有进行权限限制,导致了权限提升。

v5.0.3 的插件配置:

//wp-content/plugins/contact-form-7/includes/contact-form.php
    public static function register_post_type() {
        register_post_type( self::post_type, array(
            'labels' => array(
                'name' => __( 'Contact Forms', 'contact-form-7' ),
                'singular_name' => __( 'Contact Form', 'contact-form-7' ),
            ),
            'rewrite' => false,
            'query_var' => false,
        ) );
    }

就导致了如果绕过了nonce检测,普通用户也就可以成功的创建只有editer权限才可以创建的 contact form 7了。

进一步利用

权限提升已经完成,下面就是利用了contact from 7 v5.0.3的一个问题。

Wordpress contact_form_7_v5.0.3 插件 权限提升、任意文件读取漏洞分析

当发送邮件的时候,可以携带附件,但是这个附件可以跨目录读取,导致了用户可以直接携带 wp-config.php 进行发送,实现敏感信息的泄露。

漏洞利用

理清了漏洞触发逻辑,利用方式就简单了,在后台登录页面,直接引用 poc.js

注意修改几个参数

meta_input[_mail][recipient]
meta_input[_mail][attachments]

然后可以在控制台里面引用,会发现新建了一个表单,然后在帖子里面正常引用这个表单,再页面中使用,并点击发送后,在自己的收件箱当中收到 wp-config.php 的附件。

Wordpress contact_form_7_v5.0.3 插件 权限提升、任意文件读取漏洞分析

漏洞修复

在注册 post_type 的时候,配置权限。

//wp-content/plugins/contact-form-7/includes/contact-form.php
    public static function register_post_type() {
        register_post_type( self::post_type, array(
            'labels' => array(
                'name' => __( 'Contact Forms', 'contact-form-7' ),
                'singular_name' => __( 'Contact Form', 'contact-form-7' ),
            ),
            'rewrite' => false,
            'query_var' => false,
            'capability_type' => 'page'
        ) );
    }

如果进行了这样的配置的话,在进行 write_post 这个函数逻辑的时候

// wp-includes/post.php
    if ( !current_user_can( $ptype->cap->edit_posts ) ) {
        if ( 'page' == $ptype->name )
            return new WP_Error( 'edit_pages', __( 'Sorry, you are not allowed to create pages on this site.' ) );
        else
            return new WP_Error( 'edit_posts', __( 'Sorry, you are not allowed to create posts or drafts on this site.' ) );
    }

这个判断才会生效,导致权限认证失败。

原文链接

poc.js


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

UNIX网络编程 卷1:套接字联网API(第3版)

UNIX网络编程 卷1:套接字联网API(第3版)

[美]W. 理查德•史蒂文斯(W. Richard Stevens)、比尔• 芬纳(Bill Fenner)、安德鲁 M. 鲁道夫(Andrew M. Rudoff) / 匿名 / 人民邮电出版社 / 2014-6-1 / 129.00

《UNIX环境高级编程(第3版)》是被誉为UNIX编程“圣经”的Advanced Programming in the UNIX Environment一书的第3版。在本书第2版出版后的8年中,UNIX行业发生了巨大的变化,特别是影响UNIX编程接口的有关标准变化很大。本书在保持前一版风格的基础上,根据最新的标准对内容进行了修订和增补,反映了最新的技术发展。书中除了介绍UNIX文件和目录、标准I/......一起来看看 《UNIX网络编程 卷1:套接字联网API(第3版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码