A short update on improving Melcara's parse_nessus perl script:
My primary issue with the original, which took the most time, was sorting outputted IP addresses in the "Vulnerability to IP summary" sheet. A couple hours of investigation found that sorting those in the perl script was easier said than done.
my $ip = join "\n", keys %{$ip_vuln_data{$file}->{$sev}->{$plugin}->{ip}};e>
That's the line that creates a scalar string of IPs, separated by (invisible) newlines in the Excel cells. Turns out you can't easily sort that string. You might ask, ok, how about $ip_vuln_data:
# store data in the %ip_vuln_data hash
$ip_vuln_data{$host->{file}}->{$h_report->{-severity}}->{$h_report->{-pluginID}}->{pluginName} = $h_report->{-pluginName};
if ($host->{'host-ip'} eq "") {$ip_vuln_data{$host->{file}}->{$h_report->{-severity}}->{$h_report->{-pluginID}}->{ip}->{$host->{'name'}}++;}
else{$ip_vuln_data{$host->{file}}->{$h_report->{-severity}}->{$h_report->{-pluginID}}->{ip}->{$host->{'host-ip'}}++;}
Looks like it's searching a $h_report string to create a 'name','host-ip' hash (forgive my phrasing, Perl is not native tongue).
What if we go even earlier in the process? How does it get the string data?
Somewhere in here, it's parsing the .Nessus file. Later I realized that you can't control the order of IP addresses in the export of the .nessus file from Nessus, so it was back to the original location.
Then I found a solution
here, and adjusted it thus:
#convert unsorted string to array
my @ip2 = split("\n",$ip);
#print @ip2;
my @sorted_ips =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, eval { Net::IP->new( $_ )->intip } ] }
@ip2;
#convert back to newline-seperated string
my $ip2 = join "\n", @sorted_ips;
Now, the contents of the cells is invisibly new-line separated, and in order. Now to pack it into a new executable:
pp -M JSON -M PAR::Dist -M URI::Escape -M LWP::UserAgent -M HTTP::Cookies -M Data::Dump -M Data::Dumper -M XML::Hash::XS -M XML::TreePP -M MIME::Base64 -M Math::Round -M Excel::Writer::XLSX -M Excel::Writer::XLSX::Chart -M Excel::Writer::XLSX::Chart::Pie -M Data::Table -M Getopt::Std -M Net::IP parse_nessus_xml.v22.pl
And we are good to go! Get it
here.
Next steps: Add the ability to merge Nessus files to this script.
Update 5-22-18: I'm adjusting the original post to help anyone who's actually trying to re-create this.
To get this to work:
1. Add "use Net::IP" at the top of the perl file.
2. Where the original file has:
my $ip = join ";", keys %{$ip_vuln_data{$file}->{$sev}->{$plugin}->{ip}};
mine has the following (changes in bold):
my $ip = join "\n", keys %{$ip_vuln_data{$file}->{$sev}->{$plugin}->{ip}};
#convert unsorted string to array
my @ip2 = split("\n",$ip);
my @sorted_ips =
map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, eval { Net::IP->new( $_ )->intip } ] }
@ip2;
print @sorted_ips;
#convert back to newline-seperated string
my $ip2 = join "\n", @sorted_ips;
my $ip_cnt = keys %{$ip_vuln_data{$file}->{$sev}->{$plugin}->{ip}};
$ip_vuln_data_worksheet->write($ip_vuln_data_ctr, 0, $file,$cell_format);
$ip_vuln_data_worksheet->write($ip_vuln_data_ctr, 1, $severity,$cell_format);
$ip_vuln_data_worksheet->write($ip_vuln_data_ctr, 2, $plugin,$cell_format);
$ip_vuln_data_worksheet->write($ip_vuln_data_ctr, 3, $ip_vuln_data{$file}->{$sev}->{$plugin}->{pluginName},$cell_format);
$ip_vuln_data_worksheet->write($ip_vuln_data_ctr, 4, $ip_cnt,$cell_format);
$ip_vuln_data_worksheet->write($ip_vuln_data_ctr, 5, $ip2,$cell_format);
++$ip_vuln_data_ctr;
}
For reference, here is the perl file with my additional formatting changes.