SANS Digital Forensics and Incident Response Blog

Digital Forensics: In-depth analysis of SRM and BCWipe (for unix)

Secure wiping tools are nothing new, we've all seen and used them for a long time now. It's no mystery that these tools are used by intruders to cover their tracks by securely deleting files such as logs, or other files they downloaded onto compromised systems. Organizations also use these tools to securely delete confidential information, so it's important to know how the tools operate. After all, the difference between a good forensic analyst and a great analyst, is knowing how the tools we use work behind the scenes.

I would like to start by noting that while i was doing some tests to write this post, I came across an issue with syncing and Linux. I tried to wipe a few files using srm, shred and BCwipe to see if they did anything differently. I used The SleuthKit's istat, icat and blkcat to be able to find the block and inode numbers for my test file and then view the block's contents. The odd thing is that after wiping the file with bcwipe, srm or shred I was still able to see the contents with blkcat.

asm boot # ls -li /boot/randfile
10083 -rw-r—- 1 root root 40 Jan 17 12:07 randfile
asm boot # istat /dev/sda1 10083
inode: 10083
Allocated
Group: 5
Generation Id: 313379932
uid / gid: 0 / 0
mode: rrw-r—-
size: 40
num of links: 1
Inode Times:
Accessed:Mon Jan 17 12:07:52 2011
File Modified:Mon Jan 17 12:07:52 2011
Inode Modified:Mon Jan 17 12:07:52 2011
Direct Blocks:
42497

asm boot # dcat /dev/sda1 42497
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
asm boot #
asm boot # man bcwipe
asm boot # bcwipe -mz randfile
Wipe randfile (y/[n]/a)?y
asm boot # dcat /dev/sda1 42497
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
asm boot # ls -la | grep randfile
asm boot # dcat /dev/sda1 42497
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

After consulting on the GCFA mailing-list I realized the problem was with synchronizing data on disk with memory, using the sync command and modifying the drop_caches value seemed to fix the problem.

echo 3 >/proc/sys/vm/drop_caches

Both srm and BCwipe support many different wiping algorithms, such as DoD compliant 7-pass, Gutmann's method, etc.

This is actually how the data is overwritten by BCwipe. If we look at the source code we will find most of the relevant functions in the file wipe.c. The function bcwipe_write() has a call to the write() C function, which writes a buffer into a file descriptor, that buffer will be filled with either random data or zeros. bcwipe_write() is called by do_wipe_pass() which is subsequently called by wipe_pass(), bcwipe_write() will overwrite the data using the scheme we chose and N passes, depending on the scheme. The wiping schemes are defined in schemes.c, if we wanted to create a new type of wiping scheme we should start by adding it there. If you do that though, you may be violating BCwipe's EULA.

SRM works in a very similar way, looking at it's source code we can see that sunlink.c has most of the relevant functions. Just like BCwipe, SRM has its' own custom write function called writen(), it also calls the write() C function and does some error checking.

We can see several overwrite functions:

  • overwrite()
  • overwrite_random()
  • overwrite_byte()
  • overwrite_bytes()

The names are very self-explanatory. overwrite_random() is used to write a buffer with random data (the random data is generated by randomize_buffer() in random.c), overwrite_byte() to write a buffer containing a specific byte of data, and overwrite_bytes() to write a buffer with 3 specific bytes (this is needed for the Gutmann and DoE overwrite specifications). All these functions will ultimately call overwrite() which uses SRM's writen() function to write the buffers to a file descriptor.

I wanted to see if there was anything left behind by SRM or BCwipe that could lead to the conclusion that wiping tools were used, so i created a test file and analyzed what it's allocated space contained before and after wiping it.

For these tests i used the DoD compliant 7-pass specification, but it's likely you will find the same result with any other specification.

