#!/usr/bin/perl # # TimeCraver.pl # # 2015-08-23 # # This is a simple script that attempts to carve timestamps # from the binary data - it reads the binary data from # a given file and attempts to interpret bytes as potential # timestamps # # Currently the following timestmaps are recognized: # FILETIME # EPOCH # DOSTIME # Only dates between 2000-2015 are shown # # Usage: # perl TimeCraver.pl # Examples: # perl TimeCraver.pl config.bin use strict; use warnings; $| = 1; print STDERR " =========================================== TimeCraver v0.1, Hexacorn.com, 2015-08-23 =========================================== "; use warnings; use strict; use Time::Local ; my $YEAR_MIN = 2000; my $YEAR_MAX = 2015; my $f = shift || die ("\nGimme a parameter!\n"); open F,"<$f" || die ("\nCannot open '$f'!\n"); binmode F; read(F,my $d, -s $f); close F; while ( $d =~ /(.{4})(.{4})/gs ) { my $l=unpack("I",$1); my $h=unpack("I",$2); my $ofs=(pos $d)-8; my $hd=uc(unpack ("H*",$1.$2)); printif ($ofs,"EPOCH ",$hd,4,$l); printif ($ofs,"FILETIME",$hd,8,FILETIMEToEpoch($h,$l)); printif ($ofs,"DOSTIME ",$hd,4,DOSTimeToEpoch($l)); pos $d -=7; } sub printif { my $ofs = shift; my $desc = shift; my $hd = shift; my $hdl = shift; my $epoch = shift; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($epoch); $year += 1900; $mon += 1; if ($year > $YEAR_MIN && $year < $YEAR_MAX) { printf ("%08lX,%s,%08lX,%04d-%02d-%02d %02d:%02d:%02d,%s\n",$ofs,$desc,$epoch,$year,$mon,$mday,$hour,$min,$sec,substr($hd,0,$hdl<<1)); } } sub FILETIMEToEpoch { my $h = shift; my $l = shift; $h -= 27111902; $l -= 3577643008; my $epoch_time = int($h*429.4967296 + $l/1e7); return $epoch_time; } sub DOSTimeToEpoch { my $l = shift; my $t=$l&0xFFFF; my $d=$l>>16; return 0 if (0 == $d || 0 == $t); my $yr = ($d>>9)+1980; #0-119 my $mon = (($d & 0x1E0)>>5)-1; #1-12 (0-11) my $day = ($d & 0x1F); #1-31 my $hr = $t>>11; #0-23 my $min = ($t & 0x7E0)>>5; #0-59 my $sec = ($t & 0x1F)<<1; #0-29/*2 $sec-- if (60==$sec); my @months=(31,28,31,30,31,30,31,31,30,31,30,31); $months[$mon]++ if $mon == 1 && ( $yr%4&!$yr%100&$yr%400); # print "$yr-$mon-$day $hr:$min:$sec\n"; return 0 if ( $yr<$YEAR_MIN||$yr>$YEAR_MAX|| $mon<0||$mon>11|| $day<1||$day>$months[$mon]|| $hr<0||$hr>23|| $min<0||$min>59|| $sec<0||$sec>59 ); return timegm($sec, $min, $hr, $day, $mon, $yr); }