summaryrefslogtreecommitdiffstats
path: root/bin/compare-nvd-cve
diff options
context:
space:
mode:
authorPetter Reinholdtsen <pere@debian.org>2011-01-26 21:01:44 +0000
committerPetter Reinholdtsen <pere@debian.org>2011-01-26 21:01:44 +0000
commitb8eb49144d38830f50359884721ad8b7406ba2f8 (patch)
tree38aea297a57ffb8a03c1b8c6956a523632f5d04d /bin/compare-nvd-cve
parentb4633644331998a6597972fe3357d9a3ddf02549 (diff)
Add first sketch using data/CPE/list.
git-svn-id: svn+ssh://svn.debian.org/svn/secure-testing@15976 e39458fd-73e7-0310-bf30-c45bca0a0e42
Diffstat (limited to 'bin/compare-nvd-cve')
-rwxr-xr-xbin/compare-nvd-cve123
1 files changed, 123 insertions, 0 deletions
diff --git a/bin/compare-nvd-cve b/bin/compare-nvd-cve
new file mode 100755
index 0000000000..a74a0074da
--- /dev/null
+++ b/bin/compare-nvd-cve
@@ -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]);
+}

© 2014-2024 Faster IT GmbH | imprint | privacy policy