Thursday, August 9, 2012

File "Cliffs" Notes: Abbreviating File Reads

Sometimes a forensics task is pretty narrow.  Determining file type means reading the first few 10's of bytes in most cases.  Luckily there are tools that do just that.  But for other tasks we might face, our standard tools don't really give us a method for narrowing their scope.  You might want to search files for a string that you expect to find in the first 1000 bytes of the file.  Grep will allow you to stop searching a file once the string is found, but it won't stop searching until it finds the match.  This might not seem like a big deal until you consider large files like videos.  You really want to search 1k of data, but you end up searching 2 GB!

Head

The head command is used to output the first part of a file.  By default, it outputs the first 10 lines of a files (best when applied to text files), but it can be used to output a user-defined amount of bytes.
$ head -c 1000 file # Export the first 1000 bytes of "file".  "1k" can be used as a shortcut for "1000".  Similarly, the tail command can be used to export data from the end of a file.  
You can stop reading here if you are only needing to ouput a fixed amount of bytes from one file.  But, usually the forensic examiner is concerned with searching through hundreds of thousands of files, if not millions!

A Real-World Example

Let's say we have a disk image containing hundreds of thousand graphics, but we only want to view photographs created with a digital camera.  Graphics viewing programs like Gthumb have the ability to recurse through a file system and find graphics images, and even provide for some search limits like file size, modified date, etc.  But these filters don't really help us here.

We need a way to limit the graphics we view to digital photographs.  The best way for us to do this is to limit our search for images based on the presence of Exif data.  The term Exif stands for Exchangeable Image File Format.  Exif data contains camera and setting information and was developed to encourage interoperability between digital devices (see exif.org).  It is found before the image data in a jpeg file.  Most digital cameras use this standard.

Exif data is preceed by the header 'Exif' found 25 bytes into a jpeg file.  So, it seems logical to search graphics files for the Exif header.  But how do we search for graphics files, and then search only the first 28 bytes for the term 'Exif'?

Find and File

The find command can be used to search recursively through a file system.  It's a very robust tool, but I'll only focus on one of the the simplest invocations here: searching a path recursively for any file:
$ find path/to/search/ -type f  # The "f" argument to the "-type" option returns only files to standard output.  The "d" argument would limit output to directories, etc.
We can further limit our output based on file name, if we wish:
$ find path/to/search -type f -iname ".jp*g" # The -iname option matches the following argument with case insensitivity.  Note that standard wildcards are accepted.  The -name option would produce case sensitive results.
We might be looking for graphics that have been renamed, however, and limiting our search by name is too narrow.  This is where the file command comes in.  File reads a files header and returns its type.  We can pipe files located with find and read their type thusly:
$ find path/to/search -type f | file -i -  # The -i option returns the files MIME type, which is more standardized than the "plain language" descriptions otherwise provided.  The file command requires a file argument, and the '-' after the -i option is a shortcut to stdin.  In otherwords, the - is replaced by the file path returned by the find command.
We now have a list of files with their types being returned to the standard output.  What we want to do is filter those files for images, and then get a subset of images with exif data.  To do so,  insert a while loop and add a test:
$ find path/to/search -type f | while read i; do file -ib "$i" | grep "image"; [ $? = 0 ] && echo "$i"; done # Here, each file located with find is assigned to variable $i in the while loop.  Inside the loop, the file type of $i is determined and if the type contains the string "image", the file path is printed.  The "-b" option was added to the file command to produce "brief" output, that is output that includes the file type absent the file name (this avoids false hits where the term "image" is in the file path).
If you're not familiar with bash tests, please review this post, or on the BASH command line, enter "help test".  In brief, we are testing the grep exit code, and if it is '0', which means success, we execute the echo command to print the file path.

