Data Carving with dd

In this next example, we will useddto carve a JPEG image from a chunk of raw data. By itself, this is not a real useful exercise. There are lots of tools out there that will “carve” files from forensic images, including a simple cut and paste from a hex editor. However, the purpose of this exercise is to help you become more familiar withdd. In addition, you will get a chance to use a number of other tools in preparation for the “carving”. This will help familiarize you further with the Linux toolbox. First you will need to downloadthe raw data chunk from:

ftp://ftp.hq.nasa.gov/pub/ig/ccd/linuxintro/image_carve.raw

Have a brief look at the file_image_carve.raw_with your wonderful command line hexdump tool,xxd:

xxd image_carve.raw | less

It’s really just a file full of random characters. Somewhere inside there is a standard JPEG image. Let’s go through the steps we need to take to “recover” the picture file usingddand other Linux tools. We are going to stick with command line tools available in most default installations.

First we need a plan. How would we go about recovering the file? What are the things we need to know to get the image (picture) out, and only the image? Imagineddas a pair of scissors. We need to know where to put the scissors to start cutting, and we need to know where to stop cutting. Finding the start of the JPEG and the end of the JPEG can tell us this. Once we know where we will start and stop, we can calculate the_size_of the JPEG. We can then tellddwhere to start cutting, and how much to cut. The output file will be our JPEG image. Easy, right? So here’s our plan, and the tools we’ll use:

  1. Find the start of the JPEG (xxdandgrep)

  2. Find the end of the JPEG (xxdandgrep)

  3. Calculate the size of the JPEG (in bytes usingb**c**)

  4. Cut from the start to the end and output to a file (usingdd)

This exercise starts with the assumption that we are familiar with standard file headers. Since we will be searching for a standard JPEG image within the data chunk, we will start with the stipulation that the JPEG header begins with hexffd8_with a six-byte offset to the string “_JFIF”. The end of the standard JPEG is marked by hexffd9.

Let’s go ahead with step 1: Usingxxd, we pipe the output of our_image_carve.raw_file to grep and look for the start of the JPEG4:

xxd image_carve.raw | grep ffd8

00052a0: b4f1 559c ffd8 ffe0 0010 4a46 4946 0001 ..U…….JFIF..

As the output shows, we’ve found the pattern “ffd8” near the string

JFIF”. The start of a standard JPEG file header has been found. The offset (in hex) for thebeginning of this line ofxxdoutputis_00052a0._Now we can calculate the byte offset in decimal. For this we will use thebccommand. bcis a command line “calculator”, useful for conversions and calculations. It can be used either interactively or take piped input. In thiscase we will echo the hex offset tobc, first telling it that the value is in base 16. bcwill return the decimal value.

echo "ibase=16; 00052A0" | bc

21152

It’s important that you useuppercase letters_in the hex value. Note that this is NOT the start of the JPEG, just the start of the line inxxd’soutput. The “_ffd8” string is actually located another 4 bytes farther into that line of output. So we add 4 to the start of the line. Our offset is now21156. We have found and calculated the start of the JPEG image in our data chunk.

Now it’s time to find the end of the file.

Since we already know where the JPEG starts, we will start our search for the end of the filefrom that point. Again usingxxdandgrepwe search for the string:

xxd –s 21156 image_carve.raw | grep ffd9

0006c74: ffd9 d175 650b ce68 4543 0bf5 6705 a73cue..hEC..g..<

The–s**21156**specifies where to start searching (since we know this is the front of the JPEG, there’s no reason to search before it and we eliminate false hits from that region). The output shows the first “ffd9” at hex offset0006c74. Let’s convert that to decimal:

echo "ibase=16; 0006C74" | bc

27764

Because that is the offset for thestart_of the line, we need to add 2 to the value to include the ffd9 (giving us_27766). Now that we know the start and the end of the file, we can calculate the size:

echo"27766 - 21156" | bc

6610

We now know the file is 6610 bytes in size, and it starts at byte offset 21156. The carving is the easy part! We will useddwith three options:

skip= how far into the data chuck we begin “cutting”.bs= (block size)the number of bytes we include as a “block”.

count =the number of blocks we will be “cutting”.

The input file for theddcommand isimage_carve.raw. Obviously, the value ofskipwill be the offset to the start of the JPEG. The easiest way to handlethe block size is to specify it asbs=1(meaning one byte) and then settingcountto the size of the file. The name of the output file is arbitrary.

dd if=image_carve.raw of=carv.jpg skip=21156 bs=1 count=6610

6610+0 records in

6610+0 records out

You should now have a file in your current directory called_carv.jpg._If you are in X, simply use thexviewcommand to view the file (or any other image viewer) and see what you’ve got.

xview carv.jpg

4. The perceptive among you will notice that this is a “perfect world” situation. There area number of variables that can make this operation more difficult. The grep command can be adjusted for many situations using a complex regular expression (outside the scope of this document).

results matching ""

    No results matching ""