Saturday, May 29, 2010

Droid rooting and security.

When the Droid was first rooted it as done through by exploiting the update process and the update.zip files it used. It should come as no surprise that the root immediately followed the 2.0.1 OTA update, that was really the last piece of the puzzle.

For those unfamiliar, the update.zip files are signed; the very end of the file contains a signature used to validate the file, the signature itself is hidden in a comment and the validation occurs over everything up until that comment. More precisely, the zip file ends in 6 bytes telling you how big the comment is and where the signature is in that comment. This is interesting because zip files are essentially parsed from the end back to the start; the zip parser looks for the end of content directory (EOCD) and uses that to determine the contents of the zip file.

The exploit lies in hiding another EOCD in the comment just before the signature, the following comment basically spells it out:
for (i = 4; i < eocd_size-3; ++i) {
        if (eocd[i  ] == 0x50 && eocd[i+1] == 0x4b &&
            eocd[i+2] == 0x05 && eocd[i+1] == 0x06) {
            // if the sequence $50 $4b $05 $06 appears anywhere after
            // the real one, minzip will find the later (wrong) one,
            // which could be exploitable.  Fail verification if
            // this sequence occurs anywhere after the real one.
            LOGE("EOCD marker occurs after start of EOCD\n");
            fclose(f);
            return VERIFY_FAILURE;
        }
    }

That's part of the actual verification code in Android. Note the typo, they're checking if eocd[i+1] is 0x4b and also 0x06, which means that it will never match, so the verify failure never happens. The only thing that needs to be done is to append an extra EOCD followed by a copy of the original signature and then adjust the 6 bytes at the end of the file. The original contents remain unmodified and validate perfectly, followed by the new zip file data and new EOCD.

Now, there is a limit on how much new zip data you can stuff into a comment; the size of the comment is only stored as two bytes. The trick is understanding that while the original zip data can't be modified, it can be reused; just point to it from the new EOCD. In other words, the amount of data added is simply the amount of modifications made to the original zip.

And so with the 2.0.1 update came an exploit in the form of a new update.zip which installed su. Of course this is now all completely irrelevant, and no longer applies.

The 2.1 update changed the game by introducing a new copy of recovery that patched the bug, and pretty soon new phones were shipping with 2.1 preinstalled.

At the time, the only way to root the phones was to track down a copy of RSD lite, followed by 2.0.1 in the sbf format used by RSD,  install 2.0.1, wipe all data, then use the update.zip exploit to update to a rooted 2.1.

Really? all that work just to install an exploitable version of recovery? The whole point of running RSD was simply to install recovery, so why not streamline the process...

We're now at the emergence of sbf hacking; the sbf is more or less just raw data to be written to the flash from the bootloader. It doesn't depend on exploiting the kernel, nor does it depend on what Android version you're running. It's simply a matter of rebooting the phone into the bootloader, and telling it "write this data to flash"; we can write whatever we want, anywhere in flash. It's not even an exploit, it's a feature Motorola added to the bootloader.

So why don't we have sbf files that contain entire roms, already rooted? Well, technically we can, the reason why we don't is because the community has already developed a set of tools for distributing roms and performing backups. There's no need for another rom format, all that's needed is a way to leverage existing tools, hence the sprecovery sbf.

The sprecovery sbf does one thing, it overwrites recovery with sprecovery; from sprecovery there's full root access via adb and the ability to install any update.zip, even completely unsigned ones -- you don't need to mess with the signatures anymore.

The downside is that sprecovery provides full root access. Rooting the phone currently requires physical access to the phone, you have to be able to hit the button on bootup to drop into the booloader, and you have to use a USB cable and a pc to flash the sbf file. It's intentional; if we'd released a kernel exploit that could give any application root access, there would be some malicious applications on the market using the same exploit and you'd be none the wiser about it. By requiring physical access to root the phone there's a certain level of security, but understand that anyone with physical access to your phone also has root access. If you rather famously leave your phone at a bar or at the gym, that unlock screen isn't going to protect your data; all it takes is a few minutes with a usb cable to access the entire contents of the phone.