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 gen‐
52 erated 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
57 This module has an internal framework to make it easy to retrieve the
58 desired information of a scan. Every nmap scan is based on two main
59 sections of informations: the scan session, and the scan information of
60 all hosts. The session information will be stored as a
61 Nmap::Parser::Session object. This object will contain its own methods
62 to obtain the desired information. The same is true for any hosts that
63 were scanned using the Nmap::Parser::Host object. There are two sub
64 objects under Nmap::Parser::Host. One is the Nmap::Parser::Host::Ser‐
65 vice object which will be used to obtain information of a given service
66 running on a given port. The second is the Nmap::Parser::Host::OS
67 object which contains the operating system signature information (OS
68 guessed names, classes, osfamily..etc).
69
70 Nmap::Parser -- Core parser
71 ⎪
72 +--Nmap::Parser::Session -- Nmap scan session information
73 ⎪
74 +--Nmap::Parser::Host -- General host information
75 ⎪ ⎪
76 ⎪ ⎪-Nmap::Parser::Host::Service -- Port service information
77 ⎪ ⎪
78 ⎪ ⎪-Nmap::Parser::Host::OS -- Operating system signature information
79
81 Nmap::Parser
82
83 The main idea behind the core module is, you will first parse the
84 information and then extract data. Therefore, all parse*() methods
85 should be executed before any get_*() methods.
86
87 parse($string)
88 parse($filehandle)
89 Parses the nmap scan information in $string. Note that is usually
90 only used if you have the whole xml scan information in $string or
91 if you are piping the scan information.
92
93 parsefile($xml_file)
94 Parses the nmap scan data in $xml_file. This file can be generated
95 from an nmap scan by using the '-oX filename.xml' option with nmap.
96 If you get an error or your program dies due to parsing, please
97 check that the xml information is compliant. The file is closed no
98 matter how "parsefile()" returns.
99
100 parsescan($nmap,$args,@ips)
101 This method runs an nmap scan where $nmap is the path to the nmap
102 executable, $args are the nmap command line parameters, and @ips
103 are the list of IP addresses to scan. parsescan() will automagi‐
104 cally run the nmap scan and parse the information. See section
105 EXAMPLES for a short tutorial
106
107 Note: You cannot have one of the nmap options to be '-oX', '-oN' or
108 '-oG'. Your program will die if you try and pass any of these
109 options because it decides the type of output nmap will generate.
110 The IP addresses can be nmap-formatted addresses (see nmap(1)
111
112 If you get an error or your program dies due to parsing, please
113 check that the xml information is compliant. If you are using pars‐
114 escan() or an open filehandle , make sure that the nmap scan that
115 you are performing is successful in returning xml information.
116 (Sometimes using loopback addresses causes nmap to fail).
117
118 purge()
119 Cleans the xml scan data from memory. This is useful if you have a
120 program where you are parsing lots of nmap scan data files with
121 persistent variables.
122
123 callback(\&code_ref)
124 Sets the parsing mode to be done using the callback function. It
125 takes the parameter of a code reference or a reference to a func‐
126 tion. If no code reference is given, it resets the mode to normal
127 (no callback).
128
129 $np->callback(\&my_function); #sets callback, my_function() will be called
130 $np->callback(); #resets it, no callback function called. Back to normal.
131
132 get_session()
133 Obtains the Nmap::Parser::Session object which contains the session
134 scan information.
135
136 get_host($ip_addr)
137 Obtains the Nmap::Parser::Host object for the given $ip_addr.
138
139 del_host($ip_addr)
140 Deletes the stored Nmap::Parser::Host object whose IP is $ip_addr.
141
142 all_hosts()
143 all_hosts($status)
144 Returns an array of all the Nmap::Parser::Host objects for the
145 scan. If the optional status is given, it will only return those
146 hosts that match that status. The status can be any of the follow‐
147 ing: "(up⎪down⎪unknown⎪skipped)"
148
149 get_ips()
150 get_ips($status)
151 Returns the list of IP addresses that were scanned in this nmap
152 session. They are sorted using ipv4_sort. If there are IPv6
153 addresses, or mixed, it might not be in correct sorted order. If
154 the optional status is given, it will only return those IP
155 addresses that match that status. The status can be any of the fol‐
156 lowing: "(up⎪down⎪unknown⎪skipped)"
157
158 ipv4_sort(@ips)
159 This function takes a list of IPv4 addresses and returns the cor‐
160 rectly sorted version of the list.
161
162 Nmap::Parser::Session
163
164 This object contains the scan session information of the nmap scan.
165
166 finish_time()
167 Returns the numeric time that the nmap scan finished.
168
169 nmap_version()
170 Returns the version of nmap used for the scan.
171
172 numservices()
173 numservices($type)
174 If numservices is called without argument, it returns the total
175 number of services that were scanned for all types. If $type is
176 given, it returns the number of services for that given scan type.
177 See scan_types() for more info.
178
179 scan_args()
180 Returns a string which contains the nmap executed command line used
181 to run the scan.
182
183 scan_type_proto($type)
184 Returns the protocol type of the given scan type (provided by
185 $type). See scan_types() for more info.
186
187 scan_types()
188 Returns the list of scan types that were performed. It can be any
189 of the following: "(syn⎪ack⎪bounce⎪connect⎪null⎪xmas⎪window⎪mai‐
190 mon⎪fin⎪udp⎪ipproto)".
191
192 start_str()
193 Returns the human readable format of the start time.
194
195 start_time()
196 Returns the numeric form of the time the nmap scan started.
197
198 time_str()
199 Returns the human readable format of the finish time.
200
201 xml_version()
202 Returns the version of nmap xml file.
203
204 Nmap::Parser::Host
205
206 This object represents the information collected from a scanned host.
207
208 status()
209 Returns the state of the host. It is usually one of these
210 "(up⎪down⎪unknown⎪skipped)".
211
212 addr()
213 Returns the main IP address of the host. This is usually the IPv4
214 address. If there is no IPv4 address, the IPv6 is returned (hope‐
215 fully there is one).
216
217 addrtype()
218 Returns the address type of the address given by addr() .
219
220 all_hostnames()
221 Returns a list of all hostnames found for the given host.
222
223 extraports_count()
224 Returns the number of extraports found.
225
226 extraports_state()
227 Returns the state of all the extraports found.
228
229 hostname()
230 hostname($index)
231 As a basic call, hostname() returns the first hostname obtained for
232 the given host. If there exists more than one hostname, you can
233 provide a number, which is used as the location in the array. The
234 index starts at 0;
235
236 #in the case that there are only 2 hostnames
237 hostname() eq hostname(0);
238 hostname(1); #second hostname found
239 hostname(400) eq hostname(1) #nothing at 400; return the name at the last index
240
241 ipv4_addr()
242 Explicitly return the IPv4 address.
243
244 ipv6_addr()
245 Explicitly return the IPv6 address.
246
247 mac_addr()
248 Explicitly return the MAC address.
249
250 mac_vendor()
251 Return the vendor information of the MAC.
252
253 os_sig()
254 Returns an Nmap::Parser::Host::OS object that can be used to obtain
255 all the Operating System signature (fingerprint) information. See
256 Nmap::Parser::Host::OS for more details.
257
258 $os = $host->os_sig;
259 $os->name;
260 $os->osfamily;
261
262 tcpsequence_class()
263 tcpsequence_index()
264 tcpsequence_values()
265 Returns the class, index and values information respectively of the
266 tcp sequence.
267
268 ipidsequence_class()
269 ipidsequence_values()
270 Returns the class and values information respectively of the ipid
271 sequence.
272
273 tcptssequence_class()
274 tcptssequence_values()
275 Returns the class and values information respectively of the tcpts
276 sequence.
277
278 uptime_lastboot()
279 Returns the human readable format of the timestamp of when the host
280 had last rebooted.
281
282 uptime_seconds()
283 Returns the number of seconds that have passed since the host's
284 last boot from when the scan was performed.
285
286 tcp_ports()
287 udp_ports()
288 Returns the sorted list of TCP⎪UDP ports respectively that were
289 scanned on this host. Optionally a string argument can be given to
290 these functions to filter the list.
291
292 $host->tcp_ports('open') #returns all only 'open' ports (even 'open⎪filtered')
293 $host->udp_ports('open⎪filtered'); #matches exactly ports with 'open⎪filtered'
294
295 Note that if a port state is set to 'open⎪filtered' (or any combi‐
296 nation), it will be counted as an 'open' port as well as a 'fil‐
297 tered' one.
298
299 tcp_port_count()
300 udp_port_count()
301 Returns the total of TCP⎪UDP ports scanned respectively.
302
303 tcp_port_state($portid)
304 udp_port_state($portid)
305 Returns the state of the given port, provided by the port number in
306 $portid.
307
308 tcp_open_ports()
309 udp_open_ports()
310 Returns the list of open TCP⎪UDP ports respectively. Note that if a
311 port state is for example, 'open⎪filtered', it will appear on this
312 list as well.
313
314 tcp_filtered_ports()
315 udp_filtered_ports()
316 Returns the list of filtered TCP⎪UDP ports respectively. Note that
317 if a port state is for example, 'open⎪filtered', it will appear on
318 this list as well.
319
320 tcp_closed_ports()
321 udp_closed_ports()
322 Returns the list of closed TCP⎪UDP ports respectively. Note that if
323 a port state is for example, 'closed⎪filtered', it will appear on
324 this list as well.
325
326 tcp_service($portid)
327 udp_service($portid)
328 Returns the Nmap::Parser::Host::Service object of a given service
329 running on port, provided by $portid. See Nmap::Parser::Host::Ser‐
330 vice for more info.
331
332 $svc = $host->tcp_service(80);
333 $svc->name;
334 $svc->proto;
335
336 Nmap::Parser::Host::Service
337
338 This object represents the service running on a given port in a given
339 host. This object is obtained by using the tcp_service($portid) or
340 udp_service($portid) method from the Nmap::Parser::Host object. If a
341 portid is given that does not exist on the given host, these functions
342 will still return an object (so your script doesn't die). Its good to
343 use tcp_ports() or udp_ports() to see what ports were collected.
344
345 confidence()
346 Returns the confidence level in service detection.
347
348 extrainfo()
349 Returns any additional information nmap knows about the service.
350
351 method()
352 Returns the detection method.
353
354 name()
355 Returns the service name.
356
357 owner()
358 Returns the process owner of the given service. (If available)
359
360 port()
361 Returns the port number where the service is running on.
362
363 product()
364 Returns the product information of the service.
365
366 proto()
367 Returns the protocol type of the service.
368
369 rpcnum()
370 Returns the RPC number.
371
372 tunnel()
373 Returns the tunnel value. (If available)
374
375 version()
376 Returns the version of the given product of the running service.
377
378 Nmap::Parser::Host::OS
379
380 This object represents the Operating System signature (fingerprint)
381 information of the given host. This object is obtained from an
382 Nmap::Parser::Host object using the "os_sig()" method. One important
383 thing to note is that the order of OS names and classes are sorted by
384 DECREASING ACCURACY. This is more important than alphabetical ordering.
385 Therefore, a basic call to any of these functions will return the
386 record with the highest accuracy. (Which is probably the one you want
387 anyways).
388
389 all_names()
390 Returns the list of all the guessed OS names for the given host.
391
392 class_accuracy()
393 class_accuracy($index)
394 A basic call to class_accuracy() returns the osclass accuracy of
395 the first record. If $index is given, it returns the osclass accu‐
396 racy for the given record. The index starts at 0.
397
398 class_count()
399 Returns the total number of OS class records obtained from the nmap
400 scan.
401
402 name()
403 name($index)
404 names()
405 names($index)
406 A basic call to name() returns the OS name of the first record
407 which is the name with the highest accuracy. If $index is given, it
408 returns the name for the given record. The index starts at 0.
409
410 name_accuracy()
411 name_accuracy($index)
412 A basic call to name_accuracy() returns the OS name accuracy of the
413 first record. If $index is given, it returns the name for the given
414 record. The index starts at 0.
415
416 name_count()
417 Returns the total number of OS names (records) for the given host.
418
419 osfamily()
420 osfamily($index)
421 A basic call to osfamily() returns the OS family information of the
422 first record. If $index is given, it returns the OS family infor‐
423 mation for the given record. The index starts at 0.
424
425 osgen()
426 osgen($index)
427 A basic call to osgen() returns the OS generation information of
428 the first record. If $index is given, it returns the OS generation
429 information for the given record. The index starts at 0.
430
431 portused_closed()
432 Returns the closed port number used to help identify the OS signa‐
433 tures. This might not be available for all hosts.
434
435 portused_open()
436 Returns the open port number used to help identify the OS signa‐
437 tures. This might not be available for all hosts.
438
439 type()
440 type($index)
441 A basic call to type() returns the OS type information of the first
442 record. If $index is given, it returns the OS type information for
443 the given record. The index starts at 0.
444
445 vendor()
446 vendor($index)
447 A basic call to vendor() returns the OS vendor information of the
448 first record. If $index is given, it returns the OS vendor infor‐
449 mation for the given record. The index starts at 0.
450
452 I think some of us best learn from examples. These are a couple of
453 examples to help create custom security audit tools using some of the
454 nice features of the Nmap::Parser module. Hopefully this can double as
455 a tutorial. More tutorials (articles) can be found at www.nmap‐
456 parser.com
457
458 Real-Time Scanning - (no better "time()" like 'now')
459
460 You can run a nmap scan and have the parser parse the information
461 automagically. The only constraint is that you cannot use '-oX',
462 '-oN', or '-oG' as one of your arguments for nmap command line parame‐
463 ters passed to parsescan().
464
465 use Nmap::Parser;
466
467 my $np = new Nmap::Parser;
468 my @hosts = @ARGV; #get hosts from cmd line
469
470 #runs the nmap command with hosts and parses it automagically
471 $np->parsescan('/usr/bin/nmap','-sS O -p 1-1023',@hosts);
472
473 for my $host ($np->all_hosts()){
474 print $host->hostname."\n";
475 #do mor stuff...
476 }
477
478 Callbacks - ("not our $normal *69")
479
480 This is probably the easiest way to write a script with using
481 Nmap::Parser, if you don't need the general scan session information.
482 During the parsing process, the parser will obtain information of every
483 host. The callback function (in this case 'booyah()') is called after
484 the parsing of every host (sequentially). When the callback returns,
485 the parser will delete all information of the host it had sent to the
486 callback. This callback function is called for every host that the
487 parser encounters. The callback function must be setup before parsing
488
489 use Nmap::Parser;
490 my $np = new Nmap::Parser;
491
492 $np->callback( \&booyah );
493
494 $np->parsefile('nmap_results.xml');
495 # or use parsescan()
496
497 sub booyah {
498 my $host = shift; #Nmap::Parser::Host object, just parsed
499 print 'IP: ',$host->addr,"\n";
500 # ... do more stuff with $host ...
501
502 #when it returns, host object will be deleted from memory
503 #(good for processing VERY LARGE files or scans)
504 }
505
506 Multiple Instances - ("no less 'of'; my $self")
507
508 Using multiple instances of Nmap::Parser is extremely useful in helping
509 audit/monitor the network Policy (ohh noo! its that 'P' word!). In
510 this example, we have a set of hosts that had been scanned previously
511 for tcp services where the image was saved in base_image.xml. We now
512 will scan the same hosts, and compare if any new tcp have been open
513 since then (good way to look for suspicious new services). Easy secu‐
514 rity Compliance detection. (ooh noo! The 'C' word too!).
515
516 use Nmap::Parser;
517 use vars qw($nmap_exe $nmap_args @ips);
518 my $base = new Nmap::Parser;
519 my $curr = new Nmap::Parser;
520
521 $base->parsefile('base_image.xml'); #load previous state
522 $curr->parsescan($nmap_exe, $nmap_args, @ips); #scan current hosts
523
524 for my $ip ($curr->get_ips )
525 {
526 #assume that IPs in base == IPs in curr scan
527 my $ip_base = $base->get_host($ip);
528 my $ip_curr = $curr->get_host($ip);
529 my %port = ();
530
531 #find ports that are open that were not open before
532 #by finding the difference in port lists
533 my @diff = grep { $port{$_} < 2}
534 (map {$port{$_}++; $_}
535 ( $ip_curr->tcp_open_ports , $ip_base->tcp_open_ports ));
536
537 print "$ip has these new ports open: ".join(',',@diff) if(scalar @diff);
538
539 for (@diff){print "$_ seems to be ",$ip_curr->tcp_service($_)->name,"\n";}
540
541 }
542
544 Discussion Forum
545
546 If you have questions about how to use the module, or any of its fea‐
547 tures, you can post messages to the Nmap::Parser module forum on
548 CPAN::Forum. <http://www.cpanforum.com/dist/Nmap-Parser>
549
550 Bug Reports
551
552 Please submit any bugs to: <http://source‐
553 forge.net/tracker/?group_id=97509&atid=618345>
554
555 Please make sure that you submit the xml-output file of the scan which
556 you are having trouble. This can be done by running your scan with the
557 -oX filename.xml nmap switch. Please remove any important IP addresses
558 for security reasons.
559
561 nmap, XML::Twig
562
563 The Nmap::Parser page can be found at: <http://www.nmapparser.com>. It
564 contains the latest developments on the module. The nmap security scan‐
565 ner homepage can be found at: <http://www.insecure.org/nmap/>.
566
568 Anthony G Persaud <apersaud@gmail.com> <http://www.anthonypersaud.com>
569
571 This program is free software; you can redistribute it and/or modify it
572 under the terms of the GNU General Public License as published by the
573 Free Software Foundation; either version 2 of the License, or (at your
574 option) any later version.
575
576 This program is distributed in the hope that it will be useful, but
577 WITHOUT ANY WARRANTY; without even the implied warranty of MER‐
578 CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
579 Public License for more details.
580
581 <http://www.opensource.org/licenses/gpl-license.php>
582
583
584
585perl v5.8.8 2007-05-27 Parser(3)