Linux Desktop Remote Code Execution via File URI

March 27, 2015 by Noah
I've discovered a sort of "remote code execution" vulnerability that affects all Linux desktops, particularly Fedora and Ubuntu but most likely all desktop Linux distributions could be affected, except for maybe Arch or Gentoo with extremely customized installations.

First and foremost: this requires the victim to click not one, but two random links sent to them over Pidgin (or any other program that does URL auto-linking the way Pidgin does). So it's not exactly the most severe vulnerability, but I found it interesting nonetheless.

Demonstration video:

Key Ingredients

A few different parts are responsible for this:

Application Launchers (.desktop files)

Graphical desktop environments use .desktop files as their application launchers. They're plain text, INI-style files that describe the application's name, icon, and executable command.

A vulnerability was discovered a while back about Application Launchers, wherein a launcher file could be double-clicked on and it would run the command inside, in exactly the same way that a .exe file can be double-clicked on Windows. And, like its Windows counterpart, it was easy to accidentally double-click an application launcher that you didn't intend to.

In the linked article's example, you could attach a .desktop launcher to an e-mail in much the same way as a virus would, and a careless Linux user could accidentally run it just as easily.

In response, all of the Linux desktop environments made a change, so that you must explicitly mark an application launcher as "executable" before it can be double-clicked to run. Trying to run a non-executable launcher would result in a warning pop-up, telling you that the launcher is not trusted and giving you options to mark it executable, launch it anyway, or cancel.

Pidgin (well, not just Pidgin)

I'm only picking on Pidgin here but other apps are possible attack vectors here.

Pidgin will take any text that looks like a URL, in the format protocol://urlpath and make it into a clickable link. This includes file://, but thankfully does NOT include javascript:.

On Linux desktops, the underlying mechanism Pidgin uses is xdg-open, which is the Linux version of the open command on Mac OS X, or rough equivalent of the start command on Windows. It will open anything using your preferred application, for example HTTP URLs will open in your default browser, text files in your default text editor, etc.

Also, Adium does the same thing for the Mac OS X users; have fun poking at that.'s xdg-open

Pidgin is only guilty as far as making file:// URIs clickable; xdg-open is the next part.

These were some of the behaviors I've seen with xdg-open and what kinds of file:/// links work in Pidgin:

  • A link to a binary executable file (file:///usr/bin/gedit) would execute the program on click.
  • However, a link to an executable text file/shell script (file:///usr/bin/firefox -- a shell script), would NOT execute when clicked. Nothing would happen.
  • A link to a file of a known type would open that file in your preferred program.
But most interestingly, xdg-open will execute an application launcher (.desktop) even when it isn't marked as executable.

The Perfect Storm

Put all of these together and here's an attack path:

  1. Send the victim an HTTP link to a URL that forces a download of an application launcher .desktop file, by using the Content-Disposition: attachment response header (this would likely need to be done via a PHP or CGI script).
  2. Victim clicks the link. Google Chrome and Chromium will automatically download the launcher with no prompt. Firefox will ask to open it or save it. On most Linux desktops, the download will go into ~/Downloads in their home folder.
  3. Send the victim a file link to the launcher in their Downloads folder, like file://Downloads/Pwned.desktop
  4. Victim clicks on the file link and the launcher executes and can run whatever code it wants.
  5. ???
  6. Profit
The CGI script that forces the application launcher download can be as simple as this:

#!/usr/bin/env python

print """Content-Type: application/octet-stream
Content-Disposition: attachment; filename=Pwned.desktop

[Desktop Entry]
Exec=/usr/bin/bash -c 'echo "I pwned you :)" | /usr/bin/gedit -'

Bug Tickets?

Pidgin should be aware of this problem because it's come up multiple times for them and yet they're still doing it on Pidgin v2.10.11

For the xdg-open bug I filed a Red Hat bug ticket here. I'm half expecting to get a response back such as, "xdg-open simply forwards the request to your desktop environment's native file opener," but it is what it is.

The Good: AIM blocks file URIs

AOL Instant Messenger seems to block any IMs sent that contain a file:// URI in them. When I was initially testing this, I was sending IMs to myself and noticed that any time I used a file URI, I didn't get my own message echoed back to me. For the proof of concept video, I used my personal XMPP server.


There are 0 comments on this page. Add yours.

Add a Comment

Used for your Gravatar and optional thread subscription. Privacy policy.
You may format your message using GitHub Flavored Markdown syntax.