#!/usr/pkg/bin/perl

my $version = "2.21";

# Copyright (c) 2000 - 2003 Marco van Berkum

# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.

# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.

# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Programmed by:
# Marco van Berkum, m.v.berkum@obit.nl
# Kristian Vlaardingerbroek, kris@obit.nl
# Pepijn Vissers, zoef@zoefdehaas.nl
# Herman Poortermans, herman@ofzo.nl
#
# Website: http://ws.obit.nl
#
# Hackbot is also a freshmeat project
# http://freshmeat.net/projects/hackbot/


use IO::Socket;
use Net::hostent;
use Getopt::Std;

# core functionality

&getopts('AitfmsSdprVl:w:z:a:XF:M:O:P:g:');

use vars qw(
	$opt_A 
	$opt_i 
	$opt_t 
	$opt_f 
	$opt_m 
	$opt_s 
	$opt_S 
	$opt_d 
	$opt_p
	$opt_r 
	$opt_V 
	$opt_l 
	$opt_w 
	$opt_z 
	$opt_a 
	$opt_X 
	$opt_F 
	$opt_O 
	$opt_P 
	$opt_g
);

if (!$opt_F) { $host = $ARGV[0]; } else {chomp $opt_F; $targetfile = $opt_F};

        if($opt_V) {
                print("Hackbot version $version\n"); exit(0);
        }

if (
       ( !$host && !$opt_F )
    || ( $host && $opt_F )
    || (   !$opt_A
        && !$opt_i
        && !$opt_t
        && !$opt_f
        && !$opt_m
        && !$opt_s
        && !$opt_S
        && !$opt_d
	&& !$opt_p
        && !$opt_r
        && !$opt_w
        && !$opt_z
        && !$opt_a
        && !$opt_X
        && !$opt_F
        && !$opt_P 
	&& !$opt_g
	&& !$ARGV[1])
  )
{
	print("Hackbot version $version\nusage: ./hackbot.pl <options> <ip,hostname,net,or range>\n\n");
        print("or: ./hackbot.pl <options> -F <targetfile>\n\n");
        print("Available options:\n");
	print("-O <output file>\n");
        print("-A\t\tAll scan types\n");
	print("-i\t\tIdentd scan\n");
	print("-t\t\tSimple Telnet Fingerprint\n");
        print("-f\t\tFTP scan\n");
        print("-m\t\tMTA scan\n");
        print("-s\t\tSSH scan\n");
	print("-S\t\tSpammer check\n");
        print("-d\t\tDNS scan\n");
	print("-p\t\tPOP3 scan\n");
	print("-r\t\tRegistrar whois lookup\n");
	print("-V\t\tPrint version and exit\n");
	print("-P <host:port>\tUse proxy for scanning\n");
	print("-g <string>\tGoogle search \(uses strings from google.db when -A option is used\)\n");
        print("-l <type>\tloglevel\n");
	print("\t\tc  critical (default)\n");
        print("\t\tv  verbose\n");
        print("\t\td  debug\n");
	print("-w <type>\tWebserver scan\n");
        print("\t\ta  All scans\n");
        print("\t\tv  Version scan\n");
        print("\t\to  HTTP Options scan\n");
        print("\t\tc  CGI scan\n");
        print("\t\ti  IDA scan\n");
        print("\t\tu  Unicode scan\n");
        print("\t\tn  Nimda scan\n");
	print("-z <NN>\t\tSet time in seconds between each CGI poll \(to be less conspicuous\)\n");
	print("-a <NN>\t\tSet alternative webserver port\n");
	print("-X\t\tX allow check\n\n");
        print("examples:\t./hackbot.pl -f -m -w oci localhost\n");
        print("\t\t./hackbot.pl -A 192.168.75.3 195.0.0.255\n");
	print("\t\t./hackbot.pl -s 192.168.75.0\/26\n");
	print("\t\t./hackbot.pl -g britney www.geocities.com\n");
	print("\t\t./hackbot.pl -A -lv localhost\n\n");
	exit(0);
}

$database = "/usr/pkg/share/hackbot/cgi.db";
$fingerprintdb = "/usr/pkg/share/hackbot/fingerprint.db";
$googledb = "/usr/pkg/share/hackbot/google.db";

# print(`clear`);
print("\n");
&banner;

$noprint = 1; log_print(`date`,"c"); log_print("\n","c"); undef($noprint);

if($opt_l) {
        if(($opt_l !~ /^[cdv]+$/ ))
        {
                print "Unknown loglevel defenition: " . $opt_l . "\n";
                exit(0);
        }
}

if($opt_w) {
        if(($opt_w !~ /^[aociunv]+$/ ))
        {
                print "Unknown webserver scan type: " . $opt_w . "\n";
                exit(0);
        }
}



if($opt_a) {
	if(!$opt_A && !$opt_w) {
		print("Please define more options\n");
		print("Quitting...\n");
		unlink "output.$host";
		exit(0);
		}
	chomp($opt_a);
	$port = $opt_a;
} else {
	$port = "80";
}


if($opt_z) {
	if(!$opt_A && !$opt_w) {
		print("Please define more options\n");
		print("Quitting...\n");
		unlink "output.$host";
		exit(0);
		}
	chomp($opt_z);
}

if($opt_P) {
	($proxy, $proxyport) = split(/:/, $opt_P);
	chomp($proxy);
	chomp($proxyport);
	$userinputproxythingy = $proxy;
	if ($proxy =~ /[A-z]/) {
		log_print("Trying to resolve proxyhost $proxy\n","h");
		my $handler = gethost($proxy);
		if(!$handler) {
			log_print("proxyhost $proxy does not resolve, will continue scan without using a proxy\n\n","i");
			undef($proxy);
			undef($proxyport);
		} else {
		$proxy = inet_ntoa(@{$handler->addr_list}[0]);
		log_print("Resolved $userinputproxythingy to $proxy\n","c");
		log_print("Testing if the proxy works..\n\n","h");
		&proxytest($proxy, $host);
		$tested = 1;
		}
	}
	if ($proxy !~ /[A-z]/) {
		log_print("Testing if the proxy works..\n","h") unless($tested);
		&proxytest($proxy, $host) unless($tested);
	}

	undef($tested);
}


if($opt_F) {
        $date = `date`;
        open(TARGETLIST,"$targetfile") || die "$0:     Could not read from $targetfile! ($!)";
        while (<TARGETLIST>) { chomp; push(@targetlist, $_); }

        foreach $host (@targetlist) {
        log_print("Checking $host ...\n\n","h");
        &scanit }
	} else {
		if ($host=~/[A-z]/)
		{
			log_print("Checking named host $host ...","c");
			&scanit;
		} else { 
        	   &GetRange;
	           $range = "1";
		   unless("$start" eq "$end") { log_print("Range Scan from $start to $end\n","c"); }	
		   foreach $host (@targetlist) {
       		   	log_print("\nChecking $host ...\n\n","c");
        		&scanit; 
			}		
     }
}

