• 海博网_海博测评网_海博网论坛_海博官网论坛_海博论坛网站地址_海博测评

    海博网论坛

    海博网论坛科技

    • 安全产品与方案

      安全产品与方案
    • 基础设施安全

      基础设施安全
    • 数据安全

      数据安全
    • 云计算安全

      云计算安全
    • 工业互联网安全

      工业互联网安全
    • 物联网安全

      物联网安全
    • 信息技术应用创新

      信息技术应用创新
    • 全部产品

      全部产品
    • 全部解决方案

      全部解决方案

    基础设施安全


    • 政府

      政府
    • 运营商

      运营商
    • 金融

      金融
    • 能源

      能源
    • 交通

      交通
    • 企业

      企业
    • 科教文卫

      科教文卫

    返回列表

    WordPress REST API 内容注入漏洞分析

    2017-02-10

    发布者:海博网论坛科技

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


    WordPress 在4.7.0版本之后将REST API插件集成到默认功能之中。REST
    API为WordPress的使用者提供了一个方便快捷的管理接口。在WordPress
    4.7.0-4.7.1版本中存在着一个越权漏洞,成功的利用这个漏洞,可以绕过管理员权限对文章进行增删改查操作。


    影响版本


    WordPress 4.7.0-4.7.1


    漏洞分析


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



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


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


    在使用api对文章进行操作之前,需要对操作进行授权,授权方式有三种:cookie、oauth和简单认证。如果不进行授权直接通过api对文章进行修改操作,会返回一个401,如下图所示



    如果想成功利用漏洞,必须绕过权限管理。我们跟踪下后台update处权限管理代码



    public function update_item_permissions_check( $request ) {
    
       $post = get_post( $request['id'] );
       $post_type = get_post_type_object( $this->post_type );
    
       if ( $post && ! $this->check_update_permission( $post ) ) {
          return new WP_Error( 'rest_cannot_edit' __( 'Sorry you are not allowed to edit this post.' ) array( 'status' => rest_authorization_required_code() ) );
       }
    
       if ( ! empty( $request['author'] ) && get_current_user_id() !== $request['author'] && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
          return new WP_Error( 'rest_cannot_edit_others' __( 'Sorry you are not allowed to update posts as this user.' ) array( 'status' => rest_authorization_required_code() ) );
       }
    
       if ( ! empty( $request['sticky'] ) && ! current_user_can( $post_type->cap->edit_others_posts ) ) {
          return new WP_Error( 'rest_cannot_assign_sticky' __( 'Sorry you are not allowed to make posts sticky.' ) array( 'status' => rest_authorization_required_code() ) );
       }
    
       if ( ! $this->check_assign_terms_permission( $request ) ) {
          return new WP_Error( 'rest_cannot_assign_term' __( 'Sorry you are not allowed to assign the provided terms.' ) array( 'status' => rest_authorization_required_code() ) );
       }
    
       return true;
    }




    如上图所示,在这里if语句中,前半部分$post为真,后半部分check_update_permission()函数对$post的权限进行判断,结果为假,导致返回Sorry
    you are not allowed to edit this post信息。


    这个漏洞的挑战就在于,如何成功的绕过update_item_permissions_check()模块,使其最终return true。


    我们回头看update_item_permissions_check()函数,



    注意到$post = get_post( $request[‘id’] );这一行,这一行的作用是判断提交的文章id是否存在。



    function get_post( $post = null $output = OBJECT $filter = 'raw' ) {
       if ( empty( $post ) && isset( $GLOBALS['post'] ) )
          $post = $GLOBALS['post'];
    
       if ( $post instanceof WP_Post ) {
          $_post = $post;
       } elseif ( is_object( $post ) ) {
          if ( empty( $post->filter ) ) {
             $_post = sanitize_post( $post 'raw' );
             $_post = new WP_Post( $_post );
          } elseif ( 'raw' == $post->filter ) {
             $_post = new WP_Post( $post );
          } else {
             $_post = WP_Post::get_instance( $post->ID );
          }
       } else {
          $_post = WP_Post::get_instance( $post );
       }
    
       if ( ! $_post )
          return null;
    
       $_post = $_post->filter( $filter );
    
       if ( $output == ARRAY_A )
          return $_post->to_array();
       elseif ( $output == ARRAY_N )
          return array_values( $_post->to_array() );
    
       return $_post;
    }



    可见,如果id对应的文章不存在,则返回null。


    如果我们输入的url是这种形式


    http://192.168.3.112/wordpress/index.php/wp-json/wp/v2/posts/1/?id=1grq


    get_post()函数返回值一定为null,这样会使得$post值为null,回头来看update_item_permissions_check()函数,这时update_item_permissions_check()函数的返回值竟然为true了!


    既然update_item_permissions_check()函数的返回值为true,说明我们绕过了update_item_permissions_check()权限验证,但是id为‘1grq’,根本不存在这样数字加字母组合的文章id,那怎么才能对指定文章进行越权操作呢?


    有趣的事情发生了,让我们来看update_item()函数,这个函数是用来update通过权限验证的数据,我们看看它是怎么定义的



    注意第二行,这里将$request[‘id’]进行了int类型的数值转换,在php中,$request[‘id’]
    =”1grq”会被转换为数值类型1,如下图演示



    所以这里的$id又由‘1grq’变回1了,get_post()函数也会找到对应id为1的文章了。


    漏洞利用


    目前已经有研究员在GitHub上给出相应的poc,链接如下

    https://gist.github.com/leonjza/2244eb15510a0687ed93160c623762ab


    官方修补方案分析



    在4.7.2版本中,如果get_post()判定$post结果为 false,则直接返回$post,避免$post进入下层if判定绕过权限检查。


    修补防御


    升级wordpress至最新版本(4.7.2)。


    <<上一篇

    Hadoop遭遇勒索攻击

    >>下一篇

    预警通告:Struts2 远程代码执行漏洞(S2-045)

    您的联系方式

    *姓名
    *单位名称
    *联系方式
    *验证码
    提交到邮箱

    购买热线

    • 购买咨询:

      400-818-6868-1

    提交项目需求

    欢迎加入海博网论坛科技,成为我们的合作伙伴!
    • *请描述您的需求
    • *最终客户名称
    • *项目名称
    • 您感兴趣的产品
    • 项目预算
    您的联系方式
    • *姓名
    • *联系电话
    • *邮箱
    • *职务
    • *公司
    • *城市
    • *行业
    • *验证码
    • 提交到邮箱

    服务支持

    智能客服
    智能客服
    购买/售后技术问题
    盟管家-售后服务系统
    盟管家-售后服务系统
    在线提单|智能问答|知识库
    支持热线
    支持热线
    400-818-6868
    海博网论坛科技社区
    海博网论坛科技社区
    资料下载|在线问答|技术交流

    © 2024 NSFOCUS 海博网论坛科技 www.nsfocus.com All Rights Reserved . 京公网安备 11010802021605号 京ICP备14004349号 京ICP证12726944号

    网站首页
    海博网论坛