1Parser(3) User Contributed Perl Documentation Parser(3)
2
3
4
6 Nmap::Parser - parse nmap scan data with perl
7
9 use Nmap::Parser;
10 my $np = new Nmap::Parser;
11
12 $np->parsescan($nmap_path, $nmap_args, @ips);
13 #or
14 $np->parsefile($file_xml);
15
16 my $session = $np->get_session();
17 #a Nmap::Parser::Session object
18
19 my $host = $np->get_host($ip_addr);
20 #a Nmap::Parser::Host object
21
22 my $service = $host->tcp_service(80);
23 #a Nmap::Parser::Host::Service object
24
25 my $os = $host->os_sig();
26 #a Nmap::Parser::Host::OS object
27
28 #---------------------------------------
29
30 my $np2 = new Nmap::Parser;
31
32 $np2->callback(\&my_callback);
33
34 $np2->parsefile($file_xml);
35 #or
36 $np2->parsescan($nmap_path, $nmap_args, @ips);
37
38 sub my_callback {
39
40 my $host = shift;
41 #Nmap::Parser::Host object
42 #.. see documentation for all methods ...
43
44 }
45
46 For a full listing of methods see the documentation corresponding to
47 each object.
48
50 This module implements a interface to the information contained in an
51 nmap scan. It is implemented by parsing the xml scan data that is
52 generated by nmap. This will enable anyone who utilizes nmap to quickly
53 create fast and robust security scripts that utilize the powerful port
54 scanning abilities of nmap.
55
56 The latest version of this module can be found on here
57 https://github.com/apersaud/Nmap-Parser/
58 <https://github.com/apersaud/Nmap-Parser/>
59
61 This module has an internal framework to make it easy to retrieve the
62 desired information of a scan. Every nmap scan is based on two main
63 sections of informations: the scan session, and the scan information of
64 all hosts. The session information will be stored as a
65 Nmap::Parser::Session object. This object will contain its own methods
66 to obtain the desired information. The same is true for any hosts that
67 were scanned using the Nmap::Parser::Host object. There are two sub
68 objects under Nmap::Parser::Host. One is the
69 Nmap::Parser::Host::Service object which will be used to obtain
70 information of a given service running on a given port. The second is
71 the Nmap::Parser::Host::OS object which contains the operating system
72 signature information (OS guessed names, classes, osfamily..etc).
73
74 Nmap::Parser -- Core parser
75 |
76 +--Nmap::Parser::Session -- Nmap scan session information
77 |
78 +--Nmap::Parser::Host -- General host information
79 | |
80 | |-Nmap::Parser::Host::Service -- Port service information
81 | |
82 | |-Nmap::Parser::Host::OS -- Operating system signature information
83
85 Nmap::Parser
86 The main idea behind the core module is, you will first parse the
87 information and then extract data. Therefore, all parse*() methods
88 should be executed before any get_*() methods.
89
90 parse($string)
91 parse($filehandle)
92 Parses the nmap scan information in $string. Note that is usually
93 only used if you have the whole xml scan information in $string or
94 if you are piping the scan information.
95
96 parsefile($xml_file)
97 Parses the nmap scan data in $xml_file. This file can be generated
98 from an nmap scan by using the '-oX filename.xml' option with nmap.
99 If you get an error or your program dies due to parsing, please
100 check that the xml information is compliant. The file is closed no
101 matter how "parsefile()" returns.
102
103 parsescan($nmap,$args,@ips)
104 This method runs an nmap scan where $nmap is the path to the nmap
105 executable or binary, $args are the nmap command line parameters,
106 and @ips are the list of IP addresses to scan. parsescan() will
107 automagically run the nmap scan and parse the information.
108
109 If you wish to save the xml output from parsescan(), you must call
110 cache_scan() method BEFORE you start the parsescan() process. This
111 is done to conserve memory while parsing. cache_scan() will let
112 Nmap::Parser know to save the output before parsing the xml since
113 Nmap::Parser purges everything that has been parsed by the script
114 to conserve memory and increase speed.
115
116 See section EXAMPLES for a short tutorial
117
118 Note: You cannot have one of the nmap options to be '-oX', '-oN' or
119 '-oG'. Your program will die if you try and pass any of these
120 options because it decides the type of output nmap will generate.
121 The IP addresses can be nmap-formatted addresses see nmap(1)
122
123 If you get an error or your program dies due to parsing, please
124 check that the xml information is compliant. If you are using
125 parsescan() or an open filehandle , make sure that the nmap scan
126 that you are performing is successful in returning xml information.
127 (Sometimes using loopback addresses causes nmap to fail).
128
129 cache_scan($filename)
130 This function allows you to save the output of a parsescan() (or
131 nmap scan) to the disk. $filename is the name of the file you wish
132 to save the nmap scan information to. It defaults to
133 nmap-parser-cache.xml It returns the name of the file to be used as
134 the cache.
135
136 #Must be called before parsescan().
137 $np->cache_scan($filename); #output set to nmap-parser-cache.xml
138
139 #.. do other stuff to prepare for parsescan(), ex. setup callbacks
140
141 $np->parsescan('/usr/bin/nmap',$args,@IPS);
142
143 purge()
144 Cleans the xml scan data from memory. This is useful if you have a
145 program where you are parsing lots of nmap scan data files with
146 persistent variables.
147
148 callback(\&code_ref)
149 Sets the parsing mode to be done using the callback function. It
150 takes the parameter of a code reference or a reference to a
151 function. If no code reference is given, it resets the mode to
152 normal (no callback).
153
154 $np->callback(\&my_function); #sets callback, my_function() will be called
155 $np->callback(); #resets it, no callback function called. Back to normal.
156
157 get_session()
158 Obtains the Nmap::Parser::Session object which contains the session
159 scan information.
160
161 get_host($ip_addr)
162 Obtains the Nmap::Parser::Host object for the given $ip_addr.
163
164 del_host($ip_addr)
165 Deletes the stored Nmap::Parser::Host object whose IP is $ip_addr.
166
167 all_hosts()
168 all_hosts($status)
169 Returns an array of all the Nmap::Parser::Host objects for the
170 scan. If the optional status is given, it will only return those
171 hosts that match that status. The status can be any of the
172 following: "(up|down|unknown|skipped)"
173
174 get_ips()
175 get_ips($status)
176 Returns the list of IP addresses that were scanned in this nmap
177 session. They are sorted using addr_sort. If the optional status is
178 given, it will only return those IP addresses that match that
179 status. The status can be any of the following:
180 "(up|down|unknown|skipped)"
181
182 addr_sort(@ips)
183 This function takes a list of IP addresses and returns the
184 correctly sorted version of the list.
185
186 Nmap::Parser::Session
187 This object contains the scan session information of the nmap scan.
188
189 finish_time()
190 Returns the numeric time that the nmap scan finished.
191
192 nmap_version()
193 Returns the version of nmap used for the scan.
194
195 numservices()
196 numservices($type)
197 If numservices is called without argument, it returns the total
198 number of services that were scanned for all types. If $type is
199 given, it returns the number of services for that given scan type.
200 See scan_types() for more info.
201
202 scan_args()
203 Returns a string which contains the nmap executed command line used
204 to run the scan.
205
206 scan_type_proto($type)
207 Returns the protocol type of the given scan type (provided by
208 $type). See scan_types() for more info.
209
210 scan_types()
211 Returns the list of scan types that were performed. It can be any
212 of the following:
213 "(syn|ack|bounce|connect|null|xmas|window|maimon|fin|udp|ipproto)".
214
215 start_str()
216 Returns the human readable format of the start time.
217
218 start_time()
219 Returns the numeric form of the time the nmap scan started.
220
221 time_str()
222 Returns the human readable format of the finish time.
223
224 xml_version()
225 Returns the version of nmap xml file.
226
227 Nmap::Parser::Host
228 This object represents the information collected from a scanned host.
229
230 status()
231 Returns the state of the host. It is usually one of these
232 "(up|down|unknown|skipped)".
233
234 addr()
235 Returns the main IP address of the host. This is usually the IPv4
236 address. If there is no IPv4 address, the IPv6 is returned
237 (hopefully there is one).
238
239 addrtype()
240 Returns the address type of the address given by addr() .
241
242 all_hostnames()
243 Returns a list of all hostnames found for the given host.
244
245 extraports_count()
246 Returns the number of extraports found.
247
248 extraports_state()
249 Returns the state of all the extraports found.
250
251 hostname()
252 hostname($index)
253 As a basic call, hostname() returns the first hostname obtained for
254 the given host. If there exists more than one hostname, you can
255 provide a number, which is used as the location in the array. The
256 index starts at 0;
257
258 #in the case that there are only 2 hostnames
259 hostname() eq hostname(0);
260 hostname(1); #second hostname found
261 hostname(400) eq hostname(1) #nothing at 400; return the name at the last index
262
263 ipv4_addr()
264 Explicitly return the IPv4 address.
265
266 ipv6_addr()
267 Explicitly return the IPv6 address.
268
269 mac_addr()
270 Explicitly return the MAC address.
271
272 mac_vendor()
273 Return the vendor information of the MAC.
274
275 distance()
276 Return the distance (in hops) of the target machine from the
277 machine that performed the scan.
278
279 trace_error()
280 Returns a true value (usually a meaningful error message) if the
281 traceroute was performed but could not reach the destination. In
282 this case "all_trace_hops()" contains only the part of the path
283 that could be determined.
284
285 all_trace_hops()
286 Returns an array of Nmap::Parser::Host::TraceHop objects
287 representing the path to the target host. This array may be empty
288 if Nmap did not perform the traceroute for some reason (same
289 network, for example).
290
291 Some hops may be missing if Nmap could not figure out information
292 about them. In this case there is a gap between the "ttl()" values
293 of consecutive returned hops. See also "trace_error()".
294
295 trace_proto()
296 Returns the name of the protocol used to perform the traceroute.
297
298 trace_port()
299 Returns the port used to perform the traceroute.
300
301 os_sig()
302 Returns an Nmap::Parser::Host::OS object that can be used to obtain
303 all the Operating System signature (fingerprint) information. See
304 Nmap::Parser::Host::OS for more details.
305
306 $os = $host->os_sig;
307 $os->name;
308 $os->osfamily;
309
310 tcpsequence_class()
311 tcpsequence_index()
312 tcpsequence_values()
313 Returns the class, index and values information respectively of the
314 tcp sequence.
315
316 ipidsequence_class()
317 ipidsequence_values()
318 Returns the class and values information respectively of the ipid
319 sequence.
320
321 tcptssequence_class()
322 tcptssequence_values()
323 Returns the class and values information respectively of the tcpts
324 sequence.
325
326 uptime_lastboot()
327 Returns the human readable format of the timestamp of when the host
328 had last rebooted.
329
330 uptime_seconds()
331 Returns the number of seconds that have passed since the host's
332 last boot from when the scan was performed.
333
334 hostscripts()
335 hostscripts($name)
336 A basic call to hostscripts() returns a list of the names of the
337 host scripts run. If $name is given, it returns the text output of
338 the script with that name, or undef if that script was not run.
339
340 tcp_ports()
341 udp_ports()
342 Returns the sorted list of TCP|UDP ports respectively that were
343 scanned on this host. Optionally a string argument can be given to
344 these functions to filter the list.
345
346 $host->tcp_ports('open') #returns all only 'open' ports (even 'open|filtered')
347 $host->udp_ports('open|filtered'); #matches exactly ports with 'open|filtered'
348
349 Note that if a port state is set to 'open|filtered' (or any
350 combination), it will be counted as an 'open' port as well as a
351 'filtered' one.
352
353 tcp_port_count()
354 udp_port_count()
355 Returns the total of TCP|UDP ports scanned respectively.
356
357 tcp_del_ports($portid, [$portid, ...])
358 udp_del_ports($portid, [ $portid, ...])
359 Deletes the current $portid from the list of ports for given
360 protocol.
361
362 tcp_port_state($portid)
363 udp_port_state($portid)
364 Returns the state of the given port, provided by the port number in
365 $portid.
366
367 tcp_open_ports()
368 udp_open_ports()
369 Returns the list of open TCP|UDP ports respectively. Note that if a
370 port state is for example, 'open|filtered', it will appear on this
371 list as well.
372
373 tcp_filtered_ports()
374 udp_filtered_ports()
375 Returns the list of filtered TCP|UDP ports respectively. Note that
376 if a port state is for example, 'open|filtered', it will appear on
377 this list as well.
378
379 tcp_closed_ports()
380 udp_closed_ports()
381 Returns the list of closed TCP|UDP ports respectively. Note that if
382 a port state is for example, 'closed|filtered', it will appear on
383 this list as well.
384
385 tcp_service($portid)
386 udp_service($portid)
387 Returns the Nmap::Parser::Host::Service object of a given service
388 running on port, provided by $portid. See
389 Nmap::Parser::Host::Service for more info.
390
391 $svc = $host->tcp_service(80);
392 $svc->name;
393 $svc->proto;
394
395 Nmap::Parser::Host::Service
396
397 This object represents the service running on a given port in a given
398 host. This object is obtained by using the tcp_service($portid) or
399 udp_service($portid) method from the Nmap::Parser::Host object. If a
400 portid is given that does not exist on the given host, these functions
401 will still return an object (so your script doesn't die). Its good to
402 use tcp_ports() or udp_ports() to see what ports were collected.
403
404 confidence()
405 Returns the confidence level in service detection.
406
407 extrainfo()
408 Returns any additional information nmap knows about the service.
409
410 method()
411 Returns the detection method.
412
413 name()
414 Returns the service name.
415
416 owner()
417 Returns the process owner of the given service. (If available)
418
419 port()
420 Returns the port number where the service is running on.
421
422 product()
423 Returns the product information of the service.
424
425 proto()
426 Returns the protocol type of the service.
427
428 rpcnum()
429 Returns the RPC number.
430
431 tunnel()
432 Returns the tunnel value. (If available)
433
434 fingerprint()
435 Returns the service fingerprint. (If available)
436
437 version()
438 Returns the version of the given product of the running service.
439
440 scripts()
441 scripts($name)
442 A basic call to scripts() returns a list of the names of the
443 scripts run for this port. If $name is given, it returns the text
444 output of the script with that name, or undef if that script was
445 not run.
446
447 Nmap::Parser::Host::OS
448
449 This object represents the Operating System signature (fingerprint)
450 information of the given host. This object is obtained from an
451 Nmap::Parser::Host object using the "os_sig()" method. One important
452 thing to note is that the order of OS names and classes are sorted by
453 DECREASING ACCURACY. This is more important than alphabetical ordering.
454 Therefore, a basic call to any of these functions will return the
455 record with the highest accuracy. (Which is probably the one you want
456 anyways).
457
458 all_names()
459 Returns the list of all the guessed OS names for the given host.
460
461 class_accuracy()
462 class_accuracy($index)
463 A basic call to class_accuracy() returns the osclass accuracy of
464 the first record. If $index is given, it returns the osclass
465 accuracy for the given record. The index starts at 0.
466
467 class_count()
468 Returns the total number of OS class records obtained from the nmap
469 scan.
470
471 name()
472 name($index)
473 names()
474 names($index)
475 A basic call to name() returns the OS name of the first record
476 which is the name with the highest accuracy. If $index is given, it
477 returns the name for the given record. The index starts at 0.
478
479 name_accuracy()
480 name_accuracy($index)
481 A basic call to name_accuracy() returns the OS name accuracy of the
482 first record. If $index is given, it returns the name for the given
483 record. The index starts at 0.
484
485 name_count()
486 Returns the total number of OS names (records) for the given host.
487
488 osfamily()
489 osfamily($index)
490 A basic call to osfamily() returns the OS family information of the
491 first record. If $index is given, it returns the OS family
492 information for the given record. The index starts at 0.
493
494 osgen()
495 osgen($index)
496 A basic call to osgen() returns the OS generation information of
497 the first record. If $index is given, it returns the OS generation
498 information for the given record. The index starts at 0.
499
500 portused_closed()
501 Returns the closed port number used to help identify the OS
502 signatures. This might not be available for all hosts.
503
504 portused_open()
505 Returns the open port number used to help identify the OS
506 signatures. This might not be available for all hosts.
507
508 os_fingerprint()
509 Returns the OS fingerprint used to help identify the OS signatures.
510 This might not be available for all hosts.
511
512 type()
513 type($index)
514 A basic call to type() returns the OS type information of the first
515 record. If $index is given, it returns the OS type information for
516 the given record. The index starts at 0.
517
518 vendor()
519 vendor($index)
520 A basic call to vendor() returns the OS vendor information of the
521 first record. If $index is given, it returns the OS vendor
522 information for the given record. The index starts at 0.
523
524 Nmap::Parser::Host::TraceHop
525
526 This object represents a router on the IP path towards the destination
527 or the destination itself. This is similar to what the "traceroute"
528 command outputs.
529
530 Nmap::Parser::Host::TraceHop objects are obtained through the
531 "all_trace_hops()" and "trace_hop()" Nmap::Parser::Host methods.
532
533 ttl()
534 The Time To Live is the network distance of this hop.
535
536 rtt()
537 The Round Trip Time is roughly equivalent to the "ping" time
538 towards this hop. It is not always available (in which case it
539 will be undef).
540
541 ipaddr()
542 The known IP address of this hop.
543
544 host()
545 The host name of this hop, if known.
546
548 I think some of us best learn from examples. These are a couple of
549 examples to help create custom security audit tools using some of the
550 nice features of the Nmap::Parser module. Hopefully this can double as
551 a tutorial. More tutorials (articles) can be found at
552 http://anthonypersaud.com/category/nmap-parser/
553 <http://anthonypersaud.com/category/nmap-parser/>
554
555 Real-Time Scanning
556 You can run a nmap scan and have the parser parse the information
557 automagically. The only constraint is that you cannot use '-oX',
558 '-oN', or '-oG' as one of your arguments for nmap command line
559 parameters passed to parsescan().
560
561 use Nmap::Parser;
562
563 my $np = new Nmap::Parser;
564 my @hosts = @ARGV; #get hosts from cmd line
565
566 #runs the nmap command with hosts and parses it automagically
567 $np->parsescan('/usr/bin/nmap','-sS O -p 1-1023',@hosts);
568
569 for my $host ($np->all_hosts()){
570 print $host->hostname."\n";
571 #do mor stuff...
572 }
573
574 If you would like to run the scan using parsescan() but also save the
575 scan xml output, you can use cache_scan(). You must call cache_scan()
576 BEFORE you initiate the parsescan() method.
577
578 use Nmap::Parser;
579 my $np = new Nmap::Parser;
580
581 #telling np to save output
582 $np->cache_scan('nmap.localhost.xml');
583 $np->parsescan('/usr/bin/nmap','-F','localhost');
584 #do other stuff...
585
586 Callbacks
587 This is probably the easiest way to write a script with using
588 Nmap::Parser, if you don't need the general scan session information.
589 During the parsing process, the parser will obtain information of every
590 host. The callback function (in this case 'booyah()') is called after
591 the parsing of every host (sequentially). When the callback returns,
592 the parser will delete all information of the host it had sent to the
593 callback. This callback function is called for every host that the
594 parser encounters. The callback function must be setup before parsing
595
596 use Nmap::Parser;
597 my $np = new Nmap::Parser;
598
599
600 $np->callback( \&booyah );
601
602 $np->parsefile('nmap_results.xml');
603 # or use parsescan()
604
605 sub booyah {
606 my $host = shift; #Nmap::Parser::Host object, just parsed
607 print 'IP: ',$host->addr,"\n";
608 # ... do more stuff with $host ...
609
610 #when it returns, host object will be deleted from memory
611 #(good for processing VERY LARGE files or scans)
612 }
613
614 Multiple Instances - ("no less 'of'; my $self")
615 Using multiple instances of Nmap::Parser is extremely useful in helping
616 audit/monitor the network Policy (ohh noo! its that 'P' word!). In
617 this example, we have a set of hosts that had been scanned previously
618 for tcp services where the image was saved in base_image.xml. We now
619 will scan the same hosts, and compare if any new tcp have been open
620 since then (good way to look for suspicious new services). Easy
621 security Compliance detection. (ooh noo! The 'C' word too!).
622
623 use Nmap::Parser;
624 use vars qw($nmap_exe $nmap_args @ips);
625 my $base = new Nmap::Parser;
626 my $curr = new Nmap::Parser;
627
628
629 $base->parsefile('base_image.xml'); #load previous state
630 $curr->parsescan($nmap_exe, $nmap_args, @ips); #scan current hosts
631
632 for my $ip ($curr->get_ips )
633 {
634 #assume that IPs in base == IPs in curr scan
635 my $ip_base = $base->get_host($ip);
636 my $ip_curr = $curr->get_host($ip);
637 my %port = ();
638
639 #find ports that are open that were not open before
640 #by finding the difference in port lists
641 my @diff = grep { $port{$_} < 2}
642 (map {$port{$_}++; $_}
643 ( $ip_curr->tcp_open_ports , $ip_base->tcp_open_ports ));
644
645 print "$ip has these new ports open: ".join(',',@diff) if(scalar @diff);
646
647 for (@diff){print "$_ seems to be ",$ip_curr->tcp_service($_)->name,"\n";}
648
649 }
650
652 Discussion Forum
653 If you have questions about how to use the module, or any of its
654 features, you can post messages to the Nmap::Parser module forum on
655 CPAN::Forum. https://github.com/apersaud/Nmap-Parser/issues
656 <https://github.com/apersaud/Nmap-Parser/issues>
657
658 Bug Reports and Enhancements
659 Please submit any bugs or feature requests to:
660 https://github.com/apersaud/Nmap-Parser/issues
661 <https://github.com/apersaud/Nmap-Parser/issues>
662
663 Please make sure that you submit the xml-output file of the scan which
664 you are having trouble with. This can be done by running your scan with
665 the -oX filename.xml nmap switch. Please remove any important IP
666 addresses for security reasons. It saves time in reproducing issues.
667
669 nmap, XML::Twig
670
671 The Nmap::Parser page can be found at:
672 https://github.com/apersaud/Nmap-Parser
673 <https://github.com/apersaud/Nmap-Parser>. It contains the latest
674 developments on the module. The nmap security scanner homepage can be
675 found at: <http://www.insecure.org/nmap/>.
676
678 Anthony G Persaud <http://anthonypersaud.com> . Please see Changes file
679 and CONTRIBUTORS file for a list of other great contributors.
680
681 Additional Contributors:
682 * Robin Bowes <http://robinbowes.com>
683 * Daniel Miller <https://github.com/bonsaiviking>
684 * See Changes file for other contributors.
685
687 Copyright (c) <2003-2010> <Anthony G. Persaud>
688
689 MIT License
690
691 Permission is hereby granted, free of charge, to any person obtaining a
692 copy of this software and associated documentation files (the
693 "Software"), to deal in the Software without restriction, including
694 without limitation the rights to use, copy, modify, merge, publish,
695 distribute, sublicense, and/or sell copies of the Software, and to
696 permit persons to whom the Software is furnished to do so, subject to
697 the following conditions:
698
699 The above copyright notice and this permission notice shall be included
700 in all copies or substantial portions of the Software.
701
702 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
703 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
704 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
705 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
706 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
707 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
708 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
709
710
711
712perl v5.12.3 2011-05-25 Parser(3)