Subject: | XMLification fixes for Nmap::Scanner 1.0 |
The Nmap::Scanner 1.0 package straight from CPAN has a variety of issues.
(*) It relies too much on undef, which throws "Use of uninitialized value"
warnings from various places.
(*) It does not properly XML-encode certain characters, notably ampersand,
that it receives from nmap.
(*) When it does try to encode entities, it uses HTML encoding instead of
XML encoding or numeric entity encoding, which means that inappropriate
(non-XML) entities may be referenced.
(*) It mixes up <nmap-err> and </nmap-msg> tags.
I have run a lot of tests and addressed all the instances of such
problems found in that testing. The resulting patch is attached here
as the Nmap::Scanner-1.0.patch file. As presented, for simplicity,
the patch uses the Perl "//" operator, first available in Perl 5.10.
Subject: | Nmap::Scanner-1.0.patch |
--- Nmap/Scanner/Address.pm.orig 2005-08-29 18:51:40.000000000 -0700
+++ Nmap/Scanner/Address.pm 2016-10-08 17:01:04.182778210 -0700
@@ -7,8 +7,10 @@
vendor $),
'&as_xml' => q!return qq(<address addr="$addr" ) .
qq(addrtype="$addrtype" ) .
- qq(vendor="$vendor"/>);!
-};
+ qq(vendor=").encode_entities_numeric($vendor).qq("/>);!
+},
+'-use' => ["HTML::Entities 'encode_entities_numeric'"]
+;
=pod
--- Nmap/Scanner/Backend/XML.pm.orig 2006-10-29 11:05:38.000000000 -0800
+++ Nmap/Scanner/Backend/XML.pm 2016-10-17 18:25:00.175738945 -0700
@@ -6,6 +6,7 @@
@ISA = qw(Nmap::Scanner::Backend::Processor);
use XML::SAX::ParserFactory;
+use HTML::Entities qw(encode_entities_numeric);
use Nmap::Scanner;
use Nmap::Scanner::Backend::Results;
@@ -29,7 +30,7 @@
# Suppress warnings about reading unopened handle
$^W = 0;
- my $err = join('', (<$error>));
+ my $err = encode_entities_numeric(join('', (<$error>)));
$^W = 1;
if ($err ne '') {
@@ -41,7 +42,7 @@
<nmap-error>
<pid="$pid"/>
<cmdline="$cmdline"/>
- <nmap-err>$err</nmap-msg>
+ <nmap-err>$err</nmap-err>
</nmap-error>
EOF
exit 1;
@@ -55,7 +56,7 @@
if (defined($@) && ($@ ne '')) {
- my $msg = join('', <$read>);
+ my $msg = encode_entities_numeric(join('', <$read>));
Nmap::Scanner::debug("bytes in input stream: " . tell($read));
Nmap::Scanner::debug("bytes in error stream: " . tell($error));
@@ -66,7 +67,7 @@
<cmdline="$cmdline"/>
<perl-msg>$@</perl-msg>
<nmap-msg>$msg</nmap-msg>
- <nmap-err>$err</nmap-msg>
+ <nmap-err>$err</nmap-err>
</nmap-error>
EOF
close($read);
@@ -282,8 +283,7 @@
my $addr = Nmap::Scanner::Address->new();
$addr->addr($ref->{'{}addr'}->{Value});
$addr->addrtype($ref->{'{}addrtype'}->{Value});
- $addr->vendor($ref->{'{}vendor'}->{Value})
- if $ref->{'{}vendor'}->{Value};
+ $addr->vendor($ref->{'{}vendor'}->{Value} // '');
$self->{NMAP_HOST}->add_address($addr);
}
@@ -356,10 +356,10 @@
my ($self, $ref) = @_;
my $os = $self->{NMAP_OSGUESS};
my $class = Nmap::Scanner::OS::Class->new();
- $class->type($ref->{'{}type'}->{Value});
- $class->vendor($ref->{'{}vendor'}->{Value});
+ $class->type($ref->{'{}type'}->{Value} // '');
+ $class->vendor($ref->{'{}vendor'}->{Value} // '');
$class->osfamily($ref->{'{}osfamily'}->{Value});
- $class->osgen($ref->{'{}osgen'}->{Value});
+ $class->osgen($ref->{'{}osgen'}->{Value} // '');
$class->accuracy($ref->{'{}accuracy'}->{Value});
$os->add_os_class($class);
}
@@ -405,7 +405,7 @@
my $os = $self->{NMAP_OSGUESS};
my $t = Nmap::Scanner::OS::TCPSequence->new();
$t->index($ref->{'{}index'}->{Value});
- $t->class($ref->{'{}class'}->{Value});
+ $t->class($ref->{'{}class'}->{Value} // '');
$t->difficulty($ref->{'{}difficulty'}->{Value});
$t->values($ref->{'{}values'}->{Value});
$os->tcpsequence($t);
@@ -415,7 +415,7 @@
my ($self, $ref) = @_;
my $os = $self->{NMAP_OSGUESS};
my $t = Nmap::Scanner::OS::TCPTSSequence->new();
- $t->class($ref->{'{}class'}->{Value});
+ $t->class($ref->{'{}class'}->{Value} // '');
$t->values($ref->{'{}values'}->{Value});
$os->tcptssequence($t);
}
@@ -424,7 +424,7 @@
my ($self, $ref) = @_;
my $os = $self->{NMAP_OSGUESS};
my $t = Nmap::Scanner::OS::IPIdSequence->new();
- $t->class($ref->{'{}class'}->{Value});
+ $t->class($ref->{'{}class'}->{Value} // '');
$t->values($ref->{'{}values'}->{Value});
$os->ipidsequence($t);
}
--- Nmap/Scanner/Host.pm.orig 2006-10-29 09:55:00.000000000 -0800
+++ Nmap/Scanner/Host.pm 2016-10-08 06:44:13.260046410 -0700
@@ -65,7 +65,7 @@
}
$xml .= qq(<smurf responses="$self->{smurf}"/>\n)
- if $self->{smurf} > 0;
+ if $self->{smurf};
my $hxml = '';
--- Nmap/Scanner/HostList.pm.orig 2005-08-29 18:51:40.000000000 -0700
+++ Nmap/Scanner/HostList.pm 2016-10-06 08:23:00.624539338 -0700
@@ -21,7 +21,7 @@
my $self = shift;
- my $xml;
+ my $xml = '';
while (my $host = $self->get_next()) {
last unless defined $host;
--- Nmap/Scanner/OS.pm.orig 2006-10-28 22:14:50.000000000 -0700
+++ Nmap/Scanner/OS.pm 2016-10-17 18:04:05.676806669 -0700
@@ -18,7 +18,7 @@
'&as_xml' => q!
# No fingerprinting happened if no ports found to fingerprint with.
- return unless scalar($self->ports_used()) > 0;
+ return '' unless scalar($self->ports_used() // @{[]}) > 0;
my $xml = "<os>\n";
--- Nmap/Scanner/OS/Class.pm.orig 2005-08-29 18:51:42.000000000 -0700
+++ Nmap/Scanner/OS/Class.pm 2016-10-08 17:03:10.917694648 -0700
@@ -11,12 +11,14 @@
accuracy $),
'&as_xml' => q!
- return qq(<osclass type="$self->{type}" vendor="$self->{vendor}" ) .
+ return qq(<osclass type="$self->{type}" vendor=").encode_entities_numeric($self->{vendor}).qq(" ) .
qq(osfamily="$self->{osfamily}" osgen="$self->{osgen}" ) .
qq(accuracy="$self->{accuracy}"/>);
!
-};
+},
+'-use' => ["HTML::Entities 'encode_entities_numeric'"]
+;
1;
--- Nmap/Scanner/OS/Match.pm.orig 2005-08-29 18:51:42.000000000 -0700
+++ Nmap/Scanner/OS/Match.pm 2016-10-08 17:06:09.580040299 -0700
@@ -6,11 +6,12 @@
class 'Nmap::Scanner::OS::Match' => {
qw(name $
accuracy $),
- '&as_xml' => q!my $osname = HTML::Entities::encode_entities($self->{name});
+ '&as_xml' => q!my $osname = encode_entities_numeric($self->{name});
qq(<osmatch name="$osname" ) .
qq(accuracy="$self->{accuracy}"/>);!
},
-'-use' => 'HTML::Entities';
+'-use' => ["HTML::Entities 'encode_entities_numeric'"]
+;
1;
--- Nmap/Scanner/PortList.pm.orig 2005-08-29 18:51:40.000000000 -0700
+++ Nmap/Scanner/PortList.pm 2016-10-08 06:45:07.186597886 -0700
@@ -31,7 +31,7 @@
sub as_xml {
my $self = shift;
- my $xml;
+ my $xml = '';
while (my $p = $self->get_next()) {
last unless defined $p;
--- Nmap/Scanner/Service.pm.orig 2005-08-29 18:51:40.000000000 -0700
+++ Nmap/Scanner/Service.pm 2016-10-08 17:04:38.316776484 -0700
@@ -29,7 +29,7 @@
for my $ee (qw(product extrainfo)) {
next unless $self->{$ee};
- my $encoded = encode_entities($self->{$ee});
+ my $encoded = encode_entities_numeric($self->{$ee});
$body .= qq($ee="$encoded" );
}
@@ -37,7 +37,7 @@
!
},
-'-use' => 'HTML::Entities'
+'-use' => ["HTML::Entities 'encode_entities_numeric'"]
;
=pod