&endbanner;

# end core


###############
# Subroutines #
###############

sub scanit {

        if (!&check_ip($host)) {
                log_print(" trying to resolve hostname $host\n\n","c");
                my $handler = gethost($host);
                if(!$handler) {
                        log_print("$host does not resolve, I died\n\n","c");
                        if($opt_O) {
                          unlink $opt_O;
                        } else {
                          unlink "output.$host";
                        }
                        exit(0);
                        }
                $target = inet_ntoa(@{$handler->addr_list}[0]);
                log_print("resolved host to: $target\n\n","i");
                $host_resolves = 1;
                } else {
                $target = $host;
                $host_resolves = 0;
                }
	if($opt_A){
	$opt_i="1";$opt_t="1";
	$opt_f="1";$opt_m="1";
	$opt_s="1";$opt_S="1";
        $opt_d="1";$opt_r="1";
	$opt_w="a";$opt_X="1";
	$opt_g="1";$opt_p="1";

	#now you can undef opt_A in case of no web. 
	# undef after this line
	}

	if($opt_S) {
		header_reset();
		&spamcheck;
	}
	if($opt_i) {
		header_reset();
		&ident;
	}
	if($opt_t) {
		header_reset();
		&telnetfprint;
	}
        if($opt_f) {
		header_reset();
                &ftp;
        }
        if($opt_m) {
		header_reset();
                &mta;
		&evilsendmail;
        }
        if($opt_s) {
		header_reset();
                &ssh;
        }
        if($opt_d) {
		header_reset();
                &dns;
        }
	if($opt_p) {
		header_reset();
		&pop3;
	}
	if($opt_r) {
		header_reset();
		&whois unless ($nowhois);
		$nowhois = $range;
	}
	if($opt_X) {
		header_reset();
		&xcheck;
	}
        if($opt_g) {
		header_reset();
		$gdefined = $opt_g unless($opt_g == "1");
		chomp($gdefined) unless(!$gdefined);
      		my $google_handler = gethost("www.google.com");
		        if(!$google_handler) {
		                print("cannot resolve www.google.com, skipping google search\n");
		                undef($opt_G);
        		} elsif ($google_handler) {
        	$google_ip = inet_ntoa(@{$google_handler->addr_list}[0]);
	        &googlescan($google_ip, $target, $gdefined);
        }
}
        if($opt_w) {
		header_reset();
                &checkweb;

                if(($opt_w =~ /o/)||($opt_w =~ /a/)) {
                        header_reset();
			&http_options unless $noweb;
                }
                if(($opt_w =~ /c/)||($opt_w =~ /a/)) {
                       header_reset();
			log_print("\n","c");
			&cgi unless $noweb;
                        &netscape unless $noweb;
                }
                if(($opt_w =~ /i/)||($opt_w =~ /a/)) {
                        header_reset();
			&ida unless $noweb;
                }
                if(($opt_w =~ /u/)||($opt_w =~ /a/)) {
                        header_reset();
			&unicode unless $noweb;
                        &unicode2 unless $noweb;
                }
                if(($opt_w =~ /n/)||($opt_w =~ /a/)) {
                        header_reset();
			&nimda unless $noweb;
                }
        } 

}


