Bringing Up the Past
I mentioned previously that the adb shell is an ASH shell without auto-completion, inline editing, or command history. In other words, this car is a base model without all the bells and whistles with which you might be accustomed. Add to that a limited set of binary tools (no copy, tar, or find commands, for example) and its a bit like standing at the base of a cliff without any climbing tools.
Plan of Attack
We need tools, and we need them bad. But we don't want to change any more data on the phone than necessary. So, what to do?
Android phones use SD cards to store user media, like photos and music. This card should be removed and imaged, following standard forensic imaging protocols, as part of your examination. While the card can be imaged from within the phone, the interface is slow (took 45 minutes to image 16gb) and requires that the phone be placed in USB mass storage mode for the workstation to see it. A locked phone may make this impossible.
Significantly, removing the card allows us to replace it with one of our own containing tools for accessing data in the phone's internal memory. You can get by quite handily with one small tool: busybox.
You can copy busybox to the card before inserting it in the phone, but its not a necessity. You can also use the Android Debug Bridge (adb) utility to copy busybox to an installed card using the command:
# adb push busybox /sdcardFinally, the card you use should have enough space to capture the full internal memory of the phone. The adb shell allows us to copy files within the device, but not to our workstations. So, we must copy files to the SD card.
The size of our SD card can very, depending on the amount of physical memory found in the phone. This can be quite small, as in the case of the original Motorola Droid which has only 256mb of internal storage. However newer devices, like the Droid 2, have significantly more memory with 8gb of internal storage capacity.
Sequential Processing: Starting with "dd"
I'm experienced in fingerprint development as well as computer forensics. In fingerprint processing, there is a phenomenon known as "Sequential Processing." Sequential processing simply means to do processing in such an order so that the first step does not inhibit the second step, and so on. We actually do this every day in computer forensics: we image a device before before we conduct an examination, and we use the image for the examination so as to not harm the original evidence.
It is my opinion that we should do physical imaging of the device before logical. The device we are working on has a running operating system and files are changing and being created and deleted as part of the normal process of the phone. Further, a physical image means we can recover deleted files, so we want the physical images before we do anything that could overwrite data. "dd" is the tool of choice here, and it can be deployed quickly (it is part of the resident operating system) and there is no set up involved, i.e., remounting of partitions.
- Root the device. See my previous post if you don't know what I'm talking about.
- Start the adb shell if its not already running. Look for the telltale root prompt to be sure you have "rooted" the device.
# adb shell
# <-- adb shell prompt
- Determine the devices you want to image. In Android, the devices are called mtdblock devices, and are listed in /proc/mtd.
# cat /proc/mtd
dev: size erasesize name
mtd0: 00180000 00020000 "pds"
mtd1: 00060000 00020000 "misc"
mtd2: 00380000 00020000 "boot"
mtd3: 00480000 00020000 "recovery"
mtd4: 08c60000 00020000 "system"
mtd5: 05ca0000 00020000 "cache"
mtd6: 105c0000 00020000 "userdata"
mtd7: 00200000 00020000 "kpanic"
- Ideally, we want to image everything. But of particular interest are the "cache" and "userdata" block devices. The size of each device is listed in hexadecimal code. In the above case, the "cache" device is 97124352 bytes [echo $((0x5ca0000))], and the "userdata" device is 274464768 bytes [echo $((0x105c0000))]. We need to know how the devices are addressed:
rootfs / rootfs ro,relatime 0 0
/dev/block/mtdblock4 /system yaffs2 ro,relatime 0 0
/dev/block/mtdblock6 /data yaffs2 rw,nosuid,nodev,relatime 0 0
/dev/block/mtdblock5 /cache yaffs2 rw,nosuid,nodev,relatime 0 0
/dev/block/mtdblock0 /config yaffs2 ro,relatime 0 0
- We see that the "cache" mtdblock device is addressed as /dev/block/mtdblock5 and "userdata" as /dev/block/mtdblock6. We can make a dd image of each as follows:
# dd if=/dev/block/mtdblock5 of=/mnt/sdcard/cache.dd
189696+0 records in
189696+0 records out
97124352 bytes transferred in 24.001 secs (4046679 bytes/sec)
# dd if=/dev/block/mtdblock6 of=/sdcard/data.dd
/dev/block/mtdblock6: read error: I/O error
83808+0 records in
83808+0 records out
42909696 bytes transferred in 8.653 secs (4958938 bytes/sec)
Uh, oh, an error. Normally, we overcome dd errors by adding the "conv=noerror" argument, which tells dd to continue on read error. But the Android dd does not support that option. So, what do we do in such a circumstance? Give up? Hardly!
Phase Two: Busybox
Busybox can be described as "the swiss army knife of embedded Linux." It is a single executable file, about 1mb in size, containing many common Unix utilities, including cp, find, tar, and yes, dd! In order to use it, we need a version compiled for Android, but I will not discuss how to compile here. It is readily available on the Web and in Android Root kits, but I'd recommend compiling a trusted version if you can. One things certain, you cannot use the busybox binary from your workstation.
There's a catch to using busybox. We want to place it on our SD card so we don't change anything on the phone's internal memory, but busybox cannot be run from the SD card. "Why?" you ask. I'll show you:
/dev/block/vold/179:1 /mnt/sdcard vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
So, to make the busybox on the SD card executable, we need to remount the card with the ability to execute binary files.
- If busybox was not already on your card, push it to the card from a terminal on your workstation.
# adb push busybox /mnt/sdcard
1255 KB/s (1745016 bytes in 1.356s)
- Remount your card with executable permission.
# adb shell
# mount -o remount,rw /mnt/sdcard /mnt/sdcard
/dev/block/vold/179:1 /mnt/sdcard vfat rw,dirsync,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
- Change directories to the SD card and optionally start a busybox shell. By starting a busybox shell, we attain inline editting and a shell history. In other words, entering commands becomes easier.
# cd /mnt/sdcard
# ./busybox sh
- Now we can dd that damaged "userdata" mdtblock again, this time passing conv=noerror because we will use the busybox dd. Note: because busybox is not installed on the system or in the path, we have to prepend busybox utilities with ./busybox
. To see a list of available busybox tools, issue "./busybox" alone.
# ./busybox dd if=/dev/block/mtdblock6 of=/mnt/sdcard/data.dd conv=noerror
- With busybox, we can also create archives of the logical files on the device. Again, to simplify the discussion, we'll focus on the /cache and /data directories where we saw the respective mtdblock devices were mounted. Why should we archive the logical files when we have physical images made with dd? Because the file systems in the images are "yaffs" and present special problems I won't discuss here. It is enough to say, for now, that your workstation likely doesn't support yaffs by default and you cannot mount and examine the images you created. They are only useful file carving.
Therefore, we'll use tar to make archives of the /cache and /data directories.
# ./busybox tar czvf cache.tar.gz /cache
tar: removing leading '/' from member names
# ./busybox tar czvf data.tar.gz /data
tar: removing leading '/' from member names
Wrapping Things Up
When you've acquired the images/files that you seek, you need to get the data from the SD card to your workstation. The easiest way is to turn off the phone and remove the card, the read it directly. But you can pull the files from the card with adb, too. You might want to do this if you need the data quickly, or to free up space on a smaller card for more images/archives. To pull the files from the card to your workstation:
- Use "adb pull" to move files from the SD installed in the phone to your workstation. The command is run in a terminal on your workstation, NOT in the adb shell. You can exit adb shell or open a new terminal window if you want to remain in the adb shell environment.
# exit <-- exits the busybox shell
# exit <-- exits the adb shell to your terminal
# adb pull /mnt/sdcard/cache.tar.gz /some/evidence/directory/
# adb pull /mnt/sdcard/cache.dd /some/evidence/directory/
- When you are done pulling all the files you plan to transfer, remove the exploit from the install directory.
# adb shell rm /data/local/tmp/ratc.bin
Note: I chose this method of removing the exploit to demonstrate that the adb shell command can pass arguments to the adbd daemon on the phone without dropping into the shell. I hope to use this ability to script the process we've been discussing.
- Reboot the phone to kill the exploit and the phone is back in its pre-exam condition.
I'll leave the examination of the data you've recovered to you for now. Maybe in a future post, I'll highlight some key files and how to process them (hint: mmssms.db contains text messaging, and cache.cell contains GPS data).