Installing Dropbox? Prepare to lose ASLR.

Dropbox has become a daily part of my life. I rely on it to synchronise data between my growing set of devices. But how much of an impact does it have on the security of my system? I decided to find out by digging around in exactly what it does to my machine, or more specifically, the processes running on it.

The first thing I want to check out is what modules are loaded into various processes. Tools like Dropbox like to extend the functionality of other programs using shell extensions, which are nothing more than specially designed DLLs loaded into process memory. Let’s see what we’ve got…

Dropbox Files

Interesting! Looks like we’ve got two extension DLLs, one 32-bit and one 64-bit. These are likely used to add extra context menu options when right-clicking on files. Now let’s find out where they get injected. For this, we’ll use good ol’ trusty Process Explorer. By going to Find » Find Handle or DLL, we can search for the DLLs in running processes.

Dropbox DLL Injection

It looks like it’s being loaded into processes that have windows created, which implies it’s probably an AppInit DLL, but it turns out not to be the case – the registry key doesn’t contain that DLL. This implies that there’s something more active going on, and that Dropbox actively selects which processes to inject into. I may be mistaken here, I’m not sure. Either way, though, it’s a little odd that it chose to inject into Notepad++ and other innocuous processes.

(Update: thanks to zeha and 312c on Reddit for pointing out that it’s likely injected via the standard file browser shell, due to the Dropbox icon in the favourites list)

The biggest problem becomes clear when you take a look at the module in a running process. In this case, it’s Firefox:

Dropbox in Firefox

Notice that the Dropbox extension DLL doesn’t have the ASLR flag set. This means that any vulnerability in Firefox becomes a lot easier to exploit, since the Dropbox module provides an unrandomised anchor for a ROP chain. Ignore PowerHookMenu.dll here – I’m aware of that issue and have notified the developer, but it’s infrequently seen on people’s machines so it’s not so bad.

Let’s just quickly verify that the DLL isn’t ASLR enabled at all, by checking the DLL characteristics flags in the file…

ASLR disabled for DLL

Definitely not enabled.

Anyway, the take-away issue here is that Dropbox arbitrarily injects an ASLR-disabled DLL into various 32-bit and 64-bit processes, causing significant degradation in the efficacy of ASLR across the entire system. With no ASLR, an attacker could craft an exploit payload that utilises executable code within the injected DLL to product a ROP chain, leading to code execution. This is significantly problematic in high-risk programs like web browsers and torrent clients.

I notified Dropbox of this back when version 1.0.0.17 was the latest version, but got not response. I’ve since tried again, but had no luck. I’m hoping that going public will give them the kick they need to get it fixed. In the meantime, a good mitigation is to install EMET and set a policy to enforce Mandatory ASLR. All of this was re-tested against Dropbox 2.0.22, with versions 1.0.0.19 of both the 32-bit and 64-bit DLLs. The operating system used was Windows 7 x64 SP1.

Update: Brad “spender” Spengler (of grsec fame) has noted that the latest version of Dropbox has ASLR enabled for the 64-bit DLL, but still doesn’t on 32-bit.

Update 2: Dropbox responds: “Our engineers are aware of this issue and actively working on fixing it. Unfortunately, I can’t give you an exact timeline that a fix will become available. If you have any additional questions or concerns please let me know.”

Update 3: @_sinn3r has done some awesome work on the exploitability of these issues, over at Metasploit. Definitely worth a read.

Advertisements

The Router Review: From nmap to firmware

When I moved into my flat, I found that the previous tenant had left behind his Sky Broadband router. Awesome – a new toy to break! Sadly I got bogged down with silly things like moving house and going to work, so I didn’t get a chance to play with it. Until now, that is.

This isn’t the first embedded device I’ve played with. Over the years I’ve desoldered EEPROMs from routers, done unspeakable things to photocopiers, and even overvolted an industrial UPS unit via SNMP. The router I shall be discussing in this post, however, was one of the easier and more generic bits of kit I’ve played with.

Now, a little about the device. The model is DG934, and the full part number is 272-10452-01. It’s an ADSL router supplied by Sky (also known as BSkyB) as part of their old broadband package, but it’s actually manufactured by Netgear. It’s got four ethernet ports, an ADSL (phone) port, and takes a 12V power supply. Internally, it runs on the Atheros chipset. Unfortunately, this being a UK-only device, there’s no FCC ID – if there had been, I could’ve looked it up on the FCC OET database and found all sorts of internal photos and test data, which is often valuable when looking at the hardware aspects.

My first job was to power it on and get into the config panel. Since the previous tenant clearly wasn’t security conscious, he’d kindly left the device in its default configuration and I was able to log into the configuration interface using the default admin / sky credentials. I exported the config file to my machine, and took a look. In this case it’s plaintext, so there’s nothing to break here, but it’s not exactly good practice – it includes the passwords for WiFi and the configuration interface.