sub check_ip {
	my $ipaddr = shift;

	if ($ipaddr !~ /^[0-9\.]+$/) { return 0 }
	if ($ipaddr !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { return 0 }
	for ($1, $2, $3, $4) { return 0 if ($_ > 255) }
	return 1;
}

sub banner {
	log_print("###############################################################\n","c");
	log_print("#      HackBot v$version 2003 / http://ws.obit.nl/hackbot/        #\n","c");
	log_print("#               (c) 2000-2003 Marco van Berkum                #\n","c");
	log_print("#                                                             #\n","c");
	log_print("# Marco van Berkum            - m.v.berkum\@obit.nl            #\n","c");	
	log_print("# Kristian Vlaardingerbroek   - kris\@obit.nl                  #\n","c");
	log_print("# Pepijn Vissers              - zoef\@zoefdehaas.nl            #\n","c");
	log_print("# Martijn Mooijman            - foobar\@obit.nl                #\n","c");
	log_print("# Herman Poortermans          - herman\@ofzo.nl                #\n","c");
	log_print("###############################################################\n","c");
	log_print("\n","c");
}


sub cgi {
	if (!-e $database) { 
		$nodb = 1;
		}

	open CGI, "<$database" unless($nodb);
	# potential bugfix
	undef($exploit); undef($description); undef($advisory);
	
	# actual code
	log_print("Checking the webserver on port $port for various potential problems\n","h") unless($nodb);
	log_print("------------------------------------------------------------------\n","h") unless($nodb);
	
	while(1) {
        	if($nodb) { 
			log_print("No db found it should be in $database, skipping CGI scan\n","c");
			last;
		}	

		if($proxy) {
		log_print("Scanning via proxy $proxy\n\n","h");
                while(<CGI>) {
			if($opt_z) { sleep($opt_z); }
                        ($exploit, $description, $advisory) = split(/\!/, $_);

# debug flag, where are we ?
	log_print("checking for: $exploit\n","d");

                        chomp($exploit, $description, $advisory);



                        my $sock = new IO::Socket::INET (PeerAddr => $proxy, PeerPort => $proxyport, Proto => 'tcp', Timeout => '5');
                        if($sock && $exploit) {


                                if($host_resolves == 1) {
                                        print $sock "GET http://$host$exploit HTTP/1.0\r\n\r\n";
                                } else {
                                        print $sock "GET http://$target$exploit HTTP/1.0\r\n\r\n";
                                }
                                sysread($sock, $buff, 15000);
                                if($buff =~ /200 OK/) {
                                log_print("* $exploit found!\n","c");
                                log_print("* $description\n","c") unless (!$description);
                                log_print("* $advisory\n","c") unless (!$advisory);
                                log_print("\n","c");
                                close($sock); } 
                        	} 
		}} else
			{
		while(<CGI>) {
			if($opt_z) { sleep($opt_z); }
			($exploit, $description, $advisory) = split(/\!/, $_);
			chomp($exploit, $description, $advisory);

# debug flag, where are we ?
        log_print("checking for: $exploit\n","d");

			my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');
			if($sock) {
				if($host_resolves == 1) {
					print $sock "GET http://$host$exploit HTTP/1.0\r\n\r\n";
				} else {
					print $sock "GET $exploit HTTP/1.0\r\n\r\n";
				}
				sysread($sock, $buff, 15000);
				if($buff =~ /200 OK/) {
				log_print("* $exploit found!\n","c");
				log_print("* $description\n","c") unless (!$description);
				log_print("* $advisory\n","c") unless (!$advisory);
				log_print("\n","c");
				close($sock);
				}
			}	
		} 
	}

	close CGI;
	last;
 	}	
}

sub mta {
	log_print("Trying MTA - Relaying, VRFY and EXPN\n","h");
	log_print("------------------------------------\n","h");
	my $sock = new IO::Socket::INET (
        	PeerAddr => $target,
        	PeerPort => '25',
        	Proto => 'tcp',
        	Timeout => '7'
        	); 

	if(!$sock) {
		log_print("No MTA\n\n","i");
	}

	while($sock) {
		$cnt = sysread($sock, $buff, 15000);
		if(!$cnt) {
			log_print("Hmmm weird socket error, I died\n\n","c");
			close($sock);
			last;
		}		
		log_print("$buff","c"); 

                if($buff =~ /^220 \*\*\*\*\*\*\*\*\*/) {
		log_print("This mailserver is probably protected by a Cisco Pix Firewall with MailGuard enabled\n","c");
		log_print("\nLets try to outsmart it \:\)\_\n\n","c");
		print $sock "data\r\n";
		sleep(3);
		sysread($sock, $buff, 1500);
		print("return after DATA command is: $buff\n");

		if($buff !~ /^500/) {
		log_print("Sending EHLO command\n","h");
		print $sock "EHLO hackbot\r\n";
		sleep(3);
		sysread($sock, $buff, 1500);

		if($buff !~ /^500/) {
		log_print("worked..\n\n","c");
		log_print("$buff\n","c");
		} else { 
		log_print("didn't work..\n\n","i");
		}
						
		log_print("Sending HELP command\n","h");
		print $sock "HELP\r\n";
		sleep(3);
		sysread($sock, $buff, 1500);

		if($buff !~ /^500/) {
		log_print("worked..\n\n","c");
		log_print("$buff\n");
		} else {
		log_print("didn't work..\n\n","i");
		}
		
		log_print("Trying VRFY command\n","h");
		print $sock "vrfy root\r\n";
		sleep(3);
		sysread($sock, $buff, 1500);

		if ($buff =~ /^250/) {
		log_print("worked..\n\n","c");
		log_print("$buff\n");
		} else { 
		log_print("didn't work..\n\n","i");
		}

		log_print("Trying EXPN command\n","h");
		print $sock "expn root\r\n";
		sleep(3);
		sysread($sock, $buff, 1500);

		if ($buff =~ /^250/) {
		log_print("worked..\n\n","c");
		log_print("$buff\n","c");
		} else {
		log_print("didn't work..\n\n","i");
		}
		log_print("Done playing with PIX for now, let's continue with the normal commands\n\n","i");
		print $sock "RSET\r\n";
		}
		}

		undef($buff);
		sleep(1);
		print $sock "helo bla\r\n";
		sleep(2);
		sysread($sock, $buff, 150);
		log_print("$buff\n","d");
		print $sock "mail from: bill.gates\@microsoft.com\r\n";
		sleep(1);
		sysread($sock, $buff, 150);
		log_print("$buff\n","d");
		print $sock "rcpt to: bill.gates\@microsoft.com\r\n";
		sleep(1);
		sysread($sock, $buff, 150);
		log_print("$buff\n","d");
		if ($buff =~ /^250/) {
			log_print("Relaying allowed\n\n","c");
			} else {
			log_print("Relaying not allowed\n\n","i");
		}

		print $sock "vrfy root\r\n";
		sleep(1);
		sysread($sock, $buff, 15000);
		log_print("$buff\n","d");
		if ($buff =~ /^250/) {
			log_print("VRFY enabled\n\n","c");
			log_print("$buff\n");
			} else {
			log_print("VRFY not enabled\n\n","i");
		}

		print $sock "expn root\r\n";
		sleep(1);
		sysread($sock, $buff, 15000);
		log_print("$buff","d");
		if ($buff =~ /^250/) {
			log_print("EXPN enabled\n\n","c");
			print "$buff\n"
		} else {
		log_print("EXPN not enabled\n\n","i");
		}

		log_print("\n","c");
		close(!$sock);
		last;
		}
}

sub checkweb {
	undef($noweb);
	log_print("\n","h");
        log_print("Checking for webserver on port $port\n","h");
	log_print("-----------------------------------\n","h");
        my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');
        if ($sock) {
                if($host_resolves == 1) {
		        print $sock "HEAD http://$host/ HTTP/1.0\r\n\r\n";
                } else {
		        print $sock "HEAD / HTTP/1.0\r\n\r\n";
                }
		sleep(2);
		sysread($sock, $httpversion, 15000);

		if($opt_w =~ /v/ || $opt_w =~ /a/ || $opt_A) {
       		 	log_print("$httpversion\n","c");

			if ($httpversion =~ /Apache/) {
				&modphpssl($httpversion);
			}

		} else {
		log_print("Webserver found\n\n","c");
		}
        } else {
        $noweb = 1;
        log_print("No webserver\n","i");
   }
}

sub http_options {
	log_print("HTTP options\n","h");
	log_print("------------\n","h"); 
	my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');

	# potential bugfix
	undef($allow); undef($public);

	# actual code

	if ($sock) {
                if($host_resolves == 1) {
			print $sock "OPTIONS http://$host/ HTTP/1.0\r\n\r\n";
		} else {
			print $sock "OPTIONS / HTTP/1.0\r\n\r\n";
		}
		sysread($sock, $buff, 5000);
		$allow = $buff; $public = $buff;
		($tmp, $allow) = split(/Allow:(.*)/, $buff);
		($tmp, $public) = split(/Public:(.*)/, $buff);
		log_print("Allow options : $allow\n","c") unless(!$allow);
		log_print("Public options: $public\n","c") unless(!$public);
		close($sock);
	} 
		if ($httpversion =~ /IIS/) {
			log_print("\n","c");
			&propfind($target);
			&isapi($target);
		}
}


sub ida {
@idas = ('ida','idq','idc');
log_print("\nChecking for ida\n","h");
log_print("----------------\n","h");
foreach(@idas) {
	my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');
	if ($sock) {
		if($host_resolves == 1) {
			print $sock "GET http://$host/blabla.$_ HTTP/1.0\r\n\r\n";
		} else {
			print $sock "GET /blabla.$_ HTTP/1.0\r\n\r\n";
		}
		sleep(3);
		sysread($sock, $buff, 1000);
		if ($buff =~ /\:\\/) {
			($temp, $lastline) = split(/file\ /,$buff);
			($path) = split(/\ /,$lastline);
			log_print("$path\n","c");
 		}
		close($sock);
   	} 
}
#log_print("\n","c");
}


sub unicode {
	@vuln = ('msadc','scripts');
	log_print("Unicode tests\n","h");
	log_print("-------------\n","h");
	log_print("Checking for unicode with ..\%c0\%af..\n","h");

	foreach(@vuln) {
		my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');
		if ($sock) { $buff = ""; $current = $_;
			if($host_resolves == 1) {
				print $sock "GET http://$host/$current/..\%c0\%af../..\%c0\%af../..\%c0\%af../..\%c0\%af../..\%c0\%af../winnt/system32/cmd.exe\?\/c+bla HTTP/1.0\n\n";
			} else {
				print $sock "GET /$current/..\%c0\%af../..\%c0\%af../..\%c0\%af../..\%c0\%af../..\%c0\%af../winnt/system32/cmd.exe\?\/c+bla HTTP/1.0\n\n";
			}
			sysread($sock, $buff, 9000);
			close($sock);
			if ($buff =~ /Content-Type: application\/octet-stream/) {
				log_print("Unicode vulnerable with $current and ..\%c0\%af.. \n","c");
  				}
			close($sock);
  			}
 		}
		undef($current);
}


sub unicode2 {
	log_print("Checking for unicode with ..\%255c..\n","h");

	foreach(@vuln) {
		my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');
		if ($sock) { $buff = ""; $current = $_;
			if($host_resolves == 1) {
				print $sock "GET http://$host/$current/..\%255c../..\%255c../..\%255c../..\%255c../..\%255c../winnt/system32/cmd.exe\?\/c+bla HTTP/1.0\n\n";
			} else {
				print $sock "GET /$current/..\%255c../..\%255c../..\%255c../..\%255c../..\%255c../winnt/system32/cmd.exe\?\/c+bla HTTP/1.0\n\n";
			}
			sysread($sock, $buff, 9000);
			close($sock);
				if ($buff =~ /Content-Type: application\/octet-stream/) {
					log_print("Unicode vulnerable with $current and ..\%255c.. \n","c");
  				}
			close($sock);
  			}
 		}
}

sub nimda {
	my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');
	if ($sock) {
		log_print("\nchecking for nimda infection\n","h");
		log_print("----------------------------\n","h");
		if($host_resolves == 1) {
			print $sock "GET http://$host/blaat HTTP/1.0\n\r\n\r";
		} else {
			print $sock "GET /blaat HTTP/1.0\n\r\n\r";
		}
		sleep(5);
		sysread($sock, $buff, 15000);
			if ($buff =~ /eml/ig) {
			log_print("eml found at $target, it's probably infected\n","c");
     			}
		 close($sock);
   		}
 header_reset();
}


sub dns { 
	log_print("Checking for DNS\n","h");
	log_print("----------------\n","h");
	my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => 53, Proto => 'tcp', Timeout => '5');
	if ($sock) {                  
		$nsversion = `dig \@$target version.bind chaos txt`;
		($temp, $bind) = split(/\"/, $nsversion);
		$temp = "";
		log_print("Bindversion: $bind\n\n","c") unless !$bind;
		if(!$bind) { log_print("Name daemon is running but returned no version\n\n","c"); }
  	} else {
          	log_print("No DNS\n\n","i");
        }
    	close($sock);
}
 

sub ssh {
	log_print("Checking for SSH\n","h");
	log_print("----------------\n","h");

	my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => 22, Proto => 'tcp', Timeout => '5');

	if(!$sock) {
		log_print("No SSH\n\n","i");
	}
	while($sock) {
		sleep(5);
		$cnt = sysread($sock, $buff, 10000);
		if(!$cnt) {
			log_print("huh, fscking TCP wrappers, I died\n\n","i");
			last;
		}
		log_print("$buff\n","c");

   		close($sock); 
   		last;
	}
}