asm boot #perl -e 'print "A"x40000'> /boot/randfilee
asm boot # istat /dev/sda1 10083
inode: 10083
Allocated
Group: 5
Generation Id: 313379940
uid / gid: 0 / 0
mode: rrw-r—-
size: 40000
num of links: 1
Inode Times:
Accessed:Tue Jan 18 08:51:03 2011
File Modified:Tue Jan 18 08:51:52 2011
Inode Modified:Tue Jan 18 08:51:52 2011
Direct Blocks:
43009 43010 43011 43012 43013 43014 43015 43016
43017 43018 43019 43020 43022 43023 43024 43025
43026 43027 43028 43029 43030 43031 43032 43033
43034 43035 43036 43037 43038 43039 43040 43041
43042 43043 43044 43045 43046 43047 43048 43049
Indirect Blocks:
43021
All I did there was find inode and block numbers for my test file so I could then use blkcat to see the contents.
asm boot # blkcat -h /dev/sda1 43009
0 41414141 41414141 41414141 41414141 AAAA AAAA AAAA AAAA
16 41414141 41414141 41414141 41414141 AAAA AAAA AAAA AAAA
...
992 41414141 41414141 41414141 41414141 AAAA AAAA AAAA AAAA
1008 41414141 41414141 41414141 41414141 AAAA AAAA AAAA AAAA
asm boot # blkcat -h /dev/sda1 43021
0 0ea80000 0fa80000 10a80000 11a80000 .... .... .... ....
16 12a80000 13a80000 14a80000 15a80000 .... .... .... ....
32 16a80000 17a80000 18a80000 19a80000 .... .... .... ....
48 1aa80000 1ba80000 1ca80000 1da80000 .... .... .... ....
64 1ea80000 1fa80000 20a80000 21a80000 .... .... ... !...
80 22a80000 23a80000 24a80000 25a80000 "... #... $... %...
96 26a80000 27a80000 28a80000 29a80000 &... '... (... )...
112 00000000 00000000 00000000 00000000 .... .... .... ....
...
992 00000000 00000000 00000000 00000000 .... .... .... ....
1008 00000000 00000000 00000000 00000000 .... .... .... ....
Here I checked the contents with TSK's blkcat and saw a bunch of A's as was expected and the indirect block contains other block numbers (in hex). So the next step was to wipe the file with srm and see what was left behind.
asm boot # srm -Df randfile
asm boot # blkcat -h /dev/sda1 43009
0 8e42d882 60df83f7 599fdf78 2a6ca3b9 .B.. `... Y..x *l..
16 cfbac122 050db37d e461324c ac08c138 ..." ...} .a2L ...8
...
992 26272cfd cb14e9ae 38821a73 ee2e70ac &',. .... 8..s ..p.
1008 eed20f83 70fd3d53 b43cd865 204fbfac .... p.=S .<.e O..
asm boot # blkcat -h /dev/sda1 43021
0 0ea80000 0fa80000 10a80000 11a80000 .... .... .... ....
16 12a80000 13a80000 14a80000 15a80000 .... .... .... ....
32 16a80000 17a80000 18a80000 19a80000 .... .... .... ....
48 1aa80000 1ba80000 1ca80000 1da80000 .... .... .... ....
64 1ea80000 1fa80000 20a80000 21a80000 .... .... ... !...
80 22a80000 23a80000 24a80000 25a80000 "... #... $... %...
96 26a80000 27a80000 28a80000 29a80000 &... '... (... )...
112 00000000 00000000 00000000 00000000 .... .... .... ....
...
992 00000000 00000000 00000000 00000000 .... .... .... ....
1008 00000000 00000000 00000000 00000000 .... .... .... ....
Random data was left behind on the direct blocks, this is normal. But what's interesting is that the indirect block (43021) was not overwritten and you can still see the block numbers in hex. Hal Pomeranz discovered the same behavior with the shred utility, it's very interesting to know that SRM and BCwipe also share the same behavior.

10 Comments

Posted January 19, 2011 at 3:13 PM | Permalink | Reply

Hal Pomeranz

Good follow-up, Juan! It's clear that any unprivileged tool that simply opens the file and writes data over the original content is going to miss the indirect block data. There would be an interesting GIAC Gold paper in writing a set-UID tool that would do a more thorough job via the raw disk devices. But I'm not sure the forensic community would thank the author of such a tool.

Posted January 19, 2011 at 4:40 PM | Permalink | Reply

Juan Leaniz

Thanks Hal. Yes, I would certainly be willing to write the tool for a Gold paper. I'll run the idea by Rob, and see what he thinks about it.

Posted January 19, 2011 at 5:28 PM | Permalink | Reply

techmonkey

How much does this behavior rely on the file system in use? For example, will it be the same on EXT3, EXT4, ReiserFS, etc?

Posted January 20, 2011 at 3:26 AM | Permalink | Reply

Rob Lee

Honestly, I am thinking of starting a "Gold Paper Research Ideas" under the SANS Community site. Someone could research the site and pick out ideas from research topics that could use some additional eyes on it.
Consider this'' how many mobile devices will run on top of some unix like filesystem? With more of these devices being created a tool such as this will become more and more valuable. This type of work and ideas are critical to the future of forensics and should not be lost.

Posted January 20, 2011 at 8:43 AM | Permalink | Reply

Sergio Hernando

Same results with Bruce's 7 pass:
sansforensics@SIFT-Workstation:~$ cat test.txt
this is a test
sansforensics@SIFT-Workstation:~$ ls -li test.txt
721089 -rw-rw-rw- 1 sansforensics sansforensics 15 2011-01-20 03:24 test.txt
sansforensics@SIFT-Workstation:~$ sudo istat /dev/sda3 721089
inode: 721089
Allocated
Group: 88
Generation Id: 156767109
uid / gid: 1000 / 1000
mode: rrw-rw-rw-
size: 15
num of links: 1
Inode Times:
Accessed:Thu Jan 20 03:27:22 2011
File Modified:Thu Jan 20 03:24:29 2011
Inode Modified:Thu Jan 20 03:24:29 2011
Direct Blocks:
2894058
sansforensics@SIFT-Workstation:~$ sudo blkcat /dev/sda3 2894058
this is a test
sansforensics@SIFT-Workstation:~$ bcwipe -ms test.txt
Wipe test.txt (y/[n]/a)?y
sansforensics@SIFT-Workstation:~$ sudo blkcat /dev/sda3 2894058
this is a test
Good catch and explanation! :)

Posted January 20, 2011 at 11:39 AM | Permalink | Reply

Juan Leaniz

techmonkey: I am pretty sure you will see the same behavior on ext3, but i don't know about ReiserFS or ext4. It would be interesting to check it out on ext4, but TSK doesn't fully support it as far as i know. It could be possible to use a different tool for the analysis.

Posted January 30, 2011 at 4:54 PM | Permalink | Reply

ED

I don't think this works on ext4, simply because ext4 does away with indirect blocks in favour of extents (and these extents are cleared when the file is deleted). Hans explains this in his 20th December post here.
"It's clear that any unprivileged tool that simply opens the file and writes data over the original content is going to miss the indirect block data."
''" As far as I know, all one would have to do to erase the indirect blocks is create a file the size of the filesystem (i.e. wipe free space). This way the indirect blocks are overwritten.

Posted February 5, 2011 at 11:16 AM | Permalink | Reply

ED

There would be an interesting GIAC Gold paper in writing a set-UID tool that would do a more thorough job via the raw disk devices."
''" I don't think this would be safe. You shouldn't write to raw disk devices while they are mounted with read-write access. I think something like this would need to come from the filesystem driver.
On the other hand indirect blocks don't contain that much information, in the above case they just show that file shredding software was used.

Posted August 8, 2012 at 11:41 AM | Permalink | Reply

Kyle

This is very interesting indeed, and I was able to reproduce on ext3. Thanks for the share.
To clarify my understanding of what is going on here. Before the drop caches is issued, the blkcat and icat are reading from the cache?
Is is it fair to say that the physical data has been shredded, but the running system can still read the data if its in the cache? Assuming that rebooting a system and running the blkcat test would result in the successful shredding result?

Posted August 15, 2013 at 1:06 PM | Permalink | Reply

Basil Peace

On the other hand indirect blocks don't contain that much information, in the above case they just show that file shredding software was used."
Fact of use of file shredding software can and will be used as indirect evidence in crime investigation.
"There would be an interesting GIAC Gold paper in writing a set-UID tool that would do a more thorough job"
This would be very useful for some purposes. And opinion of forensics is not interesting for people protecting their private data.
Really, I'm surprised that now there is no such tool.