In this article by Rohit Tamma and Donnie Tindall, authors of the book Learning Android Forensics, we will cover physical data extraction using free and open source tools wherever possible. The majority of the material covered in this article will use the ADB methods.
(For more resources related to this topic, see here.)
The dd command should be familiar to any examiner who has done traditional hard drive forensics. The dd command is a Linux command-line utility used by definition to convert and copy files, but is frequently used in forensics to create bit-by-bit images of entire drives. Many variations of the dd commands also exist and are commonly used, such as dcfldd, dc3dd, ddrescue, and dd_rescue. As the dd command is built for Linux-based systems, it is frequently included on Android platforms. This means that a method for creating an image of the device often already exists on the device!
The dd command has many options that can be set, of which only forensically important options are listed here. The format of the dd command is as follows:
dd if=/dev/block/mmcblk0 of=/sdcard/blk0.img bs=4096 conv=notrunc,noerror,sync
- if: This option specifies the path of the input file to read from.
- of: This option specifies the path of the output file to write to.
- bs: This option specifies the block size. Data is read and written in the size of the block specified, defaults to 512 bytes if not specified.
- conv: This option specifies the conversion options as its attributes:
- notrunc: This option does not truncate the output file.
- noerror: This option continues imaging if an error is encountered.
- sync: In conjunction with the noerror option, this option writes x00 for blocks with an error. This is important for maintaining file offsets within the image.
Do not mix up the if and of flags, this could result in overwriting the target device!
A full list of command options can be found at http://man7.org/linux/man-pages/man1/dd.1.html.
Note that there is an important correlation between the block size and the noerror and sync flags: if an error is encountered, x00 will be written for the entire block that was read (as determined by the block size). Thus, smaller block sizes result in less data being missed in the event of an error. The downside is that, typically, smaller block sizes result in a slower transfer rate. An examiner will have to decide whether a timely or more accurate acquisition is preferred.
Booting into recovery mode for the imaging process is the most forensically sound method.
Determining what to image
When imaging a computer, an examiner must first find what the drive is mounted as; /dev/sda, for example. The same is true when imaging an Android device. The first step is to launch the ADB shell and view the /proc/partitions file using the following command:
The output will show all partitions on the device:
In the output shown in the preceding screenshot, mmcblk0 is the entirety of the flash memory on the device. To image the entire flash memory, we could use /dev/blk/mmcblk0 as the input file flag (if) for the dd command. Everything following it, indicated by p1– p29, is a partition of the flash memory. The size is shown in blocks, in this case the block size is 1024 bytes for a total internal storage size of approximately 32 GB. To obtain a full image of the device’s internal memory, we would run the dd command with mmcblk0 as the input file.
However, we know that most of these partitions are unlikely to be forensically interesting; we’re most likely only interested in a few of them. To view the corresponding names for each partition, we can look in the device’s by-name directory. This does not exist on every device, and is sometimes in a different path, but for this device it is found at /dev/block/msm_sdcc.1/by-name. By navigating to that directory and running the ls -al command, we can see to where each block is symbolically linked as shown in the following screenshot:
If our investigation was only interested in the userdata partition, we now know that it is mmcblk0p28, and could use that as the input file to the dd command.
If the by-name directory does not exist on the device, it may not be possible to identify every partition on the device. However, many of them can still be found by using the mount command within the ADB shell. Note that the following screenshot is from a different device that does not contain a by-name directory, so the data partition is not mmcblk0p28:
On this device, the data partition is mmcblk0p34. If the mount command does not work, the same information can be found using the cat /proc/mounts command. Other options to identify partitions depending on the device are the cat /proc/mtd or cat /proc/yaffs commands; these may work on older devices. Newer devices may include an fstab file in the root directory (typically called fstab.
Writing to an SD card
The output file of the dd command can be written to the device’s SD card. This should only be done if the suspect SD card can be removed and replaced with a forensically sterile SD to ensure that the dd command’s output is not overwriting evidence. Obviously, if writing to an SD card, ensure that the SD card is larger than the partition being imaged.
On newer devices, the /sdcard partition is actually a symbolic link to /data/media. In this case, using the dd command to copy the /data partition to the SD card won’t work, and could corrupt the device because the input file is essentially being written to itself.
To determine where the SD card is symbolically linked to, simply open the ADB shell and run the ls -al command. If the SD card partition is not shown, the SD likely needs to be mounted in recovery mode using the steps shown in this article, Extracting Data Logically from Android Devices.
In the following example, /sdcard is symbolically linked to /data/media. This indicates that the dd command’s output should not be written to the SD card.
In the example that follows, the /sdcard is not a symbolic link to /data, so the dd command’s output can be used to write the /data partition image to the SD card:
On older devices, the SD card may not even be symbolically linked.
After determining which block to read and to where the SD card is symbolically linked, image the /data partition to the /sdcard, using the following command:
dd if=/dev/block/mmcblk0p28 of=/sdcard/data.img bs=512 conv=notrunc,noerror,sync
Now, an image of the /data partition exists on the SD card. It can be pulled to the examiner’s machine with the ADB pull command, or simply read from the SD card.
Writing directly to an examiner’s computer with netcat
If the image cannot be written to the SD card, an examiner can use netcat to write the image directly to their machine. The netcat tool is a Linux-based tool used for transferring data over a network connection. We recommend using a Linux or a Mac computer for using netcat as it is built-in, though Windows versions do exist. The examples below were done on a Mac.
Installing netcat on the device
Very few Android devices, if any, come with netcat installed. To check, simply open the ADB shell and type nc. If it returns saying nc is not found, netcat will have to be installed manually on the device. Netcat compiled for Android can be found at many places online. We have shared the version we used at http://sourceforge.net/projects/androidforensics-netcat/files/.
If we look back at the results from our mount command in the previous section, we can see that the /dev partition is mounted as tmpfs. The Linux term tmpfs means that the partition is meant to appear as an actual filesystem on the device, but is truly only stored in RAM. This means we can push netcat here without making any permanent changes to the device using the following command on the examiner’s computer:
adb push nc /dev/Examiner_Folder/nc
The command should have created the Examiner_Folder in /dev, and nc should be in it. This can be verified by running the following command in the ADB shell:
Now that the netcat binary is on the device, we need to give it permission to execute from the ADB shell. This can be done as follows:
chomd +x /dev/Examiner_Folder/nc
We will need two terminal windows open with the ADB shell open in one of them. The other will be used to listen to the data being sent from the device.
Now we need to enable port forwarding over ADB from the examiner’s computer:
adb forward tcp:9999 tcp:9999
9999 is the port we chose to use for netcat; it can be any arbitrary port number between 1023 and 65535 on a Linux or Mac system (1023 and below are reserved for system processes, and require root permission to use). Windows will allow any port to be assigned.
In the terminal window with ADB shell, run the following command:
dd if=/dev/block/mmcblk0p34 bs=512 conv=notrunc,noerror,sync | /dev/Examiner_Folder/nc –l –p 9999
mmcblk0p34 is the user data partition on this device, however, the entire flash memory or any other partition could also be imaged with this method. In most cases, it is best practice to image the entirety of the flash memory in order to acquire all possible data from the device. Some commercial forensic tools may also require the entire memory image, and may not properly handle an image of a single partition.
In the other terminal window, run:
nc 127.0.0.1 9999 > data_partition.img
The data_partition.img file should now be created in the current directory of the examiner’s computer. When the data is finished transferring, netcat in both terminals will terminate and return to the command prompt. The process can take a significant amount of time depending on the size of the image.
This article discussed techniques used for physically imaging internal memory or SD cards and some of the common problems associated with dd are as follows:
- Usually pre-installed on device
- May not work on MTD blocks
- Does not obtain Out-of-Band area
Additionally, each imaging technique can be used to either save the image on the device (typically on the SD card), or used with netcat to write the file to the examiner’s computer:
- Writing to SD card:
- Easy, doesn’t require additional binaries to be pushed to the device
- Familiar to most examiners
- Cannot be used if SD card is symbolically linked to the partition being imaged
- Cannot be used if the entire memory is being imaged
- Using netcat:
- Usually requires yet another binary to be pushed to the device
- Somewhat complicated, must follow steps exactly
- Works no matter what is being imaged
- May be more time consuming than writing to the SD
Resources for Article:
- Reversing Android Applications [article]
- Introduction to Mobile Forensics [article]
- Processing the Case [article]