I ran nmap against the device and got the following results:

PORT      STATE SERVICE VERSION
80/tcp    open  http    BSkyB DG934G http config
5000/tcp  open  sip     BSkyB/1.0 UPnP/1.0 miniupnpd/1.0 (Status: 501 Not Implemented)
8080/tcp  open  http    BSkyB DG934G http config
32764/tcp open  unknown

Interestingly, the configuration site was available on both 80 and 8080. This seems to be the norm for many routers, but I have no idea why. UPnP on port 5000 is always a fun one to spot, and we’ll take a look at this shortly. Finally, there’s an unknown protocol running on port 32764.

For messing with UPnP, I have the UPnP Developer Tools for Windows. They’re mainly written in C# and are open source, so you can always port to Mono if you want. I used Device Spy to get the following info:

  • It’s a BSkyB DG934 Router.
  • The firmware date is 2007-08-27.
  • You can pull out stats such as total bytes sent/received, total packets sent/received, and uptime in seconds.
  • Port mapping functions are available.
  • SetEnabledForInternet isn’t present – shame, really, since it leads to a nice DoS condition.

Sadly there’s not much you can play with here.

Next, we’ll take a look at that weird unknown protocol on port 32764. When connecting to it, the string “MMcS” is returned, along with two binary IP representations: 255.255.255.0 and 0.0.0.0. I tried playing around with this, but honestly I have no idea what it’s for. Google returned a bunch of people asking what it was, and nobody with any real answers. Potentially it’s for Multimedia Class Schedule Server, but that’s speculation at best. Again, no luck at fun stuff here.

Finally, let’s dig into the firmware. Instead of taking the device apart, desoldering the firmware EEPROM, and interfacing to it with a BusPirate to rip the data off, I decided to go the easy route and download the openly available firmware from Netgear. The file provided is a flat binary, with some interesting data inside it. It’s partitioned into various sections, with conveniently obvious data offsets (e.g. 0x10000). In order to properly dissect the file, I used binwalk. In BackTrack 5 it’s located in /pentest/reverse-engineering/binwalk/ and requires you to manually set the magic file via the -m switch.

root@bt:~# binwalk -m /pentest/reverse-engineering/binwalk/magic.binwalk ~/dg834gt_1_02_09.img
DECIMAL HEX DESCRIPTION
-------------------------------------------------------------------------------------------------------
:1248 0x4E0 CFE boot loader
1288 0x508 CFE boot loader
4177 0x1051 LZMA compressed data, properties: 0xA4, dictionary size: 285474816 bytes, uncompressed size: 256 bytes
7951 0x1F0F LZMA compressed data, properties: 0xC2, dictionary size: 556793856 bytes, uncompressed size: 67108881 bytes
8087 0x1F97 LZMA compressed data, properties: 0x82, dictionary size: 556793856 bytes, uncompressed size: 67108881 bytes
8227 0x2023 LZMA compressed data, properties: 0xC2, dictionary size: 556793856 bytes, uncompressed size: 67108881 bytes
8371 0x20B3 LZMA compressed data, properties: 0x82, dictionary size: 556793856 bytes, uncompressed size: 67108881 bytes
10563 0x2943 LZMA compressed data, properties: 0xDF, dictionary size: 555220992 bytes, uncompressed size: 167272448 bytes
65792 0x10100 CramFS filesystem, big endian size 2879488 version #2 sorted_dirs CRC 0x51df60ff, edition 0, 1975 blocks, 938 files
1016865 0xF8421 ARJ archive data, v193, backup, original name: \230\346+\210\365 ... [snip]

This gives us a pretty good idea of what we’re dealing with. First, there’s a Common Firmware Environment (CFE) bootloader, which is Broadcom’s alternative to U-Boot. There’s some irony here in that Broadcom and Atheros are competitors, yet CFE is being used on an Atheros chipset device. Anyway, there’s a bunch of LZMA junk after that which looks like various bits of firmware and a Linux kernel image. The bit we’re really interested in is the CramFS data. As a side note here, it looks like binwalk was a bit overzealous in identifying an ARJ archive at the end (hence the corrupted original name) so we can assume that the CramFS block takes up the remainder of the file.

In order to extract the filesystem, we can use good old dd. The following should suffice:

dd size=256 skip=257 count=20000 if=dg834gt_1_02_09.img of=firmware.cramfs

Note that 257 * 256 = 65792, which is 0x10100, i.e. the offset of the data we want to pull out. I stuck a really big count in there because we’re reading to the end of the file. Now, you’re going to want to grab some tools to work with CramFS:

sudo apt-get install cramfsprogs fusecram

This provides you with the modules needed to mount CramFS volumes, as well as some tools to help you along the way. Now we can mount the filesystem:

root@bt:~# sudo mount -t cramfs -o loop ~/firmware.cramfs /media/firmware/
mount: wrong fs type, bad option, bad superblock on /dev/loop1,
missing codepage or helper program, or other error
In some cases useful info is found in syslog - try
dmesg | tail or so

Hmmm, that’s odd. Let’s see what dmesg has to say about this…

root@bt:~# dmesg | tail -n 1
[ 4394.319907] cramfs: wrong endianess

Aha! A fun fact about CramFS is that file systems have endianness as per the architecture they were created on. Since the router is big-endian and my box is little-endian, I need to convert it. Thankfully, cramfsprogs includes a tool called cramfsswap that flips the endianness of a provided image. Side note: if you get “wrong magic” as an error, you didn’t extract the right blocks of data, or the file system isn’t CramFS.

root@bt:~# cramfsswap ./firmware.cramfs ./firmware-conv.cramfs
Filesystem is big endian, will be converted to little endian.
Filesystem contains 937 files.
CRC: 0xe86ad3b0
root@bt:~# sudo mount -t cramfs -o loop ~/firmware-conv.cramfs /media/firmware/
root@bt:~#

Excellent! Now to dig around inside the files.

root@bt:~# ls -l /media/firmware/
total 20
drwxr-xr-x 1 root root 452 1970-01-01 01:00 bin
drwxr-xr-x 1 root root 0 1970-01-01 01:00 dev
lrwxrwxrwx 1 root root 8 1970-01-01 01:00 etc -> /tmp/etc
drwxr-xr-x 1 root root 784 1970-01-01 01:00 lib
drwxr-xr-x 1 root root 0 1970-01-01 01:00 proc
drwxr-xr-x 1 root root 176 1970-01-01 01:00 sbin
drwxr-xr-x 1 root root 0 1970-01-01 01:00 tmp
drwxr-xr-x 1 root root 116 1970-01-01 01:00 usr
lrwxrwxrwx 1 root root 8 1970-01-01 01:00 var -> /tmp/var
lrwxrwxrwx 1 root root 8 1970-01-01 01:00 www -> /tmp/www
drwxr-xr-x 1 root root 3900 1970-01-01 01:00 www.deu
drwxr-xr-x 1 root root 3908 1970-01-01 01:00 www.eng
drwxr-xr-x 1 root root 3824 1970-01-01 01:00 www.fre

There’s a full listing on pastebin, if you’re interested. It’s worth noting that if you can mount the filesystem, can see the directories and files inside it, but can’t read the file data, then you probably didn’t copy the entire filesystem and it’s missing chunks of data. Anyway, this looks pretty typical. We can see a very basic file system that comprises all the runtime parts of the device, excluding the kernel and any ramfs stuff. Here’s what I found:

  • The three www prefixed directories contain the template files used for the administration panel.
  • /bin contains busybox binaries.
  • /lib contains the kinds of libraries you’d expect on a router, e.g. libcrypt, libupnp, libpppoe, etc.
  • /lib/modules contains various kernel modules for the router, such as the push button driver and Atheros HAL.
  • /sbin contains various binaries such as ifconfig, insmod, lsmod, etc.
  • /usr/bin contains four binaries, including one called test.
  • /usr/etc contains the default config files and various scripts.
  • /usr/sbin contains various binaries for daemons (including reaim and iptables), as well as some for performing maintenance operations, e.g. WiFi control operations.
  • /usr/upnp contains the definitions for the UPnP endpoint.

The most interesting directory was /usr/etc, which contains both passwd and an svn.info. The passwd file shows only root and nobody, which leads me to believe that all services run as root. The svn.info file has all sorts of interesting info in it:

Path: .
URL: file:///svn/Platform/DG834_PN/Source
Repository Root: file:///svn/Platform/DG834_PN
Repository UUID: 25bc2c04-8815-0410-823d-fa30465ac5aa
Revision: 93
Node Kind: directory
Schedule: normal
Last Changed Author: ethan
Last Changed Rev: 93
Last Changed Date: 2007-02-16 16:23:45 +0800 (Fri, 16 Feb 2007)

Boot Loader version: CFE version 1.0.37-5.11 for BCM96348

So we now know that Netgear use(d) SVN for their source control, that “Ethan” is the guy developing the firmware for the DG834, and that we’re running CFE 1.0.37-5.11 on the BCM96348 SoC IC. Hi, Ethan!

I’m going to leave this here for now, primarily because it’s almost 4am, but also because the point of this blog post was to show just how much information you can dig out of a device without even touching it with a screwdriver, or opening a manual. Keep in mind that the techniques I’ve shown here should apply to many routers and other small embedded devices. At some point in the future I’ll get around to digging into some of their custom binaries, as well as their HTTPD. If I find anything interesting, I’ll be sure to post an update. Also, let me know if you’ve got any spare routers you want me to dig into when I get a spare few hours – I’m always happy to take donations!