We've now managed a list of files that are classified as images.  We need to determine which have Exif data to complete the our quest.  We do this by integrating one more test:
$ find path/to/search -type f | while read i; do file -ib "$i" | grep "image"; [ $? = 0 ] && head -c 28 "$i" | grep "Exif"; [ $? = 0 ] && echo "$i"; done  # Here, if the file is determined to be an image, the first 28 bytes are grepped for the string "Exif".  If that results in a match, the filename is printed.
Okay, you caught me: I only produced a list of files with Exif headers and I can't see the content of the images by reading a list.  This is easily rectified with the ln or 'link' command.  We can replace the last echo with a command to create link files to the images we located allowing for all the files to be viewed from one location:
$ find path/to/search -type f | while read i; do file -ib "$i" | grep "image"; [ $? = 0 ] && head -c 28 "$i" | grep "Exif"; [ $? = 0 ] && ln -s "$i" "${i##*/}"-$(stat -c %i "$i"); done # The -s option creates a symbolic link to file $i in the current directory.  The link will be named for the file's basename and have the inode number appended to prevent errors the occur if the files have the same name.  
Don't worry about the "${i##*/}"-$(stat -c %i "$i") razzle-dazzle for now.  I'll explain that in another post.  For now, just mimic that part of the command if you are concerned about files having the same name.

A Little More Detail for Those Still Conscious

It turns out that Exif is really not the best string on which to filter.  More effective was filtering on an exif creation date.  Consider a recent case where I carved jpegs from unallocated clusters.  Here, I could filter on file name over file type because the carver automatically appended the .jpg file extension.

Total number of files carved:

$ find recovered/ -type f | wc -l # The wc or "word count" command can be used to count lines of output
231331

My total number of jpeg images:
$ find recovered/ -name "*.jpg" | wc
61432
Total number of jpeg images with Exif data:

$ find recovered/ -name "*.jpg" | while read i; do head -c 28 $i | grep Exif ; done | wc -l
3815
Total number of jpeg imags with Exif creation dates:

$ find recovered/ -name "*.jpg" | while read i; do head -c 256 $i | grep -E '[0-9]{4}:[0-9]{2}:[0-9]{2}\ [0-9]{2}:[0-9]{2}:[0-9]{2}'; done | wc -l # The regular expression matches output like "2012:08:09 17:11:56"
841


As you can see, filtering on a date code was much more effective at finding files with meta data associated with cameras (file creation dates) the on the Exif header alone.

I know that there is a lot of information here, but I hope by presenting it completely you are able to understand and adapt the concepts to your own uses.

Thursday, August 2, 2012

Obtaining USB Device Details

It's very often the desire of Forensics investigators to determine if a particular USB flash drive has been mounted in a computer that is the subject of an examination.  This brief post will not cover the various methods used check the Windows Registry or other OSes for a history of mounted devices, but instead how to extract USB Device details to match to the Windows Registry artifacts.

usbutils

The usbutils package includes the lsusb, a tool to list USB devices.  It can be used to find the device manufacturer (not always apparent from the exterior), the serial number, the vendor ID, and other information that can be used to identify the device in a computer system log or settings file.


The basic command, lsusb, lists all attached usb devices, including hubs:
$ lsusbBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching HubBus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching HubBus 002 Device 003: ID 0557:8021 ATEN International Co., Ltd Bus 002 Device 004: ID 0557:2213 ATEN International Co., Ltd CS682 2-Port USB 2.0 DVI KVM SwitchBus 001 Device 004: ID 0930:6545 Toshiba Corp. Kingston DataTraveler 102 Flash Drive / HEMA Flash Drive 2 GB / PNY Attache 4GB StickBus 001 Device 005: ID 1058:1111 Western Digital Technologies, Inc.
The Kingston device is the device of interest.  As you can see, the basic output lets us determine the bus, device number, and vendor id (ID 0930:6545) but not the serial number or other device details.  From the basic help, we can see how to address the specific device of interest to obtain more information:

