TEST...">WordPress <= 4.3.0 跨站脚本漏洞 - exploit database | Vulners.com TEST...">TEST...">TEST...">Lucene searchWordPress <= 4.3.0 跨站脚本漏洞
2015-09-1900:00:00RickGraywww.seebug.org21<p>WordPress 在编辑文章内容时允许使用简码(shorcodes)来表示资源(图片,链接等)。WordPress 中开启了白名单机制去过滤 HTML 标签,只有在白名单规则里的标签,才允许被使用,并且会使用专用脚本 “KSES” 去检测和过滤这些 HTML 标签。这里需要说明的是,WordPress 对 HTML 标签的检测和过滤发生在将内容插入数据库时,而简码的解析渲染发生在将内容输出到页面时,下面简单用例子说明一下两个处理过程的差别,编辑文章插入内容为:</p><pre>TEST!!![caption width=“1” caption=‘<a href="’ “>]</a><a>xxxxxx</a></pre><p>因插入的内容包含完整且符合白名单规则的 HTML 标签,而简码 caption(<a href=“http://codex.wordpress.org/Caption_Shortcode” target=”_blank">caption简码说明</a>) 并不包含在 “KSES” 检测的内容里,最后输出内容到前台时简码解析后会被渲染为:</p><pre><p>TEST!!!<figure style=“width: 1px;” class=“wp-caption alignnone”><figcaption class=“wp-caption-text”><a href=“</figcaption></figure></a><a>xxxxxx</a></p></pre><p>由于在 “KSES” 过滤检测时只关 HTML 标签,对简码并不进行检测,又因简码中属性都以 KEY=VALUE 的形式出现,用单引号(')或者双引号(”)包裹值 VALUE ,因此在 TEST!!![caption width=“1” caption=‘<a href="’ “>]</a><a>xxxxxx</a> 这段内容中,简码
caption
有两个属性,分别为:</p><pre>width: 1
caption: <a href=”</pre><p>而后半部分的 <a href="’ “>]</a><a>xxxxxx</a> 又为正常的 HTML 标签闭合形式,因此并不会被 “KSES” 检测过滤后丢弃掉。最终在前台输出时,简码 caption 被解析,使得最后出现 <a> 标签中 href 属性值未闭合的情况。</p><p>因此利用前后处理的差异,可以构造出有利的 payload 形成 XSS:</p><pre>TEST!!![caption width=“1” caption='<a href=”’ “>]</a><a href=“http://onMouseOver=‘alert(1)’”>Click me</a></pre><p>将上面 payload 作为文章内容发布,前端渲染出来的结果为:</p><pre><p>TEST!!!<figure style=“width: 1px;” class=“wp-caption alignnone”><figcaption class=“wp-caption-text”><a href=”</figcaption></figure></a><a href=“http://onMouseOver=‘alert(1)’”>Click me</a></p></pre><p>输出的内容在浏览器中解析成 <a> 标签部分,href 属性值为 </figcaption></figure></a><a href=,而 http:// 由于双斜杠(//)的原因与 onMouseOver='alert(1) 部分断开,因此一个 onmouseover 属性被解析出来,形成 XSS。</p><p><img alt=“4.png” src=“https://images.seebug.org/contribute/d838cf01-106c-4c35-a580-2b8da82721ae-4.png”><br></p><p>该漏洞(CVE-2015-5714)已经在 WordPress 新版 4.3.1 中修复,具体 patch 部分位于两处,第一处在 wp-includes/shortcodes.php 中的 shortcode_parse_atts() 函数中:</p><pre>— wp-includes/shortcodes.php
+++ wp-includes/shortcodes.php
@@ -462,6 +462,15 @@
elseif (isset($m[8]))
$atts[] = stripcslashes($m[8]);
}
+
// Reject any unclosed HTML elements
foreach( $atts as &$value ) {
if ( false !== strpos( $value, '<' ) ) {
if ( 1 !== preg_match( '/^[^<]*+(?:<[^>]*+>[^<]*+)*+$/', $value ) ) {
$value = '';
}
}
}
} else {
$atts = ltrim($text);
}<br></pre><p>新添加的处理过程,过滤了在简码属性值中出现的未闭合 HTML 标签的值。并且解析简码时使用 wp_kses() 函数进行了过滤,确保输出的内容被编码(代码位于 wp-includes/media.php):</p><pre>— wp-includes/media.php
+++ wp-includes/media.php
@@ -863,6 +863,8 @@
$content = $matches[1];
$attr[‘caption’] = trim( $matches[2] );
}} elseif ( strpos( $attr[‘caption’], ‘<’ ) !== false ) {
$attr['caption'] = wp_kses( $attr['caption'], 'post' );
}
/**
</pre><p>这样一来就很难利用上面所说的 "KSES"和简码解析前后处理差异 成功构造出能够进行 XSS 的 HTML 标签了。</p>