1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
From e759b3300aace5314fe3d30800c8bd83c81c29f7 Mon Sep 17 00:00:00 2001
From: sullo <sullo@cirt.net>
Date: Thu, 31 May 2018 23:30:03 -0400
Subject: [PATCH] Fix CSV injection issue if server responds with a malicious
Server string & CSV output is opened in Excel or other spreadsheet app.
Potentially malicious cell start characters are now prefaced with a ' mark.
Thanks to Adam (@bytesoverbombs) for letting me know!
Also fixed a crash in the outdated plugin if the $sepr field ends up being something that triggers a panic in split().
---
program/plugins/nikto_outdated.plugin | 2 +-
program/plugins/nikto_report_csv.plugin | 41 ++++++++++++++++++++-------------
2 files changed, 26 insertions(+), 17 deletions(-)
Index: nikto/plugins/nikto_outdated.plugin
===================================================================
--- nikto.orig/plugins/nikto_outdated.plugin
+++ nikto/plugins/nikto_outdated.plugin
@@ -83,7 +83,7 @@ sub nikto_outdated {
$sepr = substr($sepr, (length($sepr) - 1), 1);
# break up ID string on $sepr
- my @T = split(/$sepr/, $mark->{'banner'});
+ my @T = split(/\\$sepr/, $mark->{'banner'});
# assume last is version...
for ($i = 0 ; $i < $#T ; $i++) { $MATCHSTRING .= "$T[$i] "; }
Index: nikto/plugins/nikto_report_csv.plugin
===================================================================
--- nikto.orig/plugins/nikto_report_csv.plugin
+++ nikto/plugins/nikto_report_csv.plugin
@@ -52,10 +52,11 @@ sub csv_open {
sub csv_host_start {
my ($handle, $mark) = @_;
$mark->{'banner'} =~ s/"/\\"/g;
- print OUT "\"$mark->{'hostname'}\","
- . "\"$mark->{'ip'}\","
- . "\"$mark->{'port'}\"," . "\"\"," . "\"\"," . "\"\","
- . "\"$mark->{'banner'}\"\n";
+ print OUT "\"" . csv_safecell($mark->{'hostname'}) . "\","
+ . "\"" . csv_safecell($mark->{'ip'}) . "\","
+ . "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"\"," . "\"\"," . "\"\","
+ #. "\"" . $mark->{'banner'} . "\"\n";
+ . "\"" . csv_safecell($mark->{'banner'}) . "\"\n";
return;
}
@@ -65,26 +66,34 @@ sub csv_item {
my ($handle, $mark, $item) = @_;
foreach my $uri (split(' ', $item->{'uri'})) {
my $line = '';
- $line .= "\"$item->{'mark'}->{'hostname'}\",";
- $line .= "\"$item->{'mark'}->{'ip'}\",";
- $line .= "\"$item->{'mark'}->{'port'}\",";
+ $line .= "\"" . csv_safecell($item->{'mark'}->{'hostname'}) . "\",";
+ $line .= "\"" . csv_safecell($item->{'mark'}->{'ip'}) . \",";
+ $line .= "\"" . csv_safecell($item->{'mark'}->{'port'}) . "\",";
$line .= "\"";
if ($item->{'osvdb'} ne '') { $line .= "OSVDB-" . $item->{'osvdb'}; }
$line .= "\",";
$line .= "\"";
- if ($item->{'method'} ne '') { $line .= $item->{'method'}; }
+ if ($item->{'method'} ne '') { $line .= csv_safecell($item->{'method'}); }
$line .= "\",";
$line .= "\"";
- if ($uri ne '') { $line .= $mark->{'root'} . $uri; }
+ if ($uri ne '') { $line .= csv_safecell($mark->{'root'}) . $uri; }
$line .= "\",";
$item->{'message'} =~ s/"/\\"/g;
- $line .= "\"$item->{'message'}\"";
+ $line .= "\"" . csv_safecell($item->{'message'}) ."\"";
print $handle "$line\n";
}
}
+###############################################################################
+# prevent CSV injection attacks
+sub csv_safecell {
+ my $celldata = $_[0] || return;
+ if ($celldata =~ /^[=+@-]/) { $celldata = "'" . $celldata; }
+ return $celldata;
+}
+
1;
|