| 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(). |
| |
| CVE: CVE-2018-11652 |
| Upstream-Status: Backport |
| Signed-off-by: Nagalakshmi Veeramallu <nveeramallu@mvista.com> |
| --- |
| plugins/nikto_outdated.plugin | 2 +- |
| plugins/nikto_report_csv.plugin | 42 +++++++++++++++++++++++++++++------------ |
| 2 files changed, 31 insertions(+), 13 deletions(-) |
| |
| diff --git a/plugins/nikto_outdated.plugin b/plugins/nikto_outdated.plugin |
| index 72379cc..eb1d889 100644 |
| --- a/plugins/nikto_outdated.plugin |
| +++ b/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] "; } |
| diff --git a/plugins/nikto_report_csv.plugin b/plugins/nikto_report_csv.plugin |
| index d13acab..b942e78 100644 |
| --- a/plugins/nikto_report_csv.plugin |
| +++ b/plugins/nikto_report_csv.plugin |
| @@ -52,10 +52,12 @@ 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 $handle "\"" . csv_safecell($hostname) . "\"," |
| + . "\"" . csv_safecell($mark->{'ip'}) . "\"," |
| + . "\"" . csv_safecell($mark->{'port'}) . "\"," . "\"\"," . "\"\"," . "\"\"," |
| + #. "\"" . $mark->{'banner'} . "\"\n"; |
| + . "\"" . csv_safecell($mark->{'banner'}) . "\"\n"; |
| + |
| return; |
| } |
| |
| @@ -65,26 +67,42 @@ 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($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; } |
| + { $line .= csv_safecell($mark->{'root'}) . $uri; } |
| + else { $line .= csv_safecell($ur |
| $line .= "\","; |
| |
| - $item->{'message'} =~ s/"/\\"/g; |
| - $line .= "\"$item->{'message'}\""; |
| - print $handle "$line\n"; |
| + my $msg = $item->{'message'}; |
| + $uri=quotemeta($uri); |
| + my $root = quotemeta($mark->{'root'}); |
| + $msg =~ s/^$uri:\s//; |
| + $msg =~ s/^$root$uri:\s//; |
| + $msg =~ s/"/\\"/g; |
| + $line .= "\"" . csv_safecell($msg) ."\""; |
| + print $handle "$line\n"; |
| + |
| } |
| } |
| |
| +############################################################################### |
| +# prevent CSV injection attacks |
| +sub csv_safecell { |
| + my $celldata = $_[0] || return; |
| + if ($celldata =~ /^[=+@-]/) { $celldata = "'" . $celldata; } |
| + return $celldata; |
| +} |
| + |
| + |
| 1; |
| -- |
| 2.6.4 |
| |