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 AllocatedGroup: 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 430090 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.