#! c:\perl\bin\perl.exe #--------------------------------------------------------- # sigs.pl # File signature analysis script for NT/2K systems # # usage: sigs.pl file # # Example file signature listing at the bottom of this # script should be copied to a file called 'sigs' (no # extension), and the comment symbols ('#') removed from # the lines containing the actual signatures. # # # Copyright 2000/2001 H. Carvey keydet89@yahoo.com #--------------------------------------------------------- use strict; my $dir = shift || die "Must supply a file or directory name.\n"; my @files; if (! -e $dir) { print "$dir not found.\n"; exit 1; } if (-f $dir) { push(@files,$dir); } if (-d $dir) { $dir = $dir."\\" unless ($dir =~ m/\\$/); opendir(DIR,$dir); while (my $list = readdir(DIR)) { my $file = $dir.$list; push(@files,$file) if (-f $file); } close(DIR); } #------------------------------------------------------------- # Read in the signature file #------------------------------------------------------------- my %sigs; my $sig_file_read = 0; my $sig_file = "sigs"; if (-e $sig_file) { if (readsigfile($sig_file)) { print "Signature file successfully read.\n"; $sig_file_read = 1; foreach (keys %sigs) { my @list = @{$sigs{$_}}; } } else { print "Signature file not read.\n"; } } print "Scan started: ".localtime(time)."\n"; foreach my $file (@files) { print "$file,"; # Check file size; skip if 0 if ((stat($file))[7] == 0) { print "File size is 0.\n"; next; } my $ext = getext($file); my ($hex,$resp) = getsig($file); if (0 == $resp) { print "Could not open file.\n"; next; } if ($sig_file_read) { my $match = 0; foreach my $key (keys %sigs) { if ($hex =~ m/^$key/) { $match = 1; if (grep(/$ext/i,@{$sigs{$key}})) { print "Sig match.\n"; } else { $hex = substr($hex,0,10); print "Sig does not match. ($ext,$hex)\n"; } } } $hex = substr($hex,0,10); print "Sig not listed. ($ext,$hex)\n" if (!$match); } } print "Scan completed: ".localtime(time)."\n"; #------------------------------------------------------------- # getext() #------------------------------------------------------------- sub getext { my $file = $_[0]; my $ext; my @filelist = split(/\./,$file); (@filelist > 1) ? ($ext = $filelist[@filelist - 1]) : ($ext = "none"); return $ext; } #------------------------------------------------------------- # getsig() #------------------------------------------------------------- sub getsig { my $file = $_[0]; my $success = 0; my $hex; eval { if (open(FH, $file)) { binmode(FH); my $bin; sysread(FH,$bin,20); close(FH); $hex = uc(unpack("H*",$bin)); $success = 1; } }; return ($hex,$success); } #------------------------------------------------------------- # readsigfile() #------------------------------------------------------------- sub readsigfile { my $file = $_[0]; if (-e $file) { open(FH,$file) || die "Could not open $file: $!\n"; while() { next if ($_ =~ m/^#/ || $_ =~ m/^\s+$/); chomp; my ($sig,$tag) = split(/:/,$_,2); my @list = split(/,/,$tag); $sigs{$sig} = [@list]; } close(FH); return 1; } else { return undef; } } # File signatures # Should be saved to a file called 'sigs', with '#' before # the signatures removed. #424D:bmp #3A42617365:cnt #D0CF11E0A1B11AE1:doc,xls,xlt #0100000058000000:emf #03000000C466C456:evt #4D5A:exe,sys,dll,drv,flt,fon,ocx,scr #3F5F0300:gid #474946383961:gif #474946383761:gif #1F8B08:gz #28546869732066696C65:hqx #00000100.00:ico #FFD8FFFE00:jpg,jpe,jpeg #FFD8FFE000:jpg,jpe,jpeg #4C000000011402:lnk #25504446:pdf #5245474544495434:reg #7B5C727466:rtf #504B0304:zip #lh:lzh #MThd:mid #0A050108:pcx #[InternetShortcut]:url