Usage: lsusb [options]...
List USB devices
  -v, --verbose
      Increase verbosity (show descriptors)
  -s [[bus]:][devnum]
      Show only devices with specified device and/or
      bus numbers (in decimal)
  -d vendor:[product]
      Show only devices with the specified vendor and
      product ID numbers (in hexadecimal)
  -D device
      Selects which device lsusb will examine
  -t
      Dump the physical USB device hierarchy as a tree
  -V, --version
      Show version of program
Therefore, to obtain a full set of details of the Kingston flash drive, we can use the -D option and provide the device path as an argument.  We determine the device path using the Bus/Device information from the base lsusb output.  Because we are adressing a device, we need root privileges, so su to root or use sudo:

# lsusb -D /dev/bus/usb/001/004
Device: ID 0930:6545 Toshiba Corp. Kingston DataTraveler 102 Flash Drive / HEMA Flash Drive 2 GB / PNY Attache 4GB Stick
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0930 Toshiba Corp.
  idProduct          0x6545 Kingston DataTraveler 102 Flash Drive / HEMA Flash Drive 2 GB / PNY Attache 4GB Stick
  bcdDevice            1.00
  iManufacturer           1 Kingston
  iProduct                2 DT 101 G2
  iSerial                 3 001CC0EC346EEC11########  (redacted)
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              200mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      6 SCSI
      bInterfaceProtocol     80 Bulk-Only
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0000
  (Bus Powered)
As you can see, we get a nice, report worthy display of the device details, including the serial number.  The output can be redirected to a file with the usual redirection operators, or sent to the terminal and a file at the same time with the tee command:
# lsusb -D /dev/bus/usb/001/004 | tee device_details.txt
Finally, the verbose option can be used to obtain the same device details as the -D option and without the need to exercise root privileges or address the device, but there's a catch: you get verbose output of all USB devices.  Pick your poison.

Wednesday, August 1, 2012

Waiting on Long Processes? Don't!

The Scene

[Cue dramatic organ music] You started imaging a large hard drive, and you need to follow that with a md5sum of the device to verify the data hash in the image is the same as the device.  But, its time to go home and the image isn't complete!  [dunt, Dunt, DUN!]  Yes, you could have written you command to start the md5sum program upon completion of the acquisition, but you didn't.  Is there anything you can do to ensure you can go home to a warm dinner AND still complete the hashing operation?

You bet!!

Much of life, computing and digital forensics included, is about processes.  First "A" happens, then "B", and next "C."  Forensic disk imaging is like that: First attach the device, then image the device, and next verify the image.  GUI tools can be handy for this in that they can be configured to do several sequential steps for us.  Take the Guymager imaging tool for example: it allows you to verify the image with a separate hash of the device, and it performs the imaging and verification, one after the other, without your intervention.

But what if you are working on the command line?  How can you start one process immediately after another completes?  Back to our scenario...

What You Could Have Done

The whole issue could have been solved at the BASH command line when you issued your acquisition command.  BASH allows control operators to control the flow of your commands.  You have the ability to run command_1 AND command_2, or alternatively, command_1 OR command_2, for example.  The linchpin is the exit status (success or failure) of command_1.

  • With the AND operator, which is represented in BASH by "&&", command_2 will execute if command_1 was successful (exit status 0).  
  • With the OR operator, which is represented in BASH by "||", command_2 will execute if command_1 was unsuccessful (non-zero exit status).

So, if I wanted to make an Expert Witness Format image with ewfacquire, a tool from the libewf library, and follow that automatically with a hash of the device, I could:
# ewfacquire /dev/sdd && md5sum /dev/sdd 
With that command, the md5sum of /dev/sdd will calculate if ewfacquire is successful,.  If ewfacquire fails for some reason, then the hashing operation will not execute.

Woulda, Coulda, Shoulda!

But in our scenario, you are already hours into an acquisition and it would be counter productive to stop ewfacquire process just to use the AND operator described above.  How can you cause the md5sum program to run after the acquisition in such a circumstance?  Well, two ways, as a matter of fact.

Wait

