Author: pere Date: 2011-01-26 21:01:44 +0000 (Wed, 26 Jan 2011) New Revision: 15976 Added: bin/compare-nvd-cve Log: Add first sketch using data/CPE/list. Added: bin/compare-nvd-cve ==================================================================--- bin/compare-nvd-cve (rev 0) +++ bin/compare-nvd-cve 2011-01-26 21:01:44 UTC (rev 15976) @@ -0,0 +1,123 @@ +#!/usr/bin/perl +# +# Compare the Debian list of CVEs with the NVD list of CVEs using CPE +# ids, to see if the set of affected packages match. + +use warnings; +use strict; + +use XML::Simple; +use Data::Dumper; + +use vars qw($debug %cpemap %cperevmap %cvemap %reportedmissing); + +$| = 1; + +open(my $fh, "<", "data/CPE/list") || die; +while (<$fh>) { + chomp; + my ($binpkg, $cpe) = split(/;/); + if ($cpe) { + $cpemap{$binpkg} = $cpe; + $cperevmap{$cpe} = $binpkg; + } +} +close $fh; + +open ($fh, "<", "data/CVE/list") || die; +my $cve; +while (<$fh>) { + chomp; + $cve = $1 if (m/^(CVE-\S+)\s*/); + s/^(\s+)\[\S+\] /$1/; # Trim away distribution name + if (m/^\s+- (\S+)\S*/ && ! m/<not-affected>/) { + my $srcpkg = $1; + if (exists $cvemap{$cve}) { + push(@{$cvemap{$cve}}, $srcpkg); + } else { + $cvemap{$cve} = [$srcpkg]; + } + } +} +close $fh; + +# +# Fetched from http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-2008.xml +# +for my $cvelist + ( + "nvdcve-2.0-2011.xml", +# "nvdcve-2.0-2010.xml", +# "nvdcve-2.0-2009.xml", +# "nvdcve-2.0-2008.xml", + ) { + print "Loading $cvelist\n" if $debug; + my $ref = XMLin("../../" . $cvelist); + for my $cve (sort keys %{$ref->{entry}}) { + print "Checking $cve\n" if $debug; + my $entry = $ref->{entry}->{$cve}; + + my %info; + my @debiancpe = get_debian_cpe($cve); + for my $cpe (@debiancpe) { + $info{$cpe} = 1; + } + + my @products; + if (exists $entry->{''vuln:vulnerable-software-list''}->{''vuln:product''}) { + if ("ARRAY" eq ref $entry->{''vuln:vulnerable-software-list''}->{''vuln:product''}) { + @products = @{$entry->{''vuln:vulnerable-software-list''}->{''vuln:product''}}; + } else { + @products = ($entry->{''vuln:vulnerable-software-list''}->{''vuln:product''}); + } + } + for my $cpe (@products) { + if (exists $info{cpe_product($cpe)}) { + $info{cpe_product($cpe)} += 2; + } else { + $info{cpe_product($cpe)} = 2; + } + } + for my $cpe (sort keys %info) { + if (1 == $info{$cpe}) { + my %shortlist; + map { $shortlist{cpe_product($_)} = 1 } @products; + my $cpelist = join(", ", keys %shortlist); + print STDERR "warning: $cve in Debian refer to $cpe, while NVD do not (found $cpelist).\n" + } elsif (2 == $info{$cpe}) { + if (exists $cperevmap{$cpe}) { + my $binpkg = $cperevmap{$cpe}; + print STDERR "warning: $cve in NVD is not refering to $cpe found in Debian.\n" + } + + } elsif (3 == $info{$cpe}) { + } + } + } + print "Done loading $cvelist\n" if $debug; +} + +for my $missing (sort { $reportedmissing{$a} <=> $reportedmissing{$b} } + keys %reportedmissing) { + my $count = $reportedmissing{$missing}; + print STDERR "error: $cve: missing CPE ID for $missing ($count)\n"; +} + +sub get_debian_cpe { + my ($cve) = shift; + my %cpe; + for my $binpkg (@{$cvemap{$cve}}) { + if (exists $cpemap{$binpkg}) { + $cpe{$cpemap{$binpkg}} = 1; + } else { + $reportedmissing{$binpkg} = exists $reportedmissing{$binpkg} ? + $reportedmissing{$binpkg} + 1 : 1; + } + } + return sort keys %cpe; +} + +sub cpe_product { + my $cpe = shift; + return join(":", (split(/:/, $cpe))[0..3]); +} Property changes on: bin/compare-nvd-cve ___________________________________________________________________ Added: svn:executable + *