mirror of
https://github.com/nmap/nmap.git
synced 2025-12-08 05:31:31 +00:00
204 lines
4.1 KiB
Perl
204 lines
4.1 KiB
Perl
#!/usr/bin/perl -w
|
|
|
|
sub usage() {
|
|
print STDERR "Usage: $0 <nmap os fingerprint submission file>\n" .
|
|
"Slurps up the given nmap-os-fingerprints file, sorts it appropriately (Class, then name string), then spits it out to stdout. Some minor canonicalization is done too.\n\n";
|
|
exit(0);
|
|
}
|
|
|
|
sub osprep($) {
|
|
my $ln = shift;
|
|
chomp ($ln);
|
|
$ln =~ s/^\s+//;
|
|
$ln =~ s/\s+$//;
|
|
return $ln;
|
|
}
|
|
|
|
sub finalfpprep($) {
|
|
my $ln = shift;
|
|
$ln =~ s/\)/\)\n/g;
|
|
return $ln;
|
|
}
|
|
|
|
sub fprintsort() {
|
|
lc($a->{fpClass}) cmp lc($b->{fpClass})
|
|
or
|
|
lc($a->{fpName}) cmp lc($b->{fpName})
|
|
or
|
|
$b->{fpGood} <=> $a->{fpGood}
|
|
;
|
|
}
|
|
|
|
if ($#ARGV != 0) {
|
|
print STDERR "ERROR: Wrong number of command-line arguments (must be exactly 1)\n";
|
|
usage();
|
|
}
|
|
|
|
my $osfile = shift();
|
|
open(OSFILE, "<$osfile") or die "Failed to open purported os fingerprint submission file: $osfile\n";
|
|
|
|
my $state = "null";
|
|
my $lineno = 0;
|
|
|
|
my @mails;
|
|
my %msg = ();
|
|
my $bodylines = -1;
|
|
|
|
my $fpstate = "null";
|
|
my $fpstr = "";
|
|
my @fplines;
|
|
my %fp;
|
|
my $fptestname = "";
|
|
my $fptestnum = 0;
|
|
|
|
|
|
while ($line = <OSFILE>) {
|
|
$lineno++;
|
|
|
|
if ($state eq "null") {
|
|
if ($line =~ /^\s*$/) {
|
|
next;
|
|
} else {
|
|
$state = "msg_header";
|
|
}
|
|
}
|
|
|
|
if ($state eq "msg_header") {
|
|
if ($line =~ /^\s*$/) {
|
|
# A blank line ends a mail header
|
|
if ($bodylines == -1) {
|
|
die "ERROR: Parse error on $osfile:$lineno -- expected a Lines field in mail header";
|
|
}
|
|
$state = "msg_body";
|
|
} else {
|
|
if ($line =~ /^lines:\s*([0-9]+)/i) {
|
|
$bodylines = $1;
|
|
}
|
|
$msg{header} .= $line;
|
|
}
|
|
next;
|
|
} elsif ($state eq "msg_body") {
|
|
if ($bodylines > 0) {
|
|
$bodylines--;
|
|
$msg{body} .= $line;
|
|
|
|
if ($line =~ /^\s*Fingerprint (\S.*\S)\s*$/) {
|
|
$msg{fpName} = $1;
|
|
}
|
|
if ($line =~ /^\s*Class (\S.*\S)$/) {
|
|
$msg{fpClass} = $1;
|
|
}
|
|
if ($line =~ /^\s*OS:/i) {
|
|
$line = osprep($line);
|
|
$line =~ s/^\s*OS://i;
|
|
$fpstr .= $line;
|
|
$fpstate = "fp";
|
|
} elsif ($fpstate eq "fp") {
|
|
$fpstate = "null";
|
|
}
|
|
}
|
|
if ($bodylines == 0) {
|
|
if (!$msg{fpName}) {
|
|
$msg{fpName} = "NULL";
|
|
}
|
|
if (!$msg{fpClass}) {
|
|
$msg{fpClass} = "NULL";
|
|
}
|
|
|
|
$msg{fpGood} = 0;
|
|
|
|
if ($fpstr) {
|
|
$fpstr = finalfpprep($fpstr);
|
|
# print $fpstr . "\n";
|
|
@fplines = split /\n/, $fpstr;
|
|
|
|
$fptestnum = 0;
|
|
foreach $fpline (@fplines) {
|
|
# print $fpline . "\n";
|
|
if ($fpline =~ /^SCAN.*%OT=([0-9]*)%CT=([0-9]*)%CU=([0-9]*)%PV=([YN])(%DS=([0-9]+))?%G=([YN])(%M=([0-9A-F]+))?.*/i) {
|
|
$fptestnum++;
|
|
# $fp_ot = $1;
|
|
# $fp_ct = $2;
|
|
$fp_cu = $3;
|
|
$fp_pv = $4;
|
|
# if($5) {
|
|
# $fp_ds = $6;
|
|
# } else {
|
|
# $fp_ds = -1;
|
|
# }
|
|
$fp_good = $7;
|
|
if($8) {
|
|
$fp_mac = $9;
|
|
} else {
|
|
$fp_mac = "";
|
|
}
|
|
|
|
if ($fp_cu) {
|
|
$msg{fpGood} += 1;
|
|
}
|
|
|
|
if ($fp_pv eq "Y") {
|
|
$msg{fpGood} += 1;
|
|
}
|
|
|
|
if ($fp_good eq "Y") {
|
|
$msg{fpGood} += 2;
|
|
}
|
|
|
|
if ($fp_mac) {
|
|
$msg{fpGood} += 1;
|
|
}
|
|
|
|
} elsif ($fpline =~ /^((SEQ)|(OPS)|(WIN)|(ECN)|(T[1-7])|(U1)|(IE))/i) {
|
|
$fptestname = $1;
|
|
if (!$fp{$fptestname}) {
|
|
$fptestnum++;
|
|
}
|
|
$fp{$fptestname} .= $line;
|
|
}
|
|
}
|
|
if ($fptestnum == 14) {
|
|
# This submission has all the fp fields
|
|
$msg{fpGood} += 5;
|
|
}
|
|
}
|
|
# print $msg{fpGood} . "\n";
|
|
|
|
my %copy = %msg;
|
|
push @mails, \%copy;
|
|
|
|
$state = "null";
|
|
%msg = ();
|
|
$bodylines = -1;
|
|
|
|
$fpstate = "null";
|
|
$fpstr = "";
|
|
%fp = ();
|
|
}
|
|
next;
|
|
}
|
|
}
|
|
|
|
my @sortedmails = sort fprintsort @mails;
|
|
|
|
my $firstline = 1;
|
|
my $currentFpClass = "";
|
|
foreach $mail (@sortedmails) {
|
|
if ($firstline) {
|
|
$firstline = 0;
|
|
} else { print "\n"; }
|
|
|
|
if ($currentFpClass ne $mail->{fpClass}) {
|
|
print 'From anonymous@core.lnxnet.net Mon Jul 04 00:00:01 2006', "\n",
|
|
'To: fyodor@insecure.org', "\n",
|
|
'From: nmap-submission-cgi@core.lnxnet.net', "\n",
|
|
"Subject: ====== $mail->{fpClass} ======\n",
|
|
"Status: O\n",
|
|
"Lines: 1\n\n";
|
|
print "## Separator ##\n\n";
|
|
$currentFpClass = $mail->{fpClass};
|
|
}
|
|
print "$mail->{header}\n";
|
|
print "$mail->{body}";
|
|
}
|