The wait command is a BASH builtin that takes a process ID as an argument.  When the process terminates, wait exits.  It can be used much like the example above:
# wait 1972 && md5sum /dev/sdd
Thus, when wait exits successfully, the md5sum operations begins.  If that seems too easy, in a sense, it is.  Wait only works on processes of the same shell session.  That means to use wait, you'd have to interrupt the ewfacquire process with ctrl-z, run it in the background with bg, and then determine its process ID before wait would work.  You'll may find pull this off, because ewfacquire messages will still print to stderr making working  in the shell difficult.

A better way

You can accomplish the same result as wait without backgrounding the ewfacquire process through the BASH test builtin command.  With test, it is possible to open another shell, determine the process ID of ewfacquire, and test for the presence of the process in the second shell.  Consider:
# ps -opid= -C ewfacquire
1972
# while [ -d /proc/1972 ]; do sleep 60; done && md5sum /dev/sdd
The first command, ps, shows current process.  The arguments here format the output to show only the process ID (-opid=) and search for the process by name (-c ewfacquire).  There are many ways to determine the process id, and this command is borrowed from here so you can see how it could be incorporated into a script.

The while loop uses test in the form of [ -d /proc/1972 ] to check for the presence of the /proc/1972 directory.  Every running process has a directory in the /proc file system which is removed when the process ends.  The sleep command pauses the while loop 60 seconds at a time.  The loop successfully terminates when the process directory is removed causing the md5sum the execute.


It may seem complicated at first blush, but its really not.  And, you get to go home to a warm meal instead of cold leftovers for your efforts.

Thursday, July 19, 2012

A Triumph for Forensics!

I was asked to process a Motorola Triumph Android smartphone recently.  It was pattern locked and usb debugging wasn't enabled, so pushing exploits through the Android Debug Bridge was out.  I the day before, I updated the system rom on a Motorola Droid, and in the process I learned a bit more about the various boot modes of Android devices.

Recovery Mode

The original Motorola Droid provided the ability to create a simple (user data and system) or advanced backups (adds additional user selected partitions to the backup).  Nandroid is the backup mechanism.  I performed the backup to the installed MicroSD card without any difficulty, despite the device being pattern locked and unrooted.  I wondered: do all Android devices have an inherent backup option in recovery mode?  Could it be that easy to get data from a device?  Of course not!  Most recovery images do not allow for backups to be created, which is why you will find a thriving recovery image culture on the web.

Flashing a custom recovery image, like clockworkmod, replaces the stock recovery image with the custom image.  There are a myriad of ways to do this, and I don't recommend you do this willy nilly.  For the purposes of this post, I don't need to go into the details.  Suffice it to say, I was able to flash a modified recovery image to the Droid and get greater access to the device, so I considered flashing the recovery image of the Triumph to add the ability to backup the data.  My thinking: create a backup on an sd card of my own, and extract the gesture.key to decode the pattern lock.


Download Mode

The first step to flashing a recovery image is to put the device in download mode.  The purpose of download mode is to flash firmware to the device.  I discovered the method to enter download mode, and then plugged the device into my Linux workstation once download mode was active.  This is where things got really exciting: By simply plugging the device into the workstation while in download mode, I had access to the phone's NAND memory as a block device and the ability to mount seven partitions!


Don't believe me?
$ fdisk -luDisk /dev/sdh: 1912 MB, 1912602624 bytes
1 heads, 62 sectors/track, 60250 cylinders, total 3735552 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
   Device Boot      Start         End      Blocks   Id  System