sub netscape {
if ($httpversion =~ /Netscape/) {
	@netscape = ('/?wp-cs-dump','?PageServices');
	foreach(@netscape) {
	my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');

	if (!$sock) {
	log_print("Webserver died?\n\n","i");
	}
	while($sock) {
	if($host_resolves == 1) {
        	print $sock "GET http://$host/$_ HTTP/1.0\r\n\r\n";
	} else {
        	print $sock "GET /$_ HTTP/1.0\r\n\r\n";
	}
        $cnt = sysread($sock, $buff, 15000);
	if (!$cnt) {
	log_print("Webserver died?\n\n","i");
	close($sock);
	last;
	}
	if ($buff =~ /200 OK/) {
	log_print("$_ found\!\n* Netscape $_ bug, try http://www.somehost.com/$_\n","c");
    }
   }
  }
 }
}

sub ftp {

log_print("\nChecking for FTP server\n","h");
log_print("-----------------------\n","h");
        my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => 21, Proto => 'tcp', Timeout => '5');
        if (!$sock) {
        log_print("No FTP server\n\n","i");
        }
        while($sock) {
                print $sock "user anonymous\r\n";
                sleep(2);
                $cnt = sysread($sock, $buff, 10000);
                if(!$cnt) {
                log_print("huh, fscking TCP wrappers, I died\n\n","i");
                last;
                }
                undef($cnt);
                log_print("FTP Server Found:\n$buff\n","c");
                print $sock "pass bla\@bla.com\r\n";
                sleep(2);
                $cnt = sysread($sock, $buff, 1000);
                if(!$cnt) {
                last;
                }

                if ($buff =~ /230/) {
                log_print("Anonymous login allowed\!\n\n","c");
                log_print("Checking for upload/ directory\n\n","h");
                print $sock "CWD upload\r\n";
                sleep(2);
		undef($cnt);
                $cnt = sysread($sock, $buff, 1000);
		print $buff,"\n";
                if(!$cnt){ last; }
                if ($buff =~ /250/) {
                        log_print("Got it... checking write possibilities\n\n","c");
                        print $sock "STOR hackbotwashere.bla\r\n";
                        sleep(2);
                        $cnt = sysread($sock, $buff, 100);
                        if ($buff =~ /553/){
                                log_print("nope, no write-access\n\n","c");
                                } else {
                                log_print("yup... write-access\n\n","c");
                                } 
                       }
                } else {
                log_print("Anonymous login NOT allowed\n\n","c");
                }
                close($sock);
                last;
        }
}

