#!/usr/bin/perl
#
# Egatobas Advanced Research Labs <copyright 2000> presents
# Nwhack.pl v1.0.0 by Xram_LraK <aka Matt W.>
#
# Nwhack.pl is my first attempt at placing nmap output into 
# a postgres database.  It works pretty well the only real problem
# is for some reason the -oM option creates odd output for some
# situation. 
#
# Possible bugs: Some random syntax error, right now i'm minus a test
#                environment.  Sucks moving cross country.
# 		 Bugs should be reported to kmx@egatobas.org
#
# Usage: nwhack.pl <-oM created file from nmap> <scan_id>
# scan_id is for usage over time, lets you compare different scans to
# each other.
#
# Requires, Postgres.pm Postgres-1.4 get it from www.cpan.org 
#
# Greets: My dealer, Farm9, Travis, Anne_T, #monkey, All the OpenBSD dev guys,
#         rfp, my homies in CA, my homies in Maryland 
#
# Quote of the Day "Where did the CEO go? www.fuckedcompany.com for sure now"
#
# Motto: "Will script for Food"
#

use Postgres;
$DBName = "nmapdb"; # Name of DATABASE To Connect To

$File = $ARGV[0];
$Scan_id = $ARGV[1];

if ( @ARGV < 2 ) {
	print "Usage: nmappg.pl <FileToParse> <Scan_id>\n";
}

parseFile("$ARGV[0]");


sub parseFile($file) {
   $File = shift(@_);

   open(FH, $File);
   
   while(<FH>) {
      $TheLine = $_;
      
      if($TheLine !~ '#') {
      
         # 0 = Host: IP (DNS)
         # 1 = Ports 22/open/tcp//ssh///, 5432/open/tcp//postgres///
         #  or Status: bleh
         # 2 = Ignored State: or OS:
         # 3 = Seq Index or OS
         # 4 = OS
         (@Line)=split(/\t/, $TheLine);
            if($Line[2] =~ 'OS:') {
               $OS = $Line[2];
               print "$OS\n";
            }
            if($Line[3] =~ 'OS:') {
               $OS = $Line[3];
               print "$OS\n";
            }
            if($Line[4] =~ 'OS:') {
               $OS = $Line[4];
               print "$OS\n";
            }

         # 0 = Host:
         # 1 = IPAddress:
         # 2 = DNS If available:
         (@HostInfo)=split(/ /, $Line[0]);
         (@PortInfo)=split(",", $Line[1]);
         
         if($PortInfo[0] =~ /Port/) {
            $NumPort = $#PortInfo + 1;

            ($Crap, @PortsArray) = split(" ", $PortInfo[0]);
            
            for ($i = 1; $i < $NumPort; $i++ ) {
               push(@PortsArray, $PortInfo[$i]);   
            }
            
            $NumPort = $#PortsArray + 1;
            
  #          print "$HostInfo[1] ";
            
            for ($i = 0; $i < $NumPort; $i++) {
               ($Port, $Crap)=split("/", $PortsArray[$i]);
               if($Crap =~ /open/) {
                  push(@PArray, $Port);
               }
            }
  #          print "@PArray\n";
		
	    $len = $#PArray + 1;	
       dbinsert(@PArray);	

            undef(@PArray);
         }
      }
   }
}

sub dbinsert(@PORTARRAY) {
	@Array = @_;
	
	$conn = db_connect($DBName) or die "No Connect";

	print "$HostInfo[1]\n";
	print "@Array\n";
#  Add a querry to select the newested audit_id and add 1 to it then set the audit id

	$Len = $#Array + 1;
	for ($i = 0; $i < $Len; $i++) {
		$query = $conn->execute("INSERT INTO Audit (scan_id, ip_address, port, os_name) VALUES ($Scan_id, '$HostInfo[1]', $Array[$i], '$OS');");
	}
	$conn->reset();
}
