Sie sind auf Seite 1von 8

Hard disk concepts

We'll begin by spending a little bit of time on the language used to describe
the layout of a traditional hard disk. This only of historical interest, but will
help us understand the output of fdisk(1). The important concepts are:
Platters a hard disk consists of one or more platters, stacked on top of
each other. A hard disk is, in this respect, something like a stack of dinner
plates.
Tracks each platter, on both the top and the bottom of that platter,
consists of some number of tracks, which are circular rings of varying
circumference, depending on how close to the edge of the platter a
particular track is.
Cylinders tracks are usually numbered from 0. So, for example, if a
platter has 5001 tracks on each side, they would be numbered 0-5000.
Because all platters on a hard disk have an identical number of tracks on
each side, we can use the word 'cylinder' to refer to all the tracks of a
particular number, on all sides of all platters, as a cylinder. Thus, all tracks
numbered 0 constitute a single cylinder.
Sectors each track is divided up into a number of sectors. Sectors are
normally 512 byte contiguous sections of the track.
Heads data is read from and written to a hard disk with the use of
something called a head. A head is a bit like the needle used in the old
record players: you place the needle on the vinyl LP, and it reads data.
But in the case of a hard disk, there is a 'head' for each side of the
platter. (This is not strictly true. Some drives have 255 heads, so
obviously one side of one platter isn't read.)
The word 'head' is usually used as the unit to count the number of
'sides' of platters.
Okay, that's enough to understand a lot of the output of fdisk(1):

#fdisklu/dev/sda

Disk/dev/sda:1979.1GB,1979120025600bytes
255heads,63sectors/track,240614cylinders,total3865468800
sectors
Units=sectorsof1*512=512bytes
Sectorsize(logical/physical):512bytes/512bytes
I/Osize(minimum/optimal):512bytes/512bytes
Diskidentifier:0xba3c92b4

DeviceBootStartEndBlocksIdSystem
/dev/sda1638032440131deDell
Utility
/dev/sda2*8192042762232097152cW95
FAT32(LBA)
/dev/sda342762242090762231024000007
HPFS/NTFS/exFAT
<snip>

What does this tell us about the structure of this hard disk? Well:
$ bc -q
scale=5
1979120025600 # bytes
1979120025600
1979120025600/512 # sectors
3865468800.00000
1979120025600/512/63 # all tracks on all heads of all platters
61356647.61904
1979120025600/512/63/255 # tracks per head, i.e., cylinders
240614.30438

Acquiring an image of a hard disk (but more an intro to dd(1)


To acquire an image of a hard disk, normally we boot from a trusted CDROM
(which does not mount the hard disk), and use dd(1) and nc(1) or
cryptcat(1) to copy the disk over the network to a forensic workstation. The
most common command sequence used for this purpose is the following:
#ddif=/dev/<device>conv=noerror,sync|nc<forensic_wkst>
<port>
((And of course, we'd have a listening nc(1) server listening on our forensic
workstation.))
Let's take apart our dd(1) command line a bit:
Without any options, dd(1) works pretty much like cat(1):
$dd
asdf
asdf
0+1recordsin
0+1recordsout
5bytes(5B)copied,1.99518seconds,0.0kB/s
If we add the if= option, then it reads from the file specified:
$cat>dd.in
asdf
^D
$ddif=dd.in
asdf
0+1recordsin
0+1recordsout
5bytes(5B)copied,4.5e05seconds,111kB/s
if we add the of= option, then it writes to the file specified:
$ddif=dd.inof=dd.out
0+1recordsin
0+1recordsout
5bytes(5B)copied,0.000126seconds,39.7kB/s
$catdd.out
asdf
Normally, when dd(1) encounters a read error, it exits. But during a forensic

duplication, we don't want a read error (such as a bad section of the disk) to
completely undermine our duplication. So we can specify conv=noerror.
When conv=noerroris specified, dd(1) skips over the blocks of bad data, and
continues reading.
But the effect of skipping over bad blocks is that, in the event that there are
bad blocks, the disk image will be smaller than the actual hard disk. This can
wreak havoc when we're trying to cut a disk image into partition images,
since the partition table (as we'll see later) is based on the actual disk
geometry.
To avoid this, we specify conv=sync, which instructs dd(1) to write a block 0s
to the image corresponding to each read error from the input file.
There is one other option that is often used: bs=<blocksize>.
By default, dd(1) reads data from a file in 512 byte chunks, which it calls
blocks. That is to say, it performs a series of read(2) system calls, each time
asking for the next 512 bytes from the file being read from. And for each read
call, it write(2)s that same (amount of) data to the output file.
For example:

$ddif=/dev/zeroof=example.ddcount=1
1+0recordsin
1+0recordsout
512bytes(512B)copied,0.000105seconds,4.9MB/s
$lslexample.dd
rwrr1daleusers512Apr2222:35example.dd

((Because the default block size is 512 bytes, and because we indicated with
count=1 that we wanted to read one block, this invocation of dd(1) created
a file 512 bytes in size.))
Likewise, if we now read from this file with the default block size, it'll perform
one read and one write, indicated by the '1+0recordsin/out':

$ddif=example.ddof=/dev/null
1+0recordsin
1+0recordsout
512bytes(512B)copied,3.9e05seconds,13.1MB/s

On the other hand, if we specify a different block size, say one smaller than
the default, there will be more reads and writes:

$ddif=example.ddof=/dev/nullbs=1
512+0recordsin
512+0recordsout
512bytes(512B)copied,0.000778seconds,658kB/s

Or:

$ddif=example.ddof=/dev/nullbs=256

2+0recordsin
2+0recordsout
512bytes(512B)copied,3.7e05seconds,13.8MB/s

Hard disks can usually read and write chunks much larger than the default,
and so it is more efficient to use a larger block size. The right blocksize
depends on the disk. Specifying a larger block size becomes more and more
important as disks are getting bigger and bigger.
Although bs= is mostly about efficiency, there is one case where the block size
can actually alter the output file:
When you specify the conv=noerror,sync, then, as noted above, dd(1)
writes zeros in place of the data read errors.
But it (sync in particular) does something else too: it forces dd(1) to write
in blocksize chunks, even if the corresponding read doesnt grab a full
block. If the hard disk size is not a multiple of the block size, then the last
block written will cause the image to be larger than the hard disk being
acquired.
This can be seen with a simple example:
$lslexample.dd
rwrr1daleusers512Apr2222:35example.dd
$ddif=example.ddof=out.ddbs=500conv=noerror,sync
1+1recordsin
2+0recordsout
1000bytes(1.0kB)copied,0.000141seconds,7.1MB/s
$lslexample.ddout.dd
rwrr1daleusers512Apr2222:35example.dd
rwrr1daleusers1000Apr2222:45out.dd
Notice that dd(1) indicated 1+1recordsin, and 2+0recordsout. This
means that it read: 1 full block, and one partial block; and wrote: two full
blocks. That explains why the two files differ in size.
If we do not specify sync, then everything is okay:
$ddif=example.ddof=out.ddbs=500
1+1recordsin
1+1recordsout
512bytes(512B)copied,0.000121seconds,4.2MB/s
$lslexample.ddout.dd
rwrr1daleusers512Apr2222:35example.dd
rwrr1daleusers512Apr2222:50out.dd
The moral of the story is: make sure your hard disk is a multiple of your
block size, or just leave bs= out altogether, since hard disks are always a
multiple of 512. (But for large disks, this can make the acquisition much
slower.)

Let's go through a quick example of an acquisition. I'll acquire /dev/sda1 (a


small partition we'll learn about partitions soon) because /dev/sdais too
large (the procedure is otherwise identical):
[we used /home/images/able2.dd during class, but the process is identical]

Example 1:

$nclp9998>sda1.dd&
[1]8850
$sudosu
#fdisklu/dev/sda|grepsda1
/dev/sda1638032440131deDell
Utility
#ddif=/dev/sda1conv=noerror,syncbs=2048|ncw2localhost
9998
20065+1recordsin
20066+0recordsout
41095168bytes(41MB)copied,0.191781s,214MB/s
#exit
[1]+Donenclp9998>sda1.dd
$lslsda1.dd
rwrwr1daledale41095168Jan1512:08sda1.dd
$md5sumsda1.dd
82b3bcd63d2ca56f4f23a4b1371ec759sda1.dd
$sudomd5sum/dev/sda1
8176cc7595c40f1a754c3f6522b30841/dev/sda1

Is this right? No, the checksums don't match. What happened? Answer: we
specified a block size such that the size of our hard disk was not a multiple.
Let's try again:
Example 2

$nclp9998>sda1.dd&
[1]8878
$sudosu
#ddif=/dev/sda1conv=noerror,syncbs=1024|ncw2localhost
9998
40131+0recordsin
40131+0recordsout
41094144bytes(41MB)copied,0.165376s,248MB/s
#exit
[1]+Donenclp9998>sda1.dd
$md5sum./sda1.dd
8176cc7595c40f1a754c3f6522b30841./sda1.dd

The above describes the use of dd(1) to acquire a forensic duplication of a


hard disk.

Using dcfldd(1)
There are a number of enhanced versions of dd(1) tailed to forensic
acquisition. One enhancement of dd(1) is dcfldd(1). It takes all the same
options as dd(1), plus a few more. The important enhancement that we'll

discuss is simultaneous cryptographic hashing.


With dd(1), if we want to calculate the md5sum on a hard disk, we have to do
this:
$md5sum/home/images/able2.dd
02b2d6fc742895fa4af9fa566240b880/home/images/able2.dd
The implication of this is that we need to read the entire disk twice: once to
calculate the checksum, and once to acquire an image. dcfldd(1) can be
instructed to do them simultaneously:
$dcflddif=/home/images/able2.ddof=dcfldd.outhash=md5bs=512
675328blocks(329Mb)written.Total(md5):
02b2d6fc742895fa4af9fa566240b880

675450+0recordsin
675450+0recordsout
$md5sumdcfldd.out
02b2d6fc742895fa4af9fa566240b880dcfldd.out

((dcfldd(1) calculates the checksum on the input file, which is what we want))

Another advantage of dcfldd(1) is that it can be instructed to perform


checksums on arbitrarily large chunks of the data, i.e., it is not restricted to
performing a checksum on the whole input file:
$dcflddif=/home/images/able2.ddof=dcfldd.outhash=md5bs=1024
hashwindow=10485760
9984blocks(9Mb)written.010485760:
ae29655c569257d88b57f7942ba5c08a
20224blocks(19Mb)written.1048576020971520:
9ed40206661bf69281d8a3a197881639
30464blocks(29Mb)written.2097152031457280:
cfb74baae68a6618c6261d62ef99da39
40704blocks(39Mb)written.3145728041943040:
1724856647e5bcf37dc5e83908b570e2
50944blocks(49Mb)written.4194304052428800:
8b486d7d2b9a7375a99b326133a9f657
61184blocks(59Mb)written.5242880062914560:
cf38cbd52294e307273f6b36552e502c
71424blocks(69Mb)written.6291456073400320:
4997a54998df9115ad1c5537c57107be
81664blocks(79Mb)written.7340032083886080:
1801cad43fab9b35028df2f81cd5e27d
91904blocks(89Mb)written.8388608094371840:
a453f429fb6461ab428cf61a84f4b464
102144blocks(99Mb)written.94371840104857600:
948d90c60d55bc8d3f2c07041d7cc754
112384blocks(109Mb)written.104857600115343360:
ab633030878ac23f0b2acd9a45533926
122624blocks(119Mb)written.115343360125829120:

569e2df657b96f46076ba87fc5d83c09
132864blocks(129Mb)written.125829120136314880:
657d90e458a86cb67d3ccc878504027a
143104blocks(139Mb)written.136314880146800640:
338358f9503b8a4bd78fd0e31bcf2054
153344blocks(149Mb)written.146800640157286400:
b7e1fdec69a19fc3784bf2f1bae0b785
163584blocks(159Mb)written.157286400167772160:
3e379ad423952134e39703c5cac6ffc2
173824blocks(169Mb)written.167772160178257920:
150f9b95784a909c2f6598f2a8de171f
184064blocks(179Mb)written.178257920188743680:
9551fd860eb3f3ac01290b97d9c50758
194304blocks(189Mb)written.188743680199229440:
02bb50013e94555a32e84398446019e1
204544blocks(199Mb)written.199229440209715200:
44c2428d11c027b7a6ca113afe890023
214784blocks(209Mb)written.209715200220200960:
05beb729ef2b832dc595b97f26c16011
225024blocks(219Mb)written.220200960230686720:
6524ee43cc8568a2e734550296c729ed
235264blocks(229Mb)written.230686720241172480:
924c16f533cf9bd1de44850678c9add4
245504blocks(239Mb)written.241172480251658240:
da83f35718cea396aad641a4fee6321a
255744blocks(249Mb)written.251658240262144000:
36154bc6670538da36076cdf3d991f0e
265984blocks(259Mb)written.262144000272629760:
942ee9766d3647751d90a110fb1949fd
276224blocks(269Mb)written.272629760283115520:
3681c4377dba012b2d0ea4de6138ece9
286464blocks(279Mb)written.283115520293601280:
37d83f3505b21bdaa1c61e574772eafb
296704blocks(289Mb)written.293601280304087040:
4f8041869d8e1c19b810422cf4a2f1f8
306944blocks(299Mb)written.304087040314572800:
995013fb8615aa6d1db1f11c4a155ce0
317184blocks(309Mb)written.314572800325058560:
9e76e333f18effbc726355d37f466b19
327424blocks(319Mb)written.325058560335544320:
a51175f259c6a6e99be41c3c6c15fc66
337664blocks(329Mb)written.335544320345830400:
8ecde1a10326bfc1721eff9cb7716cf7
Total(md5):02b2d6fc742895fa4af9fa566240b880

337725+0recordsin
337725+0recordsout

The advantage of this is that if, for whatever reason, the checksums change
on the original evidence (let's say because portions of the disk were
damaged), then we may still ensure the integrity of portions of our image file.
For we could compare the various portions of the image with the
corresponding portions of the original. For those portions which have
matching checksums, we can trust that our duplication is identical to the
original. This is, of course, impossible with a single checksum.

Das könnte Ihnen auch gefallen