It's Bugs All the Way Down

Security Research by Dan Rosenberg

Rooting the Sony Tablet S

After getting a taste of rooting tablets with the Lenovo Thinkpad tablet, I decided to turn my attention to the Sony Tablet S. It turned out to be a tough device to root.

The Bug

The Sony Tablet S has a logging service running as root named nfx_log_service. This service maintains on-disk backups of the Android logcat buffers in the /log directory. This directory is group-writable and group “log”, which is granted to the ADB shell, so we can modify files in this directory.

The logging service uses predictable filenames for its output. Specifically, “Kernel.txt”, “AndroidMain.txt”, “AndroidEvent.txt”, and “AndroidRadio.txt” are used. As you might expect, by replacing these files with symbolic links, it’s possible to cause the logging service to either create a new file containing the contents of the appropriate log buffer, or if the symlink is in place at boot time, append the appropriate log buffer to an existing file. These files are created as root:root 0644, so once they are created we do not have the ability to control their contents.

The Goal

Normally, I’d go straight for victory by creating a symlink at one of the logfile locations (I chose “/log/AndroidRadio.txt“) to /data/local.prop and writing “ro.kernel.qemu=1″ a whole bunch of times to the radio log. This would cause /data/local.prop to be created containing the ro.kernel.qemu property, so that when I reboot the device ADB runs as root and it’s game over.

Unfortunately, that doesn’t quite work here. The Sony Tablet S already has a /data/local.prop file, and worse, it’s actually a symlink to /configs/local.prop. Since /configs is a read-only mountpoint, we won’t be able to overwrite this file. However, if we could remove the existing /data/local.prop, we could create a new file there that sets the ro.kernel.qemu property and allows us to win. But how can we use our logger vulnerability to remove a file?

Trickiness

It turns out the Android package manager has an interesting behavior. Packages have data directories at /data/data/[package]/. Ordinary packages have a lib directory in the data directory for native libraries. However, system packages (like the ones installed by Google or the OEM, in this case Sony) are not expected to have libraries in this directory. If any system package has files in its /data/data/[package]/lib/ directory, those files are deleted on boot by the package manager. Interestingly, this includes following symlinks. So if we can somehow cause a system package’s data folder to contain a symlink at /data/data/[package]/lib that points to /data, then the /data directory will be erased on boot, wiping out /data/local.prop and allowing us to create a new one and gain root.

Android devices contain a program called “run-as” that allows the ADB shell to assume the privileges of any application that is marked as “debuggable”. This is determined by checking the /data/system/packages.list file, which contains a list of packages, their uids, the debuggable flag, and their data directories. For the exploit, we can pick any system application – I chose com.google.android.location.

We can use our logging vulnerability by creating a symlink at /log/AndroidRadio.txt that points to /data/system/packages.list, rebooting the device, and running a program that logs packages.list lines for a fake application that’s marked as debuggable with the same uid as this system application. For example, I used:

com.pwn.me 10026 1 /data/data/com.google.android.location

In this case, 10026 was the uid of com.google.android.location. This might vary based on device. At this point, the logging service appends this line to packages.list, and we can “run-as com.pwn.me”, at which point we have the privileges of our system package. We can then replace the system package’s lib directory with a symlink to /data, reboot the device, exploit the logger again to create a fresh /data/local.prop containing the line “ro.kernel.qemu=1″, and reboot again, at which point ADB is running as root and we can install su and Superuser.

The Final Product

A script that automates these steps on Windows is available here. To run it, ensure your device is in USB debugging mode, connect it via USB, extract the zip, and run “run.bat”. Enjoy!

If you were involved in raising a bounty for this exploit, donations can be made below.









This entry was posted on Wednesday, February 8th, 2012 at 2:43 pm and is filed under Android, Exploitation. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.