/dev/sdh1               1      204800      102400    c  W95 FAT32 (LBA)
/dev/sdh2   *      204801      205800         500   4d  QNX4.x
/dev/sdh3          205801      208800        1500   46  Unknown
/dev/sdh4          208801     3735551     1763375+   5  Extended
/dev/sdh5          212992      229375        8192   48  Unknown
/dev/sdh6          229376      245759        8192   50  OnTrack DM
/dev/sdh7          245760      753663      253952   82  Linux swap / Solaris
/dev/sdh8          753664     2998271     1122304   83  Linux
/dev/sdh9         2998272     3162111       81920   6c  Unknown
/dev/sdh10        3162112     3227647       32768   6a  Unknown
/dev/sdh11        3227648     3637247      204800   6b  Unknown
/dev/sdh12        3637248     3653631        8192   7b  Unknown
/dev/sdh13        3653632     3670015        8192   7a  Unknown
/dev/sdh14        3670016     3686399        8192   78  Unknown
/dev/sdh15        3686400     3702783        8192   79  Unknown
/dev/sdh16        3702784     3719167        8192   7c  Unknown
/dev/sdh17        3719168     3735551        8192   7d  Unknown
$ blkid
/dev/sdh1: SEC_TYPE="msdos" LABEL="MOBILE" UUID="4C5A-5671" TYPE="vfat"
/dev/sdh7: LABEL="system" UUID="d3e843eb-0c62-4ab6-83c6-eeb31f8c556e" TYPE="ext3"
/dev/sdh8: LABEL="userdata" UUID="c62a3dda-8776-4fb2-a8a2-bd1a02f45440" TYPE="ext3"
/dev/sdh9: LABEL="cda" UUID="c0de041c-c97b-489d-9f6e-81b4e1be8665" TYPE="ext3"
/dev/sdh10: LABEL="hidden" UUID="676aed0f-cb4d-4214-b34d-a0dbb04fcccf" TYPE="ext3"
/dev/sdh11: LABEL="cache" UUID="27ade4a2-1415-46fc-87e8-3682c396a9fd" TYPE="ext3"
/dev/sdh12: LABEL="caivs" UUID="b5719119-11a8-4cfc-a250-74a68b0e2d10" SEC_TYPE="ext2" TYPE="ext3" 

I didn't have a yaffs module installed at the time of this post, but it wouldn't surprise me if the 'Unknown' partitions were formatted yaffs.  To make a quick discussion of this, I was able to successfully image /dev/sdh, mount the partitions, even recover deleted files (note the mountable partitions in the blkid output are fat or ext).

Getting the Data

To make a quick discussion of this, I was able to successfully image /dev/sdh, mount the partitions, even recover deleted files (note the mountable partitions in the blkid output are fat or ext).  I used libewf to make the image and photorec to recover deleted files from unallocated blocks.

I didn't have a mechanism to quickly mount seven partitions read-only, but I intended to create a tar of all the logical files for easy access and distribution of files.  I thought I'd share the nifty way I quickly mounted all seven partitions and extracted the files:
  1. Create the mount points:

    $ mkdir -p mount/{MOBILE,system,userdata,cda,hidden,cache,caivs}
  2. Mount the partitions read-only:

    $ for i in $(ls mount); do p=$(sudo findfs LABEL=$i); sudo mount -o ro $p mount/$i; done
  3. Archive all the files:

    $ sudo tar -cavf logical.tar.gz mount/
  4. Unmount the partitions:

    $ for i in $(ls mount); do sudo umount mount/$i; done
I'm currently exploring the concept of flashing recovery images modified to allow data backups, and its promising, though a bit like crossing mine-laden ground for the forensic examiner.  But, in the case of the Motorola Triumph, no flashing is necessary.  Now just hope that every device that lands on your desk for examination is a Motorola Triumph!


Tuesday, June 19, 2012

Data exchange: Archiving and Moving Data between OSes

The Back Story


It finally happened (sigh): I found myself in need of a Mac.  I don't much enjoy Mac computers, but I'll save my rants for my Mac-user friends who love to hear from me on the topic.  But I needed to extract data from an iPhone4 with iOS 5.0.1.  I've discussed previously that libimobiledevice provides an open-source suite of tools that can be used to extract data from an iPhone with Linux.  Frankly, I need to freshen that post as the tools have become more robust and, as of this writing, support extracting data (by means of an iTunes-like backup with the idevicebackup tool) through iOS 5.1.1.

