To do this, I use a custom made perl script inspired by a shell script made by Thomas Roessler in its analysis for the Forensic Challenge.
Here's a copy of the script readinodes.pl:
#!/usr/bin/perl use strict; my $ILS="~/scan15/tct-1.06/bin/ils"; my $ICAT="~/scan15/tct-1.06/bin/icat"; my $IMAGE="~/scan15/honeynet/honeypot.hda8.dd"; my $RECOVERY="recovery"; my $output = `$ILS -r $IMAGE`; my @deletedFiles = split(/\n/, $output); my $n=@deletedFiles; print "Found ",$n-3," files to recover.\n"; for (my $i=3; $i<$n; $i++) { # Recover files my @infos = split(/\|/, $deletedFiles[$i]); print "Recovering inode $infos[0]..."; print "(",$i-2,"/",$n-3,")\n"; system("$ICAT $IMAGE $infos[0] > $RECOVERY/$infos[0]"); my $filedata="$RECOVERY/$infos[0].infos"; print "Writing infos to $filedata\n"; open (DATAFILE,"> $filedata") || die "Can't write to file $filedata"; print DATAFILE "Inode $infos[0] recovered from $IMAGE\n\nRaw ILS data:\n"; print DATAFILE "st_ino|st_alloc|st_uid|st_gid|st_mtime|st_atime|st_ctime|st_dtime|"; print DATAFILE "st_mode|st_nlink|st_size|st_block0|st_block1\n"; print DATAFILE $deletedFiles[$i],"\n\nSome formatted infos:\n"; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($infos[4]); $year+=1900; print DATAFILE sprintf("Last Modification time: %i/%i/%i %2i:%2i:%2i\n", $mday,$mon+1,$year,$hour,$min,$sec); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($infos[5]); $year+=1900; print DATAFILE sprintf("Last Access time: %i/%i/%i %2i:%2i:%2i\n",$mday, $mon+1,$year,$hour,$min,$sec); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($infos[6]); $year+=1900; print DATAFILE sprintf("Last inode status change time: %i/%i/%i %2i:%2i:%2i\n", $mday,$mon+1,$year,$hour,$min,$sec); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($infos[7]); $year+=1900; print DATAFILE sprintf("Deletion time (Linux only): %i/%i/%i %2i:%2i:%2i\n", $mday,$mon+1,$year,$hour,$min,$sec); print DATAFILE sprintf("File type: %s\n", substr($infos[8],0,2)); print DATAFILE sprintf("File permissions: %s\n", substr($infos[8],2,4)); print DATAFILE sprintf("File size: %i bytes; %.1f KB; %.2f MB\n", $infos[10], $infos[10]/1024, $infos[10]/1048576); print DATAFILE "\nNote that the date are written the right way (at least here, ", "in Canada), that's:\nday/month/year hour:min:sec\n"; close (DATAFILE); } exit(0);
This script uses icat and ils from The Coroner's Toolkit (TCT)
by Dan Farmer and Wietse Venema.
The script dumps the recovered inodes in the folder recovery
along with some informations about them.
All we have to do now is to open the files representing the inodes we are interested in, in this case, inode 23 and 2038.
[gfk@cesam scan15]$ cat recovery/23.infos Inode 23 recovered from ~/scan15/honeynet/honeypot.hda8.dd Raw ILS data: st_ino|st_alloc|st_uid|st_gid|st_mtime|st_atime|st_ctime|st_dtime|st_mode| st_nlink|st_size|st_block0|st_block1 23|f|0|0|984706608|984707090|984707105|984707105|100644|0|520333|307|308 Some formatted infos: Last Modification time: 15/3/2001 20:36:48 Last Access time: 15/3/2001 20:44:50 Last inode status change time: 15/3/2001 20:45:5 Deletion time (Linux only): 15/3/2001 20:45:5 File type: 10 File permissions: 0644 File size: 520333 bytes; 508.1 KB; 0.50 MB Note that the date are written the right way (at least here, in Canada), that's: day/month/year hour:min:sec [gfk@cesam scan15]$ cp recovery/23 rootkit/lk.tar [gfk@cesam scan15]$ cd rootkit [gfk@cesam rootkit]$ gunzip lk.tgz [gfk@cesam rootkit]$ tar xvf lk.tar last/ last/ssh last/pidfile last/install last/linsniffer last/cleaner last/inetd.conf last/lsattr last/services last/sense last/ssh_config last/ssh_host_key last/ssh_host_key.pub last/ssh_random_seed last/sshd_config last/sl2 last/last.cgi last/ps last/netstat last/ifconfig last/top last/logclear last/s last/mkxfs
It is not possible to read the content of deleted folder last
because it's inode number (2038) is empty. Most likely this is because there has
been some disk activity between the erasure of the folder and the image of the partition has been taken:
[gfk@cesam scan15]$ cat recovery/2038.infos Inode 2038 recovered from ~/scan15/honeynet/honeypot.hda8.dd Raw ILS data: st_ino|st_alloc|st_uid|st_gid|st_mtime|st_atime|st_ctime|st_dtime|st_mode| st_nlink|st_size|st_block0|st_block1 2038|f|1031|100|984707105|984707105|984707105|984707169|40755|0|0|8481|0 Some formatted infos: Last Modification time: 15/3/2001 20:45:5 Last Access time: 15/3/2001 20:45:5 Last inode status change time: 15/3/2001 20:45:5 Deletion time (Linux only): 15/3/2001 20:46:9 File type: 40 File permissions: 755 File size: 0 bytes; 0.0 KB; 0.00 MB Note that the date are written the right way (at least here, in Canada), that's: day/month/year hour:min:sec [gfk@cesam scan15]$ cat recovery/2038 | od 0000000
But we can still get its original content by untarring the compressed file lk.tgz
as we did in the precedent step.