#!/usr/bin/perl
#----------------------------------------------------------------------------
#
# Written by MadHat (madhat@unspecific.com)
#
# Copyright (c) 2001-2002, MadHat (madhat@unspecific.com)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#   * Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in
#     the documentation and/or other materials provided with the distribution.
#   * Neither the name of MadHat Productions nor the names of its
#     contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#----------------------------------------------------------------------------
$VERSION = '1.0';

use Getopt::Std;
use Socket qw(:DEFAULT :crlf);
$/ = CRLF;


select (STDERR); $|++; 
select (STDOUT); $|++;

my $Marconi=0; 
eval 'use Marconi';
if ($@) { 
  $Marconi=0;
  if (-e 'marconi.pm') {
    eval 'require "./marconi.pm"';
    if (!$@) {
      $Marconi++;
    }
  }
} else { 
  $Marconi++; 
}
if (!$Marconi) {
    print "ERROR:\tMarconi not found/installed.\n";
    exit;
}

getopts("i:l:d:v");

  my @nets;
  if ( defined($opt_i) ){
    open(FIN, "$opt_i" ) || die "cannot open $opt_i\n";
    @nets=<FIN>;
    close(FIN);
  } elsif ( defined($opt_l) ) {
    if ($opt_l eq '-') {
      $opt_l = join(',', <STDIN>);
    }
    @nets = split(',', $opt_l);
  }
  foreach $net (@nets){
    chomp $net;
    next if ($net =~ /^#/ or $net =~ /^$/);
    print "scanning $net\n" if (defined($opt_v));
    @iplist = Marconi::CalculateIPRange($net);
    push(@totallist, @iplist);
  }
  if (!@totallist) { die "Error in the IP list. Check syntax.
    IP list entered: $iplist
    Allowed Syntax:
    a.b.c.d/n       - 10.0.0.1/25
    a.b.c.*         - 10.0.0.* (0-255) same as /24
    a.b.c.d/w.x.y.z - 10.0.0.0/255.255.224.0 (standard format)
    a.b.c.d/w.x.y.z - 10.0.0.0/0.0.16.255    (cisco format)
    a.b.c.d-z       - 10.1.2.0-12
    a.b.c-x.*       - 10.0.0-3.*  (last octet has to be * or 0)
    a.b.c-x.d       - 10.0.0-3.0
    hostname        - www.unspecific.com
  \n"; }


print "Scanning $#totallist IPs\n" if ($opt_d);

for ( $i = 0; $i<=$#totallist; $i++ ){
  my $ipaddr = $totallist[$i];
  chomp $ipaddr;
  print "SAMBA: scanning $ipaddr\n" if ($opt_d);
  my $ip = $ipaddr;
  my $open = $domain = $os = $workgroup = $server = $shares = '';
  my $login = $share_listing = '';
  my $dump = '';
  my ($machine, $mac) = Marconi::NBTScan($ip, 1, $opt_d);
  if ($machine) {
    my $output = sprintf("%-15s %-16s %17s\n", $ip, $machine, $mac);
    print $output if ($opt_v);
    my $dump .= `smbclient -N -L $ip`;
    @output = (split "\n", $dump);
    LINE: for my $line (@output) {
      print "SAMBA: $line\n" if ($opt_d > 1);
      chomp $line;
      if ($line eq 'Anonymous login successful' and !$login) { 
        print "  Anonymous login successful\n" if ($opt_v);
        $login++;
      }
      if ($line =~ /^Domain=\[(\w+)\]/ and !$domain) {
        $domain = $1; $os = $2;
      } elsif ($line =~ /^\s+Sharename/) {
        print "SAMBA: Sharename found, looking for shares\n" if ($opt_d > 1);
        $shares++;
      } elsif ($line =~ /^\s+Server/) {
        print "SAMBA: Server found, looking for servers\n" if ($opt_d > 1);
        $shares = 0;
        $server++;
      } elsif ($line =~ /^\s+Workgroup/) {
        print "SAMBA: Workgroup found, looking for workgroups\n" if ($opt_d > 1);
        $server = 0;
        $workgroup++;
      } elsif ($shares and $line !~ /^$/) {
        my $open = '';
        print "SAMBA: Looking for shares in\n-- $line\n" if ($opt_d > 1);
        next LINE if ($line eq 'Error returning browse list: NT_STATUS_ACCESS_DENIED');
        my ($share, $type, $comment)  = split (' ', $line);
        if ($share =~ /^\w/ and !$share_listing) {
          print "  $ip offered share listing\n" if ($opt_v);
          $share_listing++;
        }
        next if ($share eq '---------' or
                 # $share eq 'ADMIN$' or
                 $share eq 'IPC$'
                 # $share eq 'C$' or
                 # $share eq 'D$' or
                 );
        my @ls =  split ("\n", `smbclient //$ip/$share -N -c ls`);
        LS: for my $entry (@ls) {
          chomp $entry;
          next LS if (
                       $entry =~ /^added interface ip/ or 
                       $entry =~ /^Domain=/ or 
                       $entry =~ /^tree connect failed/
                     );
          print "SAMBA: Looking for info in\n-- $entry\n" if ($opt_d > 1);
          if ($entry =~ /^\s+[\w\s\.]+\s+[DSAH]+\s+\d+/) {
            print "SAMBA: Looks like a directory listing \n" if ($opt_d > 1);
 
            $open++;
            # last LS;
          }
        }
        if ($open) {
          print "  @$ip //$machine/$share open share found on the $domain Domain\n";
        }
      }
    }
    my $dump .= `smbclient -U guest\%guest -N -L $ip`;
    @output = (split "\n", $dump);
    LINE: for my $line (@output) {
      print "SAMBA: $line\n" if ($opt_d > 1);
      chomp $line;
      if ($line eq 'Anonymous login successful' and !$login) { 
        print "  Anonymous login successful\n" if ($opt_v);
        $login++;
      }
      if ($line =~ /^Domain=\[(\w+)\]/ and !$domain) {
        $domain = $1; $os = $2;
      } elsif ($line =~ /^\s+Sharename/) {
        print "SAMBA: Sharename found, looking for shares\n" if ($opt_d > 1);
        $shares++;
      } elsif ($line =~ /^\s+Server/) {
        print "SAMBA: Server found, looking for servers\n" if ($opt_d > 1);
        $shares = 0;
        $server++;
      } elsif ($line =~ /^\s+Workgroup/) {
        print "SAMBA: Workgroup found, looking for workgroups\n" if ($opt_d > 1);
        $server = 0;
        $workgroup++;
      } elsif ($shares and $line !~ /^$/) {
        my $open = '';
        print "SAMBA: Looking for shares in\n-- $line\n" if ($opt_d > 1);
        next LINE if ($line eq 'Error returning browse list: NT_STATUS_ACCESS_DENIED');
        my ($share, $type, $comment)  = split (' ', $line);
        if ($share =~ /^\w/ and !$share_listing) {
          print "  $ip offered share listing vai 'Guest' login\n" if ($opt_v);
          $share_listing++;
        }
        next if ($share eq '---------' or
                 # $share eq 'ADMIN$' or
                 $share eq 'IPC$'
                 # $share eq 'C$' or
                 # $share eq 'D$' or
                 );
        my @ls =  split ("\n", `smbclient //$ip/$share -U guest\%guest -N -c ls`);
        LS: for my $entry (@ls) {
          chomp $entry;
          next LS if (
                       $entry =~ /^added interface ip/ or 
                       $entry =~ /^Domain=/ or 
                       $entry =~ /^tree connect failed/
                     );
          print "SAMBA: Looking for info in\n-- $entry\n" if ($opt_d > 1);
          if ($entry =~ /^\s+[\w\s\.]+\s+[DSAH]+\s+\d+/) {
            print "SAMBA: Looks like a directory listing \n" if ($opt_d > 1);
 
            $open++;
            # last LS;
          }
        }
        if ($open) {
          print "  @$ip //$machine/$share open share for 'Guest' on the $domain Domain\n";
        }
      }
    }
  }
}

print "\n";
1