But, in my case, though I only needed files that were available through idevicebackup, the phone was pin-locked which prevents the utility from functioning.  I am fortunate enough to have access to the tools provided by Johnathan Zdziarski at the iOS Forensic Research site, one of which provide the pin code from a locked iPhone.  One of the facts required for the pin code tool to work is knowledge of the device model, discoverable on the back of the phone, and the iOS version installed.  Discovering the iOS version is not always trivial, unless you have libimobiledevice-utils.

Useful Digression: Determining the iOS Version of a Device


The libimobiledevice-utils toolset provides the ideviceinfo tool which displays valuable information about an unlocked iPhone, Touch, or iPad in key/value pairs.  The info includes the device serial number, mac address, bluetooth address, phone number, device name ("Badguy's iPhone), cpu type, hardware model, firmware version, even the color of the phone.  Under the product version key, the iOS version is displayed. You may have noticed I said "unlocked" device.  Information, though in to a lesser degree, can be obtained from a locked device as well, but nothing you read in the help will make that obvious.  If you pass the -s / --simple option, you can still obtain limited but critical information to include the device name and the product (iOS) version.

With the iOS product version in hand, I proceeded to obtain the pin code with the aide of Zdziarski's tools.  I also downloaded the logical file system, consisting of over 12gb of data in one tar ball.  I needed to preserve the archive as evidence, and I also wanted to transfer it to a Linux box for examination, where I have more contemporary command line tools available to me than provided through OS X.

The Point: Moving Data Between Operating Systems


I like easy, and I like methodology that is cross-platform, whenever possible.  To be more specific, I prefer to use the same tools no matter the OS.  I have sort of adopted a unix philosophy of forensics: the unix tool philosophy is make one tool to do one thing and do it well.  My forensics philosophy is learn one tool to do one task and learn it well.  Now, I know its not always possible, but I want to avoid the problem of using Zip compression and tools because I'm in Windows, Gzip/Bzip and related tools because I'm in Linux where such compression is dominant, and Stuffit for Mac, etc.  Much better to learn one method that will work in most any situation without the need to download and install yet another utility, in my way of thinking.


Because I was working on the Mac command line, it made sense to stay there and chop up that 12gb tar file into DVD sized chunks.  And for fun, I decided to see if I could squeeze down the size some (it turned out that much of the data was video, and there wasn't much compression to be had, however).  So, how can it be done?  Newer incarnations of tar allow the creation of volumes, but not so in OS X Lion.  However, the bzip2 compressor and the split commands are part of the standard command line tools.

The concept is simple: compress the tar file and chop it into 4.1gb chunks for burning.  Bzip2 handles the compression, but it creates a file of the same name as the target file with the .bz2 extension by default.  Thus, "archive.tar" becomes "archive.tar.bz2."  This does not accomplish my goal, because I'm just left with a somewhat smaller file, but still too large to burn to DVD.  However, bzip2 takes the -c argument which pipes the data to stdout instead of creating a new file!  Now we're getting somewhere.

We can take the data piped from bzip2 and use our Ginsu (that's a knife for those of you who didn't watch a lot of TV in the 1980's) command called split.  Split will divide if file into user-defined sized pieces.  The sizes can be based on the number of lines, amount of data, and if I read the man page correctly on the Mac, even a data pattern.  In my case, I want to define it by size, and the Mac version of the tool tells me to specify the -b flag for the byte size of the resulting files, appending 'k' for kilobytes and 'm' for megabytes.  The single hyphen, used as an argument, replaces a file name when data is being piped from another tool like bzip2.

So, putting it all together, I split my archive.tar file thusly:
$ bzip2 -c archive.tar | split -b 4100m - archive.tar.
Bzip compresses archive.tar and sends the data to stdout.  That data is piped through the split command, which creates 4.1gb chunks.  The resulting files were archive.tar.aa, archive.tar.ab, and archive.tar.ac.  Note the hyphen in the command after the -b file size option: that is 'shortcut' for the data from the bzip2 command and replaces what would otherwise be the name of the file for split to operate upon.  Also note the period at the end of archive.tar.  Without it, the output files would have the name 'archive.taraa,' etc., without the period separator between the original file extension and the new one supplied by split.

What Now?


I burned those files to three DVDs, which provided the necessary evidence retention medium.  I also copied those files to my Linux box where I reassembled and decompressed them in one operation:
$ cat archive.tar.* | bunzip2 > archive.tar
I did not untar the archive, because I can mount that read-only and examine it as is.  This provides a better forensic environment for examination.  I'll cover this method in a future post.  Finally, because I install and maintain a Cygwin environment on my Windows workstation, I could have used the same method to transfer the files to my Windows operating system.  One method, three operation systems interchange data.  Now, that's the way I like it!

Yet Another YAFFS Discussion

In previous posts, I've discussed rooting and imaging Android devices.  While the exploits change from one Android version to another, the principals are the same as I detailed in the past.  Most Android devices, small portable devices like smart phones in particular, use NAND flash memory with the yaffs file system for storage.

If you are new to building binaries from source code, then this tutorial is probably not for you.  However, I hope to explain it well enough that you can still follow along even if you have very little build experience.  For starters, make sure you have the appropriate build tools.  In Debian and Ubuntu, it's easiest to to install the "build-essential" package:

$ sudo apt-get install build-essential

Though the next step is not required, you'll likely want to install the "git" software versioning system so you can easily obtain and install the latest yaffs source code.  Otherwise, it is possible to download the source code as a tar archive from the source code repository.  I'll be demonstrating the git method here:

$ sudo apt-get install git

Finally, you'll likely want to install the module for easy access.

$ sudo apt-get install module-init-tools

Building the Module

In order to mount Android images, download the latest source code from the online repository.  You'll probably have to install git if you haven't done so in the past.  It is not standard in most Linux Distros.
$ git clone git://www.aleph1.co.uk/yaffs2 Cloning into yaffs2...
remote: Counting objects: 7027, done.
remote: Compressing objects: 100% (4247/4247), done.
remote: Total 7027 (delta 5566), reused 3473 (delta 2700)
Receiving objects: 100% (7027/7027), 3.43 MiB | 304 KiB/s, done.
Resolving deltas: 100% (5566/5566), done.

The source code is downloaded into a subdirectory called 'yaffs2' is used the example command above.  If you want to clone into a different directory, add the directory name as an argument following the web address.  If the directory doesn't already exist, it will be created.

Next, change into the source code directory and issue the "make" command to build the source according to the parameters already laid out in the Makefile.

$ cd yaffs2
$ make 
make -C /lib/modules/2.6.38-13-generic/build M=/home/jlehr/projects/yaffs2 modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.38-13-generic'
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_mtdif.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_mtdif2_multi.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_mtdif1_multi.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_packedtags1.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_ecc.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_vfs_multi.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_guts.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_packedtags2.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_tagscompat.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_checkptrw.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_nand.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_nameval.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_allocator.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_bitmap.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_attribs.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_yaffs1.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_yaffs2.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_verify.o
  CC [M]  /home/jlehr/projects/yaffs2/yaffs_summary.o
  LD [M]  /home/jlehr/projects/yaffs2/yaffs2multi.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/jlehr/projects/yaffs2/yaffs2multi.mod.o
  LD [M]  /home/jlehr/projects/yaffs2/yaffs2multi.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.38-13-generic'

Finally, install the module.
$ sudo make mi #or sudo make modules_install
make -C /lib/modules/2.6.38-13-generic/build M=/home/jlehr/projects/yaffs2 modules_install
make[1]: Entering directory `/usr/src/linux-headers-2.6.38-13-generic'
  INSTALL /home/jlehr/projects/yaffs2/yaffs2multi.ko
  DEPMOD  2.6.38-13-generic
make[1]: Leaving directory `/usr/src/linux-headers-2.6.38-13-generic'


Mounting a yaffs image

I was planning to finish this discussion with mounting a yaffs image, but its a more complex topic than I can reasonably handle in a few lines.  Look for a discussion on the complexities of mounting a yaffs image, and maybe the methods for obtaining one, in a future post.

Monday, May 7, 2012

Chomping on BlueTooth

I had a difficult task recently: try to determine who was the likely operator of a netbook.  The netbook was used to download and store ATM card numbers that had been illicitly collected with a skimmer.  The operating system was Windows XP, and the sole user account was a pseudonym that I could not link to anyone in particular.

I tried a few obvious tactics: I looked for installed software (Program Files and Windows Registry), hoping to get registration names and/or email addresses for registered applications.  Nothing.  In fact, it appeared little extra software had been installed on the system except for the software and driver's to communicate with the skimmer.

I decided to boot the image in a VM to get a 'lay of the land.'  In dead disk analysis, its quite easy to see what files are on the desktop, for example, but not nearly so easy to see how objects are arranged, the wallpaper, running applications, etc.  Sure, you can discover these things, but you have to look several locations and then synthesize the information... sometimes a picture is just plain better.  I used xmount, VirtualBox, and opengates, a technique I've previously detailed.

I immediately noted something after the system booted: the BlueTooth (BT) service was running.  I have never seen BT running by default in a Windows system, but that doesn't mean it wasn't configured to run on boot by the netbook's manufacturer.  But still, I was intrigued.  The BT application windows did not show a history of connected devices, but I wondered if such a history was available.  Maybe the paired device might lead me to the suspect?

I'm in the habit of imaging devices with forensics-oriented Linux boot discs such as CAINE, DEFT, or those of my own creation.  The benefits can be quite substantial, including the ability to easily collect hardware information.  I use lshw for this purpose, but in this case, I saw no BT hardware listed in the report, just ethernet and wifi.  Did this netbook support BT, or was an external adapter used?  In this case, I no longer have the hardware in front of me to inspect, but it doesn't appear to have a built-in adapter.

However, I am able to detect third-party bluetooth software with a quick registry search in the mounted disk image:
$ reglookup -i software | grep -i bluetooth
/Widcomm/Install/INSTALLDIR,SZ,C:\x5CProgram Files\x5CWIDCOMM\x5CBluetooth Software\x5C,2010-11-28 03:01:19
The tool I used, reglookup, is an efficient and useful command line registry parser.  The -i option causes subkeys to inherit the timestamp of the parent key.  The date may not reflect the modification date of the specific key since the parent key modified date is updated whenever a subkey is modified.

Inspecting The Widcomm (Broadcom) software keys, I found a "Devices" subkey that organized remote devices by their MAC addresses:
Widcomm/BTConfig/Devices,KEY,,2010-11-28 03:04:14
/Widcomm/BTConfig/Devices/00:02:72:e2:05:7a,KEY,,2010-11-28 03:10:08
/Widcomm/BTConfig/Devices/00:23:3a:e5:1f:53,KEY,,2010-11-28 03:04:45
/Widcomm/BTConfig/Devices/78:ca:39:41:40:e1,KEY,,2010-11-28 03:04:05
Each "device" subkey, among other things, contained a name key.  This was the 'text' name of the device, and one of the devices stood out:

/Widcomm/BTConfig/Devices/78:ca:39:41:40:e1/Name,BINARY,badguy\xE2\x80\x99s MacBook Air\x00,
The data in the Name key is in a python bytes format, which displays ASCII text where possible and otherwise the hex in the form \x00.  It can be converted in python3 rather simply with:
b'badguy\xE2\x80\x99s MacBook Air'.decode()
'badguy’s MacBook Air'
I redacted the Name key data for this article, but from it I learned the name of the MacBook Air with which the netbook had been paired.  The name of the MacBook was the name of a suspect in the case.  Proof positive that the named suspect was the operator of the netbook?  No, certainly not.  But helpful in light of the totality of the circumstances, to be sure.

Time Perspective

Telling time in forensic computing can be complicated. User interfaces hide the complexity, usually displaying time stamps in a human reada...