sub GetRange {
	$start = $ARGV[0];
	$end = $ARGV[1];
	     if ($start=~/\*/){            
             @target=split/\./,$start;
             $start= ( &genipstart );  
             $end= ( &genipend);
             }
	($ippart, $bit) = split(/\//,$start);
		#CIDR
		if($bit ne "") 
		{ 
			($a,$b,$c,$d) = split(/\./,$ippart);

			if ($bit <= 23) 
			{
        				die "Error: CIDR Mask < /24 currently unsupported.\n";
   			 } elsif ($bit >= 31) {
       						 die "Error: CIDR Mask '$bit' is invalid.\n";
    					       }
    						$prefix = "$a.$b.$c.";
    						$network = $d;
    						$nhosts = (2 ** (32 - $bit));
    						$netmask = (256 - $nhosts);
   			 unless ($netmask > 0 && $netmask / $nhosts) 
    			{
       			 die "Invalid Network: Netmask $netmask, Hosts $nhosts\n" unless($netmask eq 0);
    			}
   			 $start=$ippart;	
			 $end="$prefix".($nhosts + $network  - 1);
		}

		if($start ne "" && $end eq "")
		{
		$end=$start;
		}
		
		if($start eq "" || $end eq "" ) { &InputError; };

	@IPstart = split(/\./,$start);
	@IPend = split(/\./,$end);
		&Check_Start_and_EndIP;

		#converts "short" (dotted) IPs to "long" (undotted) IPs

		$IPstart = (($IPstart[0]*16777216)+($IPstart[1]*65536)+($IPstart[2]*256)+$IPstart[3]);
		$IPend = (($IPend[0]*16777216)+($IPend[1]*65536)+($IPend[2]*256)+$IPend[3]);

		if($IPend < $IPstart) { die "Can't scan backwards"; }
	$CountIp = $IPstart;
        $EndIp = $IPend+1;

		while($CountIp ne $EndIp) 
		{
 				  @Class = &GetIP($CountIp);
                         	  push(@targetlist, "$Class[1]\.$Class[2]\.$Class[3]\.$Class[4]");
				  $CountIp++;
 		}
}

sub GetIP{
	 # converts "long" (undotted) IPs into "short" (dotted) IPs
	 my($ip) = @_;
 	 $Class[1] = int ( $ip / 256**3);
 	 $Class[2] = int ( $ip % 256**3 / 256**2 );
 	 $Class[3] = int ( $ip % 256**3 % 256**2 / 256**1 );
 	 $Class[4] = int ( $ip % 256**3 % 256**2 % 256**1 );
 	 @Class;
}

sub InputError {
 print "need [starting IP] [ending IP]\n\n";
 die "Wrong input";
}


sub Check_Start_and_EndIP{
                   if (!&check_ip($start)) {
                   print "\nStarting IP is not valid\n";
                   die "Exiting on bad starting IP";
                   }
  
                   if (!&check_ip($end)) {
                   print "\nEnding IP is not valid\n";
                   die "Exiting on bad ending IP";
		   }
}

sub genipstart { for(@target){ if( $_=~/\*/){ push(@tmp, 0);}
                             else {push(@tmp, $_);}
                               }
                "$tmp[0].$tmp[1].$tmp[2].$tmp[3]"
                }

sub genipend { for(@target){if( $_=~/\*/){ push(@tmp2, 255);}
                           else {push(@tmp2, $_);}
                             }
               "$tmp2[0].$tmp2[1].$tmp2[2].$tmp2[3]"
             }
             
sub log_print{
(my $logstring, $_ )= @_;    

Msg_Indexer:{
               /h/ and header($logstring), last Msg_Indexer;
               /c/ and critical($logstring), last Msg_Indexer;
	       /i/ and info($logstring), last Msg_Indexer;       
	       /d/ and debug($logstring), last Msg_Indexer;
	      final_print ("Def.:$logstring");
              }
}

sub header{ 
if($opt_l =~ /[d]/){$header.="header:\t";}
$header.=shift;
}

sub header_reset{
undef $header;
}
sub critical{
final_print("$header");
undef $header;
	if($opt_l =~ /[d]/){ 
	final_print("critic:\t".shift)
	}else 
	{ 
	final_print(shift);
	}
}

sub info{
	if($opt_l =~ /[vd]/){
		final_print($header);
		undef $header;
		if($opt_l =~ /[d]/){ 
			final_print("info:\t".shift)
		}
		else{ 
			final_print(shift) }		
		}
	
}

sub debug {
	if($opt_l =~ /[d]/){
		final_print("$header");
		undef $header;
		final_print("debug:\t".shift);
	}
}

sub final_print{
my $logstring = shift;
                if($opt_O){
                open LOGFILE, ">>$opt_O";
                } else
                        {
                        open LOGFILE, ">>output.$host";
                        }
        print LOGFILE "$logstring";  
        print("$logstring") unless($noprint);
        close LOGFILE;
}       


sub telnetfprint {

if($telnet ne "0") {

log_print("Trying simple Telnet fingerprint\n","h");
log_print("--------------------------------\n","h");


if (!-e $fingerprintdb) {
        log_print("HUH db not found, it should be in $fingerprintdb\n","c");
        log_print("Skipping Telnet fingerprint\n","c");
        $nofp = 1;
        }


my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => 23, Proto => 'tcp', Timeout => '5') unless($nofp);
	undef($fingerprint); undef($description); undef($return); undef($submitter);

	if(!$sock) {
	log_print("No telnet\n","i") unless($nofp);
	}

        while($sock) {
	sleep(3);

	$cnt = sysread($sock, $buff, 14);
	if(!$cnt) {
	log_print("Hmmm, probably TCP wrappers\n","i") unless($nofp);
	last;
	}

	@rets = split(//, $buff);
	foreach $currentret (@rets){
	$fingerprint = $fingerprint . ord($currentret); }
	close($sock);
	log_print("Possible OS's\n\n","h");
	log_print("Fingerprint:\t\t\t$fingerprint\n","c") unless($nofp);
	last;
        }

if($fingerprint) {

        open FINGERPRINTDB, "<$fingerprintdb" || last("No fingerprint database, should be /usr/pkg/share/hackbot/fingerprint.db\n");

        while(<FINGERPRINTDB>) {
        ($description, $return, $submitter) = split(/\!/, $_);
        if("$fingerprint" eq "$return") {
        $hit = 1;
        log_print("Description:\t\t\t$description\n","c") unless($nofp);
        chomp($submitter);
        log_print("Fingerprint submission by:\t$submitter\n\n","c") unless($nofp);

        }

        }
        close FINGERPRINTDB;

        if(!$hit) {
        log_print("Fingerprint not found in database. If you know what it is please\nsubmit it to fingerprint\@obit.nl\n","c") unless($nofp);
	undef($nofp);
        }

     }
  }
}


sub ident
{
log_print("Identd\n","h");
log_print("------\n","h");
    my $sock = new IO::Socket::INET(
                                    PeerAddr => $target,
                                    PeerPort => '113',
                                    Proto    => 'tcp',
                                    Timeout  => '5'
                                    );

    if ($sock)
    {

        # hmmz we got signal, why not use the same socket for getting the user of ident 
        ($lp,undef) =
          unpack_sockaddr_in(getsockname($sock))
          ;    #get source port of local conection.
        print $sock "113,$lp\r\n";
        sysread($sock, $buff, 50);
        (undef, undef, undef, $undef) = split (/:/, $buff);
        log_print ("Port\tState\tService\tOwner\n","h");
        log_print ("----\t-----\t-------\t-----\n","h");
        log_print ("113\tOpen\tident\t$undef","c");
        close($sock);
        undef $lp;
        &full_identd_scan;
    } else
    {
        # skip rest of tests.. no identd no glory
        log_print("No Identd on $target, skipping full identd scan\n\n","i");
    }
};

sub full_identd_scan
{

    # full ident scan first setup target service. if it exists check ident for owner
    # hashed for easy maintanance.
    %ports_and_servicenames = (
                               21 => "ftp",
                               23 => "telnet",
                               25 => "mail",
                               80 => "www",
                               110 => "pop3"
                               ); #todo sorting order. so output will be incremental.
                                  # All your ports are belong to us!
    while (($identport, $service) = each(%ports_and_servicenames))
    # its geting hard to come up with usefull variable names these days
    {
        my $sock = new IO::Socket::INET(
                                        PeerAddr => $target,
                                        PeerPort => $identport,
                                        Proto    => 'tcp',
                                        Timeout  => '5'
                                        );

	if(!$sock and $identport eq "23") { $telnet = "0"; }
        if ($sock)
        {

            #And now for something completely similar.
            # setup sock2
	    my $sock2 =
              new IO::Socket::INET(
                                   PeerAddr => $target,
                                   PeerPort => '113',
                                   Proto    => 'tcp',
                                   Timeout  => '5'
                                   );
            ($lp,undef) = unpack_sockaddr_in(getsockname($sock));
            print $sock2 "$identport,$lp\r\n";
            sysread($sock2, $buff2, 50);
            if ($buff2 =~ /ERROR/)
            {
                log_print ("$identport\tError\t$service\tError\n","c");
            } else
            {   #undef defined!
                (undef, undef, undef, $undef) =
                  split (/:/, $buff2);   # third entry is systype, 99,9% its UNIX)
                log_print ("$identport\tOpen\t$service\t$undef","c"); 
                undef $buff;undef $buff2;undef $lp;undef $undef;
		close($sock);#undef undef undef... and undef.       
                close($sock2);#today is definetly my undef day. #todo code cleanup ;)
            }
        } else
        {
            log_print ("$identport\tClosed\t$service\t---\n","i");
        }
    }
log_print("\n","c");
}

sub whois {

	@RESERVEDA	= ('0','1','2','5','7','10','23','27','31','36','37','39','41','42','58','59','60',
			   '69','70','71','72','73','74','75','76','77','78','79','82','83','84',
			   '85','86','87','88','89','90','91','92','93','94','95','96','97','98',
			   '99','100','101','102','103','104','105','106','107','108','109','110',
			   '111','112','113','114','115','116','117','118','119','120','121','122',
			   '123','124','125','126','127','197','221','222','223','224','225','226',
			   '227','228','229','230','231','232','233','234','235','236','237','238','239',
			   '240','241','242','243','244','245','246','247','248','249','250','251','252',
			   '253','254','255');
	@RESERVEDB	= ('172.16','172.17','172.18','172.19','172.20','172.21','172.22','172.23',
			   '172.24','172.25','172.26','172.27','172.28','172.29','172.30','172.31',
			   '192.168','169.254');
	@RIPE		= ('62','80','81','193','194','195','212','213','217');
	@ARIN		= ('24','63','64','65','66','67','68','199','200','204','205','206','207',
			   '208','209','216');
	@APNIC		= ('61','202','203','210','211','218','219','220');

# determine range to be RESERVED, RIPE, ARIN or APNIC
($firstoct, $secoct) = split(/\./, $target);

if($ipmap = grep(/$firstoct!/, @RESERVEDA) or $ipmap = grep(/$firstoct\.$secoct/, @RESERVEDB))
	{ 
	log_print "reserved by IANA\n","i"; 
	$IANA = 1; 
	} elsif ($ipmap = grep(/$firstoct/, @RIPE)) {
	log_print("RIPE registrar\n","i");
	$RIPE = 1;
	} elsif ($ipmap = grep(/$firstoct/, @ARIN)) {
	log_print("ARIN registrar\n","i");
	$ARIN = 1;
	} elsif ($ipmap = grep(/$firstoct/, @APNIC)) {
	log_print("APNIC registrar\n","i");
	$APNIC = 1;
	} else {
	log_print("Don't know where to search whois data, could be anywhere, canceling whois checkup\n\n","c");
	$IANA = 1;
	}

if(!$IANA) {
	if($RIPE) 
	{
	&ripe;
	} elsif($APNIC) {
	&apnic;
	} elsif($ARIN) {
	&arin;
	}
	undef($IANA);
	}

}


sub ripe {
log_print("Checking Whois info \@RIPE\n","h");
log_print("-------------------------\n","h");
	my $sock = new IO::Socket::INET (PeerAddr => 'whois.ripe.net', PeerPort => 43, Proto => 'tcp', Timeout => '5');
	if($sock) {
		print $sock "$target\n";
		sleep(5);
		sysread($sock, $buff, 15000);
		log_print("$buff\n","d");
		close($sock);
	}

	($foobar, $inetnum)	= split(/inetnum\:\s/, $buff);	($inetnum, $foobar)	= split(/\n/, $inetnum);
	($foobar, $netname)	= split(/netname\:\s/, $buff);	($netname, $foobar)	= split(/\n/, $netname);
	($foobar, $descr)	= split(/descr\:\s/, $buff);	($descr, $foobar)	= split(/\n/, $descr);
	$descr =~ s/^\s{2}//;
	($foobar, $country)	= split(/country\:\s/, $buff);	($country, $foobar)	= split(/\n/, $country);
	($foobar, $adminc)	= split(/admin\-c\:\s/, $buff);	($adminc, $foobar)	= split(/\n/, $adminc);

if($adminc) {
	my $sock = new IO::Socket::INET (PeerAddr => 'whois.ripe.net', PeerPort => 43, Proto => 'tcp', Timeout => '5');
	if($sock) {
		print $sock "$adminc\n";
		sleep(5);
		sysread($sock, $buff, 1500);
		log_print("$buff\n","d");
		close($sock);
		}
}
		
	($foobar, $email)	= split(/e\-mail\:\s/, $buff);	($email, $foobar)	= split(/\n/, $email);
	$email =~ s/^\s//;

	log_print("Range:\t\t$inetnum\n","c") unless !$inetnum;
	log_print("Netname:\t$netname\n","c") unless !$netname;
	log_print("Description:\t$descr\n","c") unless !$descr;
	log_print("Country:\t$country\n","c") unless !$country;
	log_print("Admin-C:\t$adminc\n","c") unless !$adminc;
	log_print("Email:\t\t$email\n\n","c") unless !$email;

if (!$inetnum && !$netname && !$descr && !$country && !$adminc && !$email) {
		log_print("RIPE could not be reached or no information was returned\n\n","c");
	}

	undef($RIPE); undef($inetnum); undef($netname); undef($descr); 
	undef($country); undef($adminc); undef($email); undef($foobar);
}

sub arin {
	log_print("Checking Whois info \@ARIN\n","h");
	log_print("--------------------------\n","h");

	my $sock = new IO::Socket::INET (PeerAddr => 'whois.arin.net', PeerPort => 43, Proto => 'tcp', Timeout => '5');
	if($sock) {
		print $sock "$target\n"; 
		sleep(3);
		sysread($sock, $buff, 5000);
		log_print("$buff\n","d");
	($temp, $netrange) = split(/NetRange\:(.*)/, $buff);
	log_print("Netrange: $netrange\n","c") unless !$netrange;
	($temp, $netname) = split(/NetName\:(.*)/, $buff);
	log_print("Netname: $netname\n","c") unless !$netname;
	($temp, $comment) = split(/Comment\:(.*)/, $buff);
	log_print("Comment: $comment\n","c") unless !$comment;
	($temp, $handle) = split(/TechHandle\:(.*)/, $buff);
	log_print("TechHandle: $handle\n","c") unless !$handle; 
	($temp, $email) = split(/TechEmail\:(.*)/, $buff);
	log_print("TechEmail: $email\n","c") unless !$email;
	}
}

sub apnic {

log_print("Checking Whois info \@APNIC\n","h");
log_print("--------------------------\n","h");
	my $sock = new IO::Socket::INET (PeerAddr => 'whois.apnic.net', PeerPort => 43, Proto => 'tcp', Timeout => '5');
	if($sock) {
		print $sock "$target\n";
		sleep(5);
		sysread($sock, $buff, 15000);
		log_print("$buff\n","d");
		close($sock);
	}


	($foobar, $inetnum)	= split(/inetnum\:\s/, $buff);	($inetnum, $foobar)	= split(/\n/, $inetnum);
	($foobar, $netname)	= split(/netname\:\s/, $buff);	($netname, $foobar)	= split(/\n/, $netname);
	($foobar, $descr)	= split(/descr\:\s/, $buff);	($descr, $foobar)	= split(/\n/, $descr);
	$descr =~ s/^\s{2}//;
	($foobar, $country)	= split(/country\:\s/, $buff);	($country, $foobar)	= split(/\n/, $country);
	($foobar, $adminc)	= split(/admin\-c\:\s/, $buff);	($adminc, $foobar)	= split(/\n/, $adminc);

if($adminc) {
	my $sock = new IO::Socket::INET (PeerAddr => 'whois.apnic.net', PeerPort => 43, Proto => 'tcp', Timeout => '5');
	if($sock) {
		print $sock "$adminc\n";
		sleep(5);
		sysread($sock, $buff, 1500);
		log_print("$buff\n","d");
		close($sock);
		}
}

	($foobar, $email)	= split(/e\-mail\:\s/, $buff);	($email, $foobar)	= split(/\n/, $email);
	$email =~ s/^\s//;

	log_print("Range:\t\t$inetnum\n","c");
	log_print("Netname:\t$netname\n","c");
	log_print("Description:\t$descr\n","c");
	log_print("Country:\t$country\n","c");
	log_print("Admin-C:\t$adminc\n","c");
	log_print("Email:\t\t$email\n\n","c") unless(!$email);

	undef($APNIC); undef($inetnum); undef($netname); undef($descr);
	undef($country); undef($adminc); undef($email); undef($foobar);
}

sub modphpssl($) {
	my $versionstring = shift;

# bad apache check
	$badapachenotification = "Evil buggy Apache found!\nSeveral vulnerabilities, check http://www.apache.org\n\n";
	
        if($versionstring =~ /Apache\/1.3/) {
        ($temp1, $temp2) = split(/Apache\/1\.3\./, $versionstring);
	($temp2, $temp1) = split(/\s/, $temp2);
        if($temp2 lt "27") {
        log_print("$badapachenotification","c");
        undef($temp1); undef($temp2);
        }
        }

        if($versionstring =~ /Apache\/1.2/) {
        log_print("$badapachenotification","c");
        }

        if($versionstring =~ /Apache\/2.0./) {
        ($temp1, $temp2) = split(/Apache\/2\.0\./, $versionstring);
	($temp2, $temp1) = split(/\s/, $temp2);
        if($temp2 lt "43") {
        log_print("$badapachenotification","c");
        undef($temp1); undef($temp2);
        }
        }
# end bad apache check

		if($versionstring =~ /mod_ssl/) {
		($temp1, $temp2) = split(/mod_ssl\//, $versionstring);
		($modsslversion, $temp1) = split(/\s/, $temp2);
				log_print("mod_ssl $modsslversion found\n","c");
    		}
	if($versionstring =~ /PHP/) {
		($temp2, $temp2) = split(/PHP\//, $versionstring);
		($phpversion, $temp1) = split(/\s/, $temp2);
		log_print("PHP $phpversion found\n","c");
	}	
	log_print("\n","c");
	undef($versionstring); undef($temp1); undef($temp2); undef($modsslversion); undef($phpversion);
}


sub isapi($) {

my $target = shift;
my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');

if($sock) {
	print $sock "GET /null.htr HTTP/1.0\r\n\r\n";
        sleep(3);
        sysread($sock, $buff, 1000);
	if($buff =~ /Error: The requested file could not be found./) {
	log_print("* HTR ISAPI filter mapped\n","c");
	log_print("* http://online.securityfocus.com/bid/4474/info/\n\n","c");
	close($sock);
	}
	}

my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');

if($sock) {
        print $sock "GET /null.printer HTTP/1.0\r\n\r\n";
        sleep(3);
        sysread($sock, $buff, 1000);
        if($buff =~ /Error in web printer install/) {
        log_print("* Printer ISAPI filter mapped\n","c");
        log_print("* http://online.securityfocus.com/bid/2674/info/\n\n","c");
        close($sock);
        }
        }

}

sub propfind($) {
my $target = shift;
my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => $port, Proto => 'tcp', Timeout => '5');

if($sock) {
if($host_resolves == 1) {
print $sock "PROPFIND http://$host/ HTTP/1.1
Host:
Content-Length: 0\r\n\r\n\r\n\r\n";
} else {
print $sock "PROPFIND / HTTP/1.1
Host:
Content-Length: 0\r\n\r\n\r\n\r\n";
}
        sleep(3);
        sysread($sock, $buff, 1000);
                if($buff =~ /207 Multi-Status/) {
                log_print("* PROPFIND Information\n","c");
                log_print("* http://www.nextgenss.com/advisories/iisip.txt\n","c");
                ($temp, $return) = split(/http\:\/\//, $buff);
                ($return, $temp) = split(/\//, $return);
                ($temp, $datereturn) = split(/rfc1123\"\>/, $buff);
                ($datereturn, $temp) = split(/\<\/a/, $datereturn);
                log_print("* Server gave host/ip address: $return\n","c");
                log_print("* Server gave back date: $datereturn\n\n","c");
                undef($temp); undef($return); undef($datereturn);
                }
        }
	close($sock);
}

sub endbanner {
	log_print("--->\n","c");
	log_print("- All scans done. Hackbot $version -\n","c");
	log_print("---> Exiting.\n","c");
}

sub spamcheck {
	if (&check_ip($target)) {
		($a, $b, $c, $d) = split(/\./, $target);
		$spamcop = ".bl.spamcop.net";
		$spamhost = $d . "." . $c . "." . $b . "."  . $a . $spamcop unless $a == "10";
		if($spamhost) {
		my $spammer = gethost($spamhost);
		if($spammer) {
		log_print("This is a known spammer\!\!, thank you spamcop \(www.spamcop.net\)\n\n","c");
		}
		if(!$spammer) {
		log_print("It is not a known spammer, thank you spamcop \(www.spamcop.net\)\n\n","i"); 
		}
		}
		else { log_print("Not doing spamcop check on a private address\n","d"); }
	}
	undef($spammer); undef($spamhost);
}

sub proxytest {

        $proxytest = $_[0];
        $target    = $_[1];

	my $sock = new IO::Socket::INET (PeerAddr => $proxytest, PeerPort => $proxyport, Proto => 'tcp', Timeout => '10');
	if($sock) {
	log_print("Proxy responds.. now lets test if it can be used.\n\n","c");   
	$responds = 1;
	} else { 
		log_print("Proxy connect failed, scanning without proxy\n\n","c");
		undef($proxytest); undef($proxy); undef($proxyport);
	}
	if($responds) {
		print $sock "GET http://$target/_bla_\r\n\r\n";
		sleep(5);
		sysread($sock, $buff, 1000);

		if($buff =~ /404/) {
			log_print("Proxying is allowed\n\n","c");
		} else {
		log_print("Proxying is not allowed, will continue scan without using a proxy\n\n","c");
		undef($proxy); undef($proxyport); undef($proxytest); 
		}
	}
}

sub xcheck {
	log_print("\nChecking if we are allowed to connect to X\n","h");
	log_print("------------------------------------------\n","h");
	my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => '6000', Proto => 'tcp', Timeout => '5');
		if($sock) {
		print $sock "\x6c\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00";
		sleep(3);
		sysread($sock, $buff, 10000);
			if($buff !~ /protocol/i && $buff !~ /autho/i) {
				log_print("Allowed to connect to X!\n\n","c");
			} 
		else
		 {
			log_print("Has X but connection is not allowed\n\n","c");
 		} 

	}

	if(!$sock) {
	log_print("No X\n\n","i");
	}

}

sub googlescan {

        my $google_ip = $_[0];
	my $target = $_[1];
	my $gdefined = $_[2];

        if (!-e $googledb) {
                $nogoogle = 1;
		log_print("Can't find google.db\n","c");
                }

if(!$gdefined) {

	log_print("\n","h");
	log_print("Google search\n","h") unless($nogoogle);
	log_print("-------------\n","h") unless($nogoogle);

	$stringcount = "0";

        open STRINGS, "<$googledb" unless($nogoogle);

	foreach(<STRINGS>) {	
	
	if($_ !~  /[a-z]/i) {
		log_print("$googledb corrupted! skipping googlesearch\n\n","c");
		$corrupted = "1";
		last;	
	}


		$current = $_;
		chomp($current);


				my $sock = new IO::Socket::INET (PeerAddr => $google_ip, PeerPort => '80', Proto => 'tcp', Timeout => '5');

   		if($sock) {


		print $sock "GET http://www.google.com/search?as_q=inurl%3A$current&num=100&hl=en&ie=ISO-8859-1&btnG=Google+Search&as_epq=&as_oq=&as_eq=&lr=&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=$host&safe=images HTTP/1.0\r\n\r\n";
		sleep(5);
		@received  = <$sock>;

		foreach(@received) {
			$string = $_;
			($temp, $string) = split(/a href=/, $string);
                	if($string =~ /:\/\/$host/) {
				($string, $temp) = split(/>/, $string);
                                log_print("$string\n","c") unless($string !~ /$current/);
                        }
		}
close $sock;
	}
	close STRINGS;
	undef($current); undef($string); undef($sock); undef(@recieved);
 }


# google index search

	my $sock = new IO::Socket::INET (PeerAddr => $google_ip, PeerPort => '80', Proto => 'tcp', Timeout => '5');
	if($sock) {
		print $sock "GET http://www.google.com/search?hl=en&lr=&ie=ISO-8859-1&q=%22Index+of+%2F%22+%22last+modified%22+site%3A$host HTTP/1.0\r\n\r\n";
		sleep(5);	
		@index  = <$sock>;
			foreach(@index) { 
			$index = $_;
			($temp, $index) = split(/a href=/, $index);
			if($index =~ /:\/\/$host/) {
				($index, $temp) = split(/>/, $index);
				log_print("$index - indexable directory\n","c"); 
			}
		}

	log_print("\n","h");
	undef($sock); undef($index); undef($temp);
	}

}


if($gdefined) {

	log_print("Google search for $gdefined \n","h") unless($nogoogle);
	log_print("---------------------------------\n","h") unless($nogoogle);


	my $sock = new IO::Socket::INET (PeerAddr => $google_ip, PeerPort => '80', Proto => 'tcp', Timeout => '5');
	print $sock "GET http://www.google.com/search?as_q=inurl%3A$gdefined&num=100&hl=en&ie=ISO-8859-1&btnG=Google+Search&as_epq=&as_oq=&as_eq=&lr=&as_ft=i&as_filetype=&as_qdr=all&as_occt=any&as_dt=i&as_sitesearch=$host&safe=images HTTP/1.0\r\n\r\n";
	sleep(5);
	@received  = <$sock>;	
		foreach(@received) {
			$string = $_;
                        ($temp, $string) = split(/a href=/, $string);
                        if($string =~ /:\/\/$host/) {
                                ($string, $temp) = split(/>/, $string);
                                log_print("$string\n","c") unless($string !~ /$gdefined/);
		}
	}
	}
	log_print("\n\n","h");
}


sub pop3 {

log_print("\nChecking for POP3 server\n","h");
log_print("------------------------\n","h");
        my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => 110, Proto => 'tcp', Timeout => '5');
        if (!$sock) {
        log_print("No POP3 server\n\n","i");
        }
	sleep(2);
	        while($sock) {
	                $cnt = sysread($sock, $buff, 10000);
        	        if(!$cnt) {
        	        log_print("huh, fscking TCP wrappers, I died\n\n","i");
               		last;	
                }
        if($cnt) {
	
	log_print("$buff\n","c");
	sleep(1);
	close($sock);
	undef($sock); undef($buff);
	} }
}

sub evilsendmail {
	$buggysendmailmsg = "* Possibly buggy sendmail\n\n\n";

	my $sock = new IO::Socket::INET (PeerAddr => $target, PeerPort => 25, Proto => 'tcp', Timeout => '5');
	if($sock) {
		sleep(4);
		sysread($sock, $buff, 1500);
		if($buff =~ /Sendmail /) {
			($temp, $buggyversion) 	= split(/Sendmail /,$buff);

			$buggyversion =~ /(\d+?)\.(\d+?)\.(\d+?)/;

			if (($1 && $2 && $3) &&
			   (($1 < 8) ||
			   (($1 == 8) && ($2 < 12)) ||
			   (($1 == 8) && ($2 == 12) && ($3 < 9)))) {
				print "$1 - $2 - $3\n";
				log_print($buggysendmailmsg,"c");

				undef($buggysendmailmsg); undef($buff); undef($temp); undef($buggyversion);
				close($sock);
				undef($sock);
			}
		}
	}
}
