File Coverage

blib/lib/XML/NessusParser.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package XML::NessusParser;
2              
3 1     1   32574 use strict;
  1         2  
  1         23  
4 1     1   5 use warnings;
  1         2  
  1         25  
5              
6 1     1   426 use XML::NessusParser::Host;
  0            
  0            
7             #use XML::NessusParser::Preferences
8             #use XML::NessusParser::Report
9              
10             use Exporter qw(import);
11              
12             our $VERSION = "0.01";
13             our @EXPORT_OK = qw(new parse livehosts RecursiveXMLtags);
14              
15              
16             sub new {
17             my $pkg = shift;
18             my $self = bless {}, $pkg;
19             $self->initialize(@_);
20             $self;
21             }
22              
23             sub initialize {
24             my $self = shift;
25             $self->{stem} = shift;
26             $self->{english} = shift;
27             }
28            
29            
30             sub parse {
31             my ($self,$filename) = @_;
32            
33             $self->{parsed} = {};
34            
35             my $parser = XML::LibXML->new();
36             my $nessusXML = $parser->parse_file($filename);
37              
38            
39             foreach ( $nessusXML->findnodes('/NessusClientData_v2/Policy/Preferences/ServerPreferences/preference') ) {
40             my @array = split('\n', $_->to_literal());
41             if ($#array eq 1 ) {
42             $self->{preferences}{server}{$array[0]} = $array[1];
43             }
44             }
45            
46             my @PluginPrefernces;
47             foreach ( $nessusXML->findnodes('/NessusClientData_v2/Policy/Preferences/PluginsPreferences/item') ) {
48             my %hash;
49             if ($_->findnodes('pluginName')->string_value()) { $hash{pluginName} = $_->findnodes('pluginName')->string_value(); }
50             if ($_->findnodes('pluginId')->string_value()) { $hash{pluginId} = $_->findnodes('pluginId')->string_value(); }
51             if ($_->findnodes('fullName')->string_value()) { $hash{fullName} = $_->findnodes('fullName')->string_value(); }
52             if ($_->findnodes('preferenceName')->string_value()) { $hash{preferenceName} = $_->findnodes('preferenceName')->string_value(); }
53             if ($_->findnodes('preferenceType')->string_value()) { $hash{preferenceType} = $_->findnodes('preferenceType')->string_value(); }
54             if ($_->findnodes('preferenceValues')->string_value()) { $hash{preferenceValues} = $_->findnodes('preferenceValues')->string_value(); }
55             if ($_->findnodes('selectedValue')->string_value()) { $hash{selectedValue} = $_->findnodes('selectedValue')->string_value(); }
56             push(@PluginPrefernces, { %hash });
57             }
58            
59             $self->{preferences}{plugins} = [ @PluginPrefernces ];
60            
61             my @Hosts;
62             foreach ($nessusXML->findnodes('/NessusClientData_v2/Report/ReportHost') ) {
63             my %HostHash;
64             for my $HostProperties ( @{$_->findnodes('HostProperties')} ) {
65             my %hash;
66             for my $tag ( $HostProperties->findnodes('tag') ) {
67             $HostHash{HostProperties}{$tag->getAttribute('name')} = $tag->string_value();
68             }
69             }
70             my @ReportItems;
71             for my $ReportItem ( $_->findnodes('ReportItem') ) {
72             my %item;
73             if ( $ReportItem->hasAttributes() ) {
74             for my $attribute ( $ReportItem->attributes() ) { $item{$attribute->name} = $attribute->getValue; }
75             }
76             for my $child ( $ReportItem->nonBlankChildNodes() ) { $item{$child->nodeName} = $child->string_value(); }
77             push(@ReportItems, { %item } );
78             }
79             $HostHash{ReportItems} = [ @ReportItems ] ;
80             push(@Hosts, { %HostHash });
81             }
82             $self->{hosts} = [ @Hosts ];
83             }
84              
85             sub plugin_set {
86             my ($self) = @_;
87             return split(/;/, $self->{preferences}{server}{plugin_set});
88            
89             }
90             sub target {
91             my ($self) = @_;
92             return $self->{preferences}{server}{TARGET};
93             }
94            
95             sub server_preference {
96             my ($self,$preference) = @_;
97             return $self->{preferences}{server}{$preference};
98             }
99              
100             sub plugin_preference {
101             my ($self,$preference) = @_;
102             return $self->{preferences}{plugins};
103             }
104              
105             sub sc_version {
106             my ($self,$preference) = @_;
107             return $self->{preferences}{plugins};
108             }
109              
110             sub nessus_version {
111             my ($self) = @_;
112             my $version;
113             foreach ( @{$self->{hosts}}) {
114             for my $item ( @{$_->{ReportItems}} ) {
115             if ($item->{pluginID} eq "19506" ) {
116             for my $line ( split('\n',$item->{plugin_output}) ) {
117            
118             chomp($line);
119             if ($line =~ /^Nessus version/ ) {
120             (undef,$version) = split(/:/,$line);
121             $version =~ s/^\s+//;$version =~ s/\s+$//;
122             last;
123             }
124             }
125             }
126             }
127             }
128             return $version;
129             }
130              
131             sub host_count {
132             my ($self) = @_;
133             my $hostCount = ( $#{$self->{hosts}} +1 );
134             return $hostCount;
135             }
136              
137             sub get_ips {
138             my ($self) = @_;
139             my @IPs;
140            
141             foreach ( @{$self->{hosts}}) {
142             for my $item ( @{$_->{ReportItems}} ) {
143             if (defined($_->{HostProperties}{'host-ip'}) ) { push(@IPs,$_->{HostProperties}{'host-ip'});}
144             }
145             }
146             return @IPs;
147             }
148              
149             sub get_host {
150            
151             my ($self,$hostIP) = @_;
152             my $host;
153             foreach ( @{$self->{hosts}}) {
154             for my $item ( @{$_->{ReportItems}} ) {
155             if (defined($_->{HostProperties}{'host-ip'}) ) {
156             $host = $_ if ( $_->{HostProperties}{'host-ip'} eq $hostIP )
157             }
158             }
159             }
160             my $HOST = NessusParser::Host->new($host);
161            
162             return $HOST;
163            
164             }
165              
166             sub get_policyName {
167            
168             }
169              
170             sub get_reportName {
171            
172             }
173              
174              
175             =head1 NAME
176              
177             XML::NessusParser - The great new XML::NessusParser!
178              
179             =head1 VERSION
180              
181             Version 0.01
182              
183             =cut
184              
185             our $VERSION = '0.01';
186              
187              
188             =head1 SYNOPSIS
189              
190             Quick summary of what the module does.
191              
192             Perhaps a little code snippet.
193              
194             use XML::NessusParser;
195              
196             my $foo = XML::NessusParser->new();
197             ...
198              
199             =head1 EXPORT
200              
201             A list of functions that can be exported. You can delete this section
202             if you don't export anything, such as for a purely object-oriented module.
203              
204             =head1 SUBROUTINES/METHODS
205              
206             =head2 parse($xml_file)
207              
208             Parses the Nessus XML scan data in $xml_file. This file is version 2 export/downlaoded Nessus results
209             obtained either from a nessus scanner directly or via Security Center. If you get an error or your
210             program dies due to parsing, please check that the xml information is compliant.
211              
212              
213             =head2 plugin_set()
214              
215             Returns an array of pluginIDs used for the parsed scan.
216            
217             =head2 all_server_preferences()
218              
219             returns an ARRAY containing a HASH values for all server preferences assoaciated with the scan results
220              
221             =head2 server_preference($preference_name)
222              
223             returne the prefeence setting associated with the preference arguement.
224              
225             =head2 all_plugin_preferences()
226              
227             returns an ARRAY containing a HASH values for all plugin preferences assoaciated with the scan results
228            
229             =head2 plugin_preference($preferance_name)
230              
231             method to return a HASH value containing the prefeernces associated with the
232              
233             =head2 target()
234              
235             shortcut method to return the target string of hosts scanned.
236            
237             =head2 sc_version()
238              
239             shortcut method to return the Security Center version (if available) in the XML results
240              
241             =head2 nessus_version()
242              
243             short cut method to return the nessus version used to scan as captured in the results of a pluginID 19506 output.
244              
245             =head2 host_count()
246              
247             returns number of live IPs in XML results
248            
249             =head2 get_ips()
250              
251             returns an array of IP addresses scanned that have results in the
252              
253             =head2 get_host($ip_address)
254              
255             returns a XML::NessusParser::Host object for the IP address passed as an arguement
256              
257              
258             =head2 get_policyName()
259              
260            
261             =head2 get_reportName()
262              
263              
264             =cut
265              
266             =head1 AUTHOR
267              
268             littleurl, C<< >>
269              
270             =head1 BUGS
271              
272             Please report any bugs or feature requests to C, or through
273             the web interface at L. I will be notified, and then you'll
274             automatically be notified of progress on your bug as I make changes.
275              
276              
277             =head1 SUPPORT
278              
279             You can find documentation for this module with the perldoc command.
280              
281             perldoc XML::NessusParser
282              
283              
284             You can also look for information at:
285              
286             =over 4
287              
288             =item * RT: CPAN's request tracker (report bugs here)
289              
290             L
291              
292             =item * AnnoCPAN: Annotated CPAN documentation
293              
294             L
295              
296             =item * CPAN Ratings
297              
298             L
299              
300             =item * Search CPAN
301              
302             L
303              
304             =back
305              
306              
307             =head1 ACKNOWLEDGEMENTS
308              
309              
310             =head1 LICENSE AND COPYRIGHT
311              
312             Copyright 2015 P Johnson.
313              
314             This program is free software; you can redistribute it and/or modify it
315             under the terms of the the Artistic License (2.0). You may obtain a
316             copy of the full license at:
317              
318             L
319              
320             Any use, modification, and distribution of the Standard or Modified
321             Versions is governed by this Artistic License. By using, modifying or
322             distributing the Package, you accept this license. Do not use, modify,
323             or distribute the Package, if you do not accept this license.
324              
325             If your Modified Version has been derived from a Modified Version made
326             by someone other than you, you are nevertheless required to ensure that
327             your Modified Version complies with the requirements of this license.
328              
329             This license does not grant you the right to use any trademark, service
330             mark, tradename, or logo of the Copyright Holder.
331              
332             This license includes the non-exclusive, worldwide, free-of-charge
333             patent license to make, have made, use, offer to sell, sell, import and
334             otherwise transfer the Package with respect to any patent claims
335             licensable by the Copyright Holder that are necessarily infringed by the
336             Package. If you institute patent litigation (including a cross-claim or
337             counterclaim) against any party alleging that the Package constitutes
338             direct or contributory patent infringement, then this Artistic License
339             to you shall terminate on the date that such litigation is filed.
340              
341             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
342             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
343             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
344             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
345             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
346             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
347             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
348             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
349              
350              
351             =cut
352              
353             1; # End of XML::NessusParser