#VERSION,1.04 #LASTMOD,03.14.2001 # eval build parameters for web servers # the stripping of letters from version numbers could be done better # versions are loaded from the "outdated.db" file, which should be in the plugins directory # we cheat, as apache is the main one that uses spaces for loaded modules... if there are others we'll have to hard code them # This software is distributed under the terms of the GPL, which should have been received # with a copy of this software in the "LICENSE.txt" file. # CHANGES: # 1.02 -- Fixed bug where software running that was newere than db would warn as outdated # 1.03 -- Fixed bug if $V (%VERSIONS) was somehow blank it evaluated as a matched version # 1.04 -- Rewrote major portions to better handle alpha characters in version strings sub nikto_outdated { my $VFILE="$NIKTO{plugindir}/outdated.db"; my %VERSIONS=load_versions($VFILE); # populate @BUILDITEMS with appropriate values # if Apache, split on space... if ($SERVER{servertype} =~ /apache/i) { @BUILDITEMS=split(/ /,$SERVER{servertype}); } elsif ($SERVER{servertype} =~ /weblogic/i) # strip all the date info from weblogic... { my @T=split(/ /,$SERVER{servertype}); push(@BUILDITEMS,"$T[0]\/$T[1]"); } else { my $t=""; if ($SERVER{servertype} !~ /\s/) # has no spaces { $MATCHSTRING=$SERVER{servertype}; } elsif ($SERVER{servertype} =~ /\//) # has spaces and / sepr { $MATCHSTRING=$SERVER{servertype}; $MATCHSTRING=~s/\s+//g; } else # must create sepr { # use the last non 0-9 . a-z char as a sepr (' ', '-', '_' etc) my $sepr=$SERVER{servertype}; $sepr =~ s/[a-zA-Z0-9\.]//gi; $sepr=substr($sepr,(length($sepr)-1),1); # $sepr=~ s/\s+/ /g; # break up ID string on $sepr my @T=split(/$sepr/,$SERVER{servertype}); # assume last is version... for ($i=0;$i<$#T;$i++) { $MATCHSTRING .= "$T[$i] "; } } $MATCHSTRING =~ s/\s+$//; push(@BUILDITEMS,$MATCHSTRING); dprint("Server Version String:$MATCHSTRING\n"); } my ($v, $V, $BI, $k) = ""; foreach $BI (@BUILDITEMS) { foreach $V (sort keys %VERSIONS) { if ($V eq "") { next; } if ($BI =~ /$V/i) # software name matched { foreach $k (keys %{ $VERSIONS{$V} }) { if ($k eq "") { next; } $v=$k; } if (vereval($v,$BI,$V)) # version check { my $t = $v; my $msg = $VERSIONS{$V}{$v}; $msg =~ s/RUNNING_VER/$BI/g; $msg =~ s/CURRENT_VER/$v/g; chomp($msg); fprint("+ $msg\n"); } } } } return; } sub load_versions { my @T=(); my %VERS; my $F=$_[0] || return; open(VF,"<$F") || die fprint("Cannot open versions file '$F': $!\n"); my @V=; close(VF); foreach my $line (@V) { chomp($line); if ($line =~ /^\#/) { next; } if ($line eq "") { next; } if ($line =~ /\#/) { $line=~s/\#.*$//; $line=~s/\s+$//; } my @T=parse_csv($line); # Match Vers Message $VERS{$T[0]}{$T[1]}=$T[2]; } return %VERS; } sub vereval { # split both by last char of @_[0], as it is the name to version separator my $sepr=substr($_[2],(length($sepr)-1),1); dprint("nikto_outdated.pl: verstring: $_[2], sepr:$sepr\n"); $CURRENT=lc($_[0]); $RUNNING=lc($_[1]); my @T=split(/$sepr/,$CURRENT); my $CURRENT=$T[$#T]; # should be version... @T=split(/$sepr/,$RUNNING); my $RUNNING=$T[$#T]; # should be version... # convert alphas to numerics so we can do a real comparison while ($CUR =~ /[^0-9\.]/) { $CURRENT =~ /([^0-9\.]){1}/; my $x=ord($1); $CURRENT =~ s/$1/\.$x/; } while ($RUNNING=~ /[^0-9\.]/) { $RUNNING=~ /([^0-9\.]){1}/; my $x=ord($1); $RUNNING=~ s/$1/\.$x/; } $RUNNING =~ s/^\.//; $CURRENT =~ s/^\.//; @CUR=split(/\./,$CURRENT); @RUN=split(/\./,$RUNNING); # start with 0... eval each in turn... for (my $i=0;$i<=$#CUR;$i++) { if ($CUR[$i] > $RUN[$i]) { return 1; } # running is older if ($CUR[$i] < $RUN[$i]) { return 0; } # running is newer if (($CUR[$i] ne "") && ($RUN[$i] eq "")) { return 1; } # running is older } return 0; # running is the same version if we make it here } 1;