File-Scan

 view release on metacpan or  search on metacpan

examples/scan.pl  view on Meta::CPAN

        exit(0);
}

#---display_msg-------------------------------------------------------------

sub display_msg {
	my $file = shift;
	my $virus = shift;

	$objects++;
	my $string = "No viruses were found";
	if($virus) {
		$infected++;
		$string = "Infection: $virus";
	}
	print "$file $string\n" if(!$QUIET || $virus);
	return();
}

#---check_path--------------------------------------------------------------

sub check_path {
	my $argv = shift;

	my @args = ();
	push(@args, "max_txt_size", $MAXTXTSIZE) if($MAXTXTSIZE);
	push(@args, "max_bin_size", $MAXBINSIZE) if($MAXBINSIZE);

	my $fs = File::Scan->new(
		extension => $EXTENSION,
		copy      => $CP_DIR,
		mkdir     => oct($MK_DIR),
		move      => $MV_DIR,
		delete    => $DELETE,
		@args);
	$fs->set_callback(
		sub {
			my $file = shift;
			local $_ = shift;
			if($UNZIP_PROG) {
				if(/^\x50\x4b\x03\x04/o) {
					# Extract compressed files in a ZIP archive
					my $files = &unzip_file($UNZIP_PROG, $TMP_DIR, $file);
					for my $f (@{$files}) {
						&check($fs, $f);
						unlink($f);
					}
					return("ZIP archive");
				}
			}
			if(/^MIME-Version: 1\.0\x0a/o) {
				# MHTML exploit
				if(my $insidefile = &mhtml_exploit($file)) {
					&check($fs, $insidefile);
					unlink($insidefile);
				}
				return("MHTML exploit");
			}
			if(/^[A-Za-z0-9\+\=\/]{76}\x0d?\x0a[A-Za-z0-9\+\=\/]{76}\x0d?\x0a/o) {
				# Base64 encoded file
				if(my $decodedfile = &decode_b64_file($TMP_DIR, $file)) {
					&check($fs, $decodedfile);
					unlink($decodedfile);
				}
				return("Base64 encoded file");
			}
			return("");
		}
	);
	for my $p (@{$argv}) {
		if(-d $p) {
			($p eq "/") or $p =~ s{\/+$}{}g;
			&dir_handle($fs, $p);
		} elsif(-e $p) {
			&check($fs, $p);
		} else {
			print "No such file or directory: $p\n";
			exit(0);
		}
	}
	return();
}

#---extract_file------------------------------------------------------------

sub extract_file {
	my $fh = shift;
	my $size = shift;
	my $buff = shift;
	my $file = shift;

	my $total = length($buff);
	open(NEWFILE, ">$file") or die("Can't open $file: $!\n");
	binmode(NEWFILE);
	print NEWFILE $buff;
	while(read($fh, $buff, $size)) {
		print NEWFILE $buff;
		if($MAXBINSIZE) {
			$total += $size;
			last if($total > $MAXBINSIZE*1024);
		}
	}
	close(NEWFILE);
	return();
}

#---decode_b64_file---------------------------------------------------------

sub decode_b64_file {
	my $tmp = shift;
	my $file = shift;

	my ($filename) = ($file =~ /\/?([^\/]+)$/);
	my $decoded = join("/", $tmp, "$filename\.eml");
	open(ENCFILE, "<$file") or die("Can't open $file to read: $!\n");
	open(DECFILE, join("", ">$decoded")) or die("Can't open $decoded to write: $!\n");
	binmode(DECFILE);
	while(<ENCFILE>) { print DECFILE decode_base64($_); }
	close(DECFILE);
	close(ENCFILE);  

	return($decoded);
}

#---mhtml_exploit-----------------------------------------------------------

sub mhtml_exploit {
	my $file = shift;

	my ($buff, $filename) = ("", "");
	my $size = 1024;
	open(FILE, "<$file") or die("Can't open $file: $!\n");
	binmode(FILE);
	while(read(FILE, $buff, $size)) {
		$buff =~ s{^MIME-Version: 1.0\x0aContent-Location: *File://([^\x0a]+)\x0aContent-Transfer-Encoding: binary\x0a\x0a}{}o or last;
		if($filename = join("/", $TMP_DIR, $1)) {
			&extract_file(\*FILE, $size, $buff, $filename);
			last;
		}
	}
	close(FILE);
	return($filename);
}

#---unzip_file--------------------------------------------------------------

sub unzip_file {
	my $program = shift;
	my $tmp_dir = shift;
	my $file = shift;   

	my $pid = open(UNZIP, "-|");
	defined($pid) or die("Cannot fork: $!");
	my @files = ();
	if($pid) {
		while(<UNZIP>) {
			if(my ($f) = (/$pattern/)[1]) {
				$f =~ s/ +$//g;
				push(@files, $f);
			}
		}
		close(UNZIP) or warn("unzip error: kid exited $?");
	} else {
		my @args = ("-P", "''", "-d", $tmp_dir, "-j", "-n");
		exec($program, @args, $file) or die("Can't exec program: $!");
	}
	return(\@files);
}

#---dir_handle--------------------------------------------------------------

sub dir_handle {
	my $fs = shift;
	my $dir_path = shift;

	unless(-r $dir_path) {
		print "Permission denied at $dir_path\n";
		return();
	}
	opendir(DIRHANDLE, $dir_path) or die("can't opendir $dir_path: $!");
	for my $item (readdir(DIRHANDLE)) {
		($item =~ /^\.+$/o) and next;



( run in 0.466 second using v1.01-cache-2.11-cpan-2398b32b56e )