PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/examples/scanhost.pl

https://github.com/gitpan/Nmap-Parser-XML
Perl | 336 lines | 123 code | 40 blank | 173 comment | 31 complexity | 872e2af712e77caa6cdf9267d50934ee MD5 | raw file
Possible License(s): GPL-2.0
  1. #!/usr/bin/perl
  2. #Anthony G. Persaud
  3. #port_info.pl
  4. #Description:
  5. # It takes in a nmap xml file and outputs onto STDOUT and a file the
  6. # all the ports that were scanned and found by nmap, their different
  7. # states and services -- all in a comma delimited output
  8. #
  9. #
  10. #This program is free software; you can redistribute it and/or modify it under
  11. #the terms of the GNU General Public License as published by the Free Software
  12. #Foundation; either version 2 of the License, or (at your option) any later
  13. #version.
  14. #
  15. #This program is distributed in the hope that it will be useful, but WITHOUT ANY
  16. #WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  17. #PARTICULAR PURPOSE. See the GNU General Public License for more details.
  18. #
  19. # Changelog:
  20. # APS 01/29/2004: Changed run_nmap_scan to use parsescan().
  21. # $nmap_exe is set to default 'nmap' if find_exe returns empty
  22. # APS 02/03/2004: Added ability to read IPs from a file
  23. #
  24. #
  25. #
  26. use strict;
  27. use Nmap::Parser::XML;
  28. use Getopt::Long;
  29. use File::Spec;
  30. use Pod::Usage;
  31. use vars qw(%G);
  32. use constant CMD1 => '-sV -O --randomize_hosts';
  33. use constant CMD2 => '-sV -O -F --randomize_hosts';
  34. use constant TEST_FILE => 'example.xml';
  35. Getopt::Long::Configure('bundling');
  36. my $p = new Nmap::Parser::XML;
  37. print "\nscan_host.pl - ( http://npx.sourceforge.net )\n",
  38. ('-'x50),"\n\n";
  39. GetOptions(
  40. 'help|h|?' => \$G{helpme},
  41. 'F' => \$G{fast},
  42. 'v+' => \$G{verbose},
  43. 'i=s' => \$G{usefile},
  44. 'L=s' => \$G{ipfile}
  45. ) or (pod2usage(-exitstatus => 0, -verbose => 2));
  46. if($G{helpme} || (!$G{usefile} && scalar @ARGV == 0 && !$G{ipfile}))
  47. {pod2usage(-exitstatus => 0, -verbose => 2)}
  48. #Setup parser callback
  49. $p->register_host_callback(\&host_handler);
  50. #If using input file, then don't run nmap and use file
  51. if($G{usefile} eq ''){$p = run_nmap_scan(@ARGV);
  52. }
  53. else {
  54. #use the input file
  55. print 'Using InputFile: '.$G{usefile}."\n" if($G{verbose} > 0);
  56. if(not -e $G{usefile})
  57. {print STDERR "ERROR: File $G{usefile} does not exists!\n"; exit;}
  58. $p->parsefile($G{usefile});
  59. }
  60. #This host handler will get call for every host that is scanned (or found in the
  61. #xml file)
  62. sub host_handler {
  63. my $host = shift;
  64. print ' > '.$host->addr."\n";
  65. print "\t[+] Status: (".uc($host->status).")\n";
  66. if($host->status ne 'up'){goto END;}
  67. tab_print("Hostname(s)",$host->hostnames());
  68. tab_print("Operation System(s)",$host->os_matches());
  69. port_service_print($host);
  70. END:
  71. print "\n\n";
  72. }
  73. #Quick function to print witht tabs
  74. sub tab_print {print "\t[+] $_[0] :\n";shift;for my $a (@_){print "\t\t$a\n";}}
  75. sub port_service_print {
  76. my $host = shift;
  77. print "\t[+] TCP Ports :\n";
  78. for my $port ($host->tcp_ports()){
  79. printf("\t\t%-6s %-20s %s\n",
  80. $port,
  81. $host->tcp_service_name($port),
  82. $host->tcp_service_product($port).' '.
  83. $host->tcp_service_version($port));
  84. }
  85. print "\t[+] UDP Ports :\n" if($host->udp_ports_count);
  86. for my $port ($host->udp_ports()){
  87. printf("\t\t%-6s %-20s %s\n",
  88. $port,
  89. $host->udp_service_name($port),
  90. $host->udp_service_product($port).' '.
  91. $host->udp_service_version($port));
  92. }
  93. }
  94. ################################################################################
  95. ## Utility Functions ##
  96. ################################################################################
  97. #quick function to find an executable in a given path
  98. sub find_exe {
  99. my $exe_to_find = shift;
  100. $exe_to_find =~ s/\.exe//;
  101. local($_);
  102. local(*DIR);
  103. for my $dir (File::Spec->path()) {
  104. opendir(DIR,$dir) || next;
  105. my @files = (readdir(DIR));
  106. closedir(DIR);
  107. my $path;
  108. for my $file (@files) {
  109. $file =~ s/\.exe$//;
  110. next unless($file eq $exe_to_find);
  111. $path = File::Spec->catfile($dir,$file);
  112. next unless -r $path && (-x _ || -l _);
  113. return $path;
  114. last DIR;
  115. }
  116. }
  117. }
  118. sub run_nmap_scan {
  119. my @ips = @_;
  120. my ($NMAP,$cmd);
  121. if($G{ipfile} && -e $G{ipfile})
  122. {push @ips ,read_ips_from_file($G{ipfile});
  123. if($G{verbose} > 0){
  124. print STDERR "\nIP file contains:\n";
  125. for(@ips){print STDERR "\t$_\n";}
  126. print "\n";}
  127. }
  128. elsif($G{ipfile} && !-e $G{ipfile})
  129. {warn "WARNING: IP file $G{ipfile} does not exist!\n";}
  130. if($G{fast}){
  131. print "FastScan enabled\n" if($G{verbose} > 0 && $G{fast});
  132. $cmd = join ' ', (CMD2, @ips);
  133. } else {
  134. $cmd = join ' ', (CMD1, @ips);
  135. }
  136. my $nmap_exe = find_exe('nmap');
  137. if($nmap_exe eq '')
  138. {warn "ERROR: nmap executable not found in \$PATH\n";$nmap_exe = 'nmap';}
  139. print 'Running: '.$nmap_exe.' '.$cmd."\n" if($G{verbose} > 0);
  140. $p->parsescan($nmap_exe,$cmd);
  141. return $p;
  142. }
  143. sub read_ips_from_file {
  144. my $filename = shift;
  145. my @ips;
  146. open FILE, "$filename" || die "ERROR: Could not open $filename! \nERROR: $!";
  147. for(<FILE>){
  148. chomp; # no newline
  149. s/#.*//; # no comments
  150. s/^\s+//; # no leading white
  151. s/\s+$//; # no trailing white
  152. next unless length; # anything left?
  153. push @ips , $_; #it might be a host name too, so don't expect only numbers
  154. }
  155. close FILE;
  156. return @ips;
  157. }
  158. __END__
  159. =pod
  160. =head1 NAME
  161. scan_host - a scanning script to gather port and OS information from hosts
  162. =head1 SYNOPSIS
  163. scan_host.pl [OPTS] <IP_ADDR> [<IP.ADDR> ...]
  164. =head1 DESCRIPTION
  165. This script uses the nmap security scanner with the Nmap::Parser::XML module
  166. in order to run quick scans against specific hosts, and gather all the
  167. information that is required to know about that specific host which nmap can
  168. figure out. This script can be used for quick audits against machines on the
  169. network and an educational use for learning how to write scripts using the
  170. Nmap::Parser::XML module. B<This script uses the -sV output to get version
  171. information of the services running on a machine. This requires nmap version
  172. 3.49+>
  173. =head1 OPTIONS
  174. These options are passed as command line parameters.
  175. =over 4
  176. =item B<-i nmapscan.xml>
  177. Runs the script using the given xml file (which is nmap xml scan data) instead
  178. of actually running a scan against the given set of hosts. This is useful if
  179. you only have the xml data on a given machine, and not nmap.
  180. =item B<--fast>
  181. Runs a fast (-F) nmap scan against the host.
  182. =item B<-h,--help,-?>
  183. Shows this help information.
  184. =item B<-L ips.txt>
  185. Reads IP addresses from filename.txt to run a scan against. The IP addresses
  186. should be in the target specification format explained below.
  187. =item B<-v>
  188. This runs the script in verbose mode. The more times used, the more verbose
  189. the script will be.
  190. =back 4
  191. =head1 TARGET SPECIFICATION
  192. This documentation was taken from the nmap man page. The IP address inputs
  193. to this scripts should be in the nmap target specification format.
  194. The simplest case is listing single hostnames or IP addresses onthe command
  195. line. If you want to scan a subnet of IP addresses, you can append '/mask' to
  196. the hostname or IP address. mask must be between 0 (scan the whole internet) and
  197. 32 (scan the single host specified). Use /24 to scan a class 'C' address and
  198. /16 for a class 'B'.
  199. You can use a more powerful notation which lets you specify an IP address
  200. using lists/ranges for each element. Thus you can scan the whole class 'B'
  201. network 128.210.*.* by specifying '128.210.*.*' or '128.210.0-255.0-255' or
  202. even use the mask notation: '128.210.0.0/16'. These are all equivalent.
  203. If you use asterisks ('*'), remember that most shells require you to escape
  204. them with back slashes or protect them with quotes.
  205. Another interesting thing to do is slice the Internet the other way.
  206. Examples:
  207. scan_host.pl 127.0.0.1
  208. scan_host.pl target.example.com
  209. scan_host.pl target.example.com/24
  210. scan_host.pl 10.210.*.1-127
  211. scan_host.pl *.*.2.3-5
  212. scan_host.pl 10.[10-15].10.[2-254]
  213. =head1 OUTPUT EXAMPLE
  214. These are ONLY examples of how the output would look like.
  215. Scan Host
  216. --------------------------------------------------
  217. [>] 127.0.0.1
  218. [+] Status: (UP)
  219. [+] Hostname(s) :
  220. localhost.localdomain
  221. [+] Operation System(s) :
  222. Linux Kernel 2.4.0 - 2.5.20
  223. [+] TCP Ports :
  224. 22 ssh OpenSSH 3.5p1
  225. 25 smtp
  226. 111 rpcbind
  227. 443 https
  228. 631 ipp
  229. [+] UDP Ports :
  230. 111 rpcbind
  231. 937 unknown
  232. =head1 BUG REPORTS
  233. Please submit any bugs to:
  234. L<http://sourceforge.net/tracker/?group_id=97509&atid=618345>
  235. =head1 SEE ALSO
  236. L<Nmap::Parser::XML>
  237. The Nmap::Parser::XML page can be found at: L<http://npx.sourceforge.net/>.
  238. It contains the latest developments on the module. The nmap security scanner
  239. homepage can be found at: L<http://www.insecure.org/nmap/>.
  240. =head1 AUTHOR
  241. Anthony G Persaud <ironstar@iastate.edu>
  242. =head1 COPYRIGHT
  243. This program is free software; you can redistribute it and/or modify it under
  244. the terms of the GNU General Public License as published by the Free Software
  245. Foundation; either version 2 of the License, or (at your option) any later
  246. version.
  247. This program is distributed in the hope that it will be useful, but WITHOUT ANY
  248. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  249. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  250. L<http://www.opensource.org/licenses/gpl-license.php>
  251. =cut