WordPress 4.1.2 / 4.2.1 XSS Vulnerability

28 Apr 2015 - evi1m0

这两个漏洞相继在 cedricvb 和 fd 报告出来后似乎并没有引起广泛的关心,平静了两天后国内各公司媒体才开始宣传爆漏洞了,爆漏洞了,原因可能由于从海外漂过来需要点儿时间,另外不少安全研究人员觉得利用起来鸡肋,其实还是很好利用的。我花费了大好睡眠时光搞定了完美的攻击载荷,所以文章只进行简单的分析和说下大致思路,不开放最终攻击代码。

WordPress Database Schema:
WordPress <4.1.2 Stored XSS:

关于这两个跨站漏洞都比较有趣,<4.1.2 XSS 是由于 WordPress 使用了 utf8mb4 ,但是 MySQL 默认配置为 utf8 。(其中对 utf8mb4 字符集的支持是 MySQL 5.5 的新功能,支持了存储4字节的 emoji 表情。)所以当我们将4字节字符插入数据库中时,会被 MySQL 自动认定是 utf8mb4 编码,因为数据库默认为 MySQL utf8,所以在数据存储时(MySQL 非strict mode)会造成截断。

不得不说 WordPress 这次真是可爱到傻瓜,当我们将标签截断闭合后,WP 标签的引号被转义,导致了我们可以自定义标签属性,WordPress 默认评论留言版支持:

 <a href="" title=""><abbr title=""> <acronym title="">
 <b> <blockquote cite=""> <cite> <code> <del datetime="">
 <em> <i> <q cite=""> <strike> <strong>

这些标签足够让我们完成 XSS 攻击了,例如我们插入:

<abbr title="test onmouseover=alert(1)// 𝌆">evi1m0

HTML 会被解析为:

<abbr title=&#8221;test onmouseover=alert(1)// </p>

浏览器:

<abbr title="”test" onmouseover="alert(1)//" <="" p="">
                            </abbr>

导致我们成功的插入了一条带有 on 事件的标签进去,之后会谈一下为什么这段 Payload 在不同的 WordPress 里面会导致有一定几率触发,有一定几率失效。

WordPress <4.2.1 Stored XSS:

第二个 <4.2.1 版本的跨站漏洞则是继续利用 MySQL 的特性来完成攻击的,根据文章开始时的 WordPress Database Schema 图可以看到,wp_comments –> comment_content 字段存储格式为 TEXT ,MySQL 的 TEXT 类型最大上限为 65535 字节,所以当存储值超过 65535 字节时会对后面进行截断操作,可爱的 WP 并未对评论字数进行限制导致我们可以利用这样一条 Payload 插入恶意标签事件:

<a href='x onclick=alert(1) AAAAAAAA...(<64k bytes)'>Evi1m0</a>

解析后的数据看起来像这样:

<p><a href='x onclick=alert(1) AAAAAAA...</p>

插曲: 在 64k XSS 官方修复后,有趣的是 TSRC 绕过了官方补丁。

FIX
END

WordPress 会对从未评论过的用户第一条进行评论审核操作,经过审核后之后的评论就不需要再次经过审核,这也是很多人说稍有鸡肋的地方,其实仔细想想这不是问题。 =)

两个极简版 PoC :

有关上面几个简短的 Payload 在测试时我发现不同 WordPress 下有些不能触发,原因是不同的程序模板对评论标签的 CSS 样式不同,导致很多情况下我们是无法触碰到评论内容区域的,所以我们可以通过自定义 CSS 样式完成这个操作,例如:

style='position:fixed;top:0;left:0;width:100%;height:100%'

当然上面这个并不是完美的 CSS 兼容样式,如果你想通杀所有浏览器的话还需要自己简单的修改一下。

另外 phithon 在博客中给出使用 tabindex onfocus 这种方法来进行直接触发事件,这种方法在 13 年底有过几次经典案例及 CTF 题目,原理:在任意标签上加tabindex即可让这个标签可以被TAB选中,于是就有了onfocus事件。然后用类似于锚的方式来替代按键TAB,访问#id(以上payload中id=a,所以是#a)即可触发;

tabindex 这种方法需要在评论页面链接后面加入描点以达到触发的目的,可能在实战中需要配合些社工成分。

<abbr title="aassx id=a tabindex=0 onfocus=alert(1)//

由于 WordPress 使用广泛历史久远,导致我没想到这种简单 Fuzz 就可能会发现的安全问题会在它身上出现,深感惭愧。

评论插件使用 Disqus ,需翻墙才能查看及留言。