Date: Mon, 12 Apr 1999 12:43:55 -0500 From: HD Moore To: nmap-hackers@insecure.org Subject: nwrap -- nmap stealth wrapper Parts/Attachments: 1 Shown 34 lines Text 2 Shown 171 lines Text ---------------------------------------- I started working on some scripts to 'wrap' nmap and allow for stealthier scanning routines. The goals for this script include: Creating a host/port table and then randomizing it. Scanning each host/port combination in a random sequence. Easy creation of decoy addresses. Parallel scanning with child process management. Consolidation of log files into a nlog-style db or MySQL. There are still a number of issues I am working on, if you have any suggestions/complaints email me: Delay between scans should be a random number within a user-defined range. Decoy addresses should remain the same during each scan to eliminate chance of detection by coordinating traffic logs from each scanned host and finding the real address in each. Log file consolidation (maybe use -m - and read it all from an open pipe?) Better option set for the nwrap script. Attached is the protoype perl script, I wanted to get some feedback about what stealth options/techniques people wanted to see implemented in a nmap wrapper script. -HD aka spinux http://nlog.ings.com http://www.trinux.org [ Part 2: "Attached Text" ] #!/usr/bin/perl use Getopt::Long; sub exitclean { my ($msg) = @_; print "$msg\n"; exit 2; } $SIG{INT}=\&sig_catch; &GetOptions("debug", \$OPTdebug, "p:s", \$OPTports, "i:s", \$OPTinput); open (INPUT,"<".$OPTinput) || exitclean("Could not open host input file: $!"); @targets = (); close(INPUT) || debugprint("close() failed on INPUT: $!"); # create a host/port list and shuffle it @targets = shuffle(\@targets); @ports = parse_ports($OPTports); @ports = shuffle(\@ports); foreach $host (@targets) { chomp($host); @ports = shuffle(\@ports); foreach $port (@ports) { push @output, "$host $port"; } } @output = shuffle(\@output); # now do something with that host/port list foreach $out (@output) { ($nmaptarget,$nmapport) = split(/\s+/,$out); $logfile = "$nmaptarget.$nmapport.log"; print "Scanning port $nmapport on $nmaptarget...\n"; system ("nmap -sS -m $logfile -P0 $nmaptarget -p$nmapport -D" . rdecoys(getpppip())) || print "Could not launch nmap: $!\n"; } exit(0); # # Functions # sub getpppip { my $DATA=`ifconfig | grep P-t-P | awk \'\{ print \$2 \}\'`; my $crap; my $ip; chomp($DATA); ($crap,$ip) = split(/\:/,$DATA); return $ip; } sub rdecoys { my ($ip) = @_; my @octets = split(/\./,$ip); my $count; my @decoys = (); my $decoy; my $output; for ($count = 0; $count < 6 ; $count++) { $decoys[$count] = int(rand()*255); } foreach $decoy (@decoys) { $output .= "$octets[0].$octets[1].$octets[2].$decoy,"; } $output .="ME"; return $output; } sub debugprint { ($msg) = @_; print "[debug] $msg\n" unless (!$OPTdebug); } sub sig_catch { my $signame = shift; print "\nRecieved SIG$signame, exiting...\n"; exit 2; } ############################################################################### # # Function: shuffle # Purpose: Randomize an array # To-Do: Done # Date: 04/09/99 # # Comments: This routine was pretty much ripped from 'Perl Cookbook' pg 121-122 # ############################################################################### sub shuffle { my $array = shift; my $i = scalar(@$array); my $j; foreach $item (@$array ) { --$i; $j = int rand ($i+1); next if $i == $j; @$array [$i,$j] = @$array[$j,$i]; } return @$array; } ############################################################################### # # Function: parse_ports # Purpose: Take in an nmap style port list and return an array # To-Do: Add a check to make sure all the ports added are numeric # Date: 04/09/99 # ############################################################################### sub parse_ports { my ($portstring) = @_; my $splitter = ","; my @portlist = (); my @portsplit = (); my $port; @portsplit = split($splitter,$portstring); foreach $port (@portsplit) { @range = split(/\-/,$port); if (scalar(@range) > 1) { if ($range[0] > $range[1] || $range[0] < 0 || $range[0] > 65535 || $range[1] < 0 || $range[1] > 65535) { print "Your range of $range[0] -> $range[1] is invalid!\n"; exit(1); } for ($i = $range[0]; $i < $range[1] + 1; $i++) { if ($i > 0 && $i < 65536) { push @portlist, $i; } } } else { push @portlist, $port; } } return @portlist; }