From 898b7ef9ca7feefd64767d9eead0ce617b448f6c Mon Sep 17 00:00:00 2001 From: JonnyHightower Date: Thu, 17 Nov 2016 12:15:12 +0000 Subject: [PATCH] Added dirb/testssl. SSH now uses medusa. Minor bugfix to SMTP. --- VERSION | 2 +- content/HTTP/HTTP.gsm | 91 +++++++++++++++++++- content/SMTP/SMTP.gsm | 36 ++++---- content/SSH/SSH.gsm | 29 +++---- content/SSH/passwords.txt | 6 +- content/SSL/SSL.gsm | 154 ++++++++++++++++++++++++---------- content/Topology/Topology.gsm | 4 +- content/UnixVA/UnixVA.gsm | 2 +- content/VERSION | 2 +- 9 files changed, 238 insertions(+), 88 deletions(-) diff --git a/VERSION b/VERSION index e25d8d9..0664a8f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.5 +1.1.6 diff --git a/content/HTTP/HTTP.gsm b/content/HTTP/HTTP.gsm index ff28fae..987697a 100644 --- a/content/HTTP/HTTP.gsm +++ b/content/HTTP/HTTP.gsm @@ -169,14 +169,16 @@ sub activate { my $screenshotTimeout=25; # Seconds my $SSL=0; my $VirtualHost=undef; + my $defaultDirbList="NEET/common.txt"; if ("$file" eq "https.txt"){ $SSL=1; + my $sslscan=$MainScan->getPath("sslscan"); if ($sslscan && !$self->IsScanComplete("${name}_ssl",$target)){ - my $error=$MainScan->System($MainScan->getPath("sslscan") . " $socket > ${outputDir}/raw/sslscan-${socket}.txt 2>&1"); + my $error=$MainScan->System($MainScan->getPath("sslscan") . " $socket > ${outputDir}/raw/sslscan-${port}.txt 2>&1"); if (!$error){ - my @ciphers=$MainScan->ReadFile("${outputDir}/raw/sslscan-${socket}.txt"); + my @ciphers=$MainScan->ReadFile("${outputDir}/raw/sslscan-${port}.txt"); my ($pref,$weak,$two,$badpref,$null,$prefnull)=(0,0,0,0,0,0); for my $cipher (@ciphers){ if ($cipher =~ /Prefered Server Cipher/){ @@ -228,6 +230,42 @@ sub activate { } else { $Log->Status("GSM thread $threadID ($name -> $target): Already checked SSL ciphers - skipping","LOGONLY"); } + + if (-x "/opt/neet/pkg/testssl/testssl.sh" && !$self->IsScanComplete("${name}_testssl-$port",$target)){ + $MainScan->System("/opt/neet/pkg/testssl/testssl.sh" . " $socket > ${outputDir}/raw/testssl-${port}.txt 2>&1"); + if (-f "${outputDir}/raw/testssl-${port}.txt"){ + my @output=$MainScan->ReadFile("${outputDir}/raw/testssl-${port}.txt"); + for my $line (@output){ + if ($line =~ /CRIME/ && $line =~ /is vulnerable/){ + my $message="SSL service vulnerable to CRIME"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-7",$message); + next; + } + if ($line =~ /BREACH/ && $line =~ /is vulnerable/){ + my $message="SSL service vulnerable to BREACH"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-8",$message); + next; + } + if ($line =~ /Heartbleed/ && $line !~ /\(ok\)/){ + my $message="SSL service vulnerable to Heartbleed"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-9",$message); + next; + } + if ($line =~ /\sCCS\s/ && $line =~ /VULNERABLE/){ + my $message="SSL service vulnerable to Change Cipher Spec"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-10",$message); + next; + } + if ($line =~ /SSLv2/ && $line !~ /\(ok\)/){ + my $message="SSL service supports SSLv2"; + $MainScan->RecordVulnerability($target,"GSM-HTTPS-11",$message); + next; + } + } + $self->SetScanComplete("${name}_testssl-$port","$target"); + } + } + } # Record what we found on this port @@ -341,6 +379,55 @@ sub activate { } } + # Run DIRB + my $dirb=$MainScan->getPath("dirb"); + if ($dirb && -x "$dirb" && !$self->IsScanComplete("${name}_dirb-$port",$target)){ + my $url="http://$socket"; + if ("$file" eq "https.txt"){ + $url =~ s/http/https/; + } + + my @wordlists=$Config->GetClassValues("module.http.dirb.wordlist"); + # Use the default wordlist unlist the user has specified others in the configuraation + # file + if ($#wordlists<0){ + $Log->Warn("DIRB: No wordlists configured (add module.http.dirb.wordlist in neet config). Using default list."); + @wordlists=($defaultDirbList); + } + + # Run dirb using each list + for my $wrdlist (@wordlists){ + $wrdlist =~ s/\.\.//g; + $wrdlist =~ s/"//g; + $wrdlist =~ s?^NEET/?/opt/neet/resources/dirb/?; + if (! -f $wrdlist){ + $Log->Warn("DIRB: wordlist \"$wrdlist\" not found!"); + next; + } + $MainScan->System("$dirb $url \"$wrdlist\" -w -S >> ${outputDir}/raw/dirb-${port}.txt 2>&1"); + } + + # Did we get any results? + my ($list,$count)=(0,0); + if (-f "${outputDir}/raw/dirb-${port}.txt"){ + for my $line ($MainScan->ReadFile("${outputDir}/raw/dirb-${port}.txt")){ + if (index($line,"+ http")>-1){ + $count++; + } elsif (index($line,"IS LISTABLE.")>-1){ + $list++; + } + } + } + if ($list){ + my $message="At least $list listable directories under $url. Check DIRB output."; + $MainScan->RecordIssue($target,"GSM-HTTP-6",$message); + } + if ($count>1){ + my $message="$count interesting URLS at $url. Check DIRB output."; + $MainScan->RecordIssue($target,"GSM-HTTP-7",$message); + } + $self->SetScanComplete("${name}_dirb-$port","$target"); + } #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> diff --git a/content/SMTP/SMTP.gsm b/content/SMTP/SMTP.gsm index fde0ad6..def3d1b 100644 --- a/content/SMTP/SMTP.gsm +++ b/content/SMTP/SMTP.gsm @@ -114,20 +114,20 @@ sub activate { }; alarm ($timeout); eval { - print "Sending: $message" if ($DEBUG); - print $sock ("$message"); - $response=<$sock>; - print "Response: $response" if ($DEBUG); + print "Sending: $message" if ($DEBUG); + print $sock ("$message"); + $response=<$sock>; + print "Response: $response" if ($DEBUG); alarm 0; }; if ("$@" !~ /^TIMEOUT/){ $SIG{'ALRM'}=''; - if ($response =~ /^\d{3}\s/){ - ($code,$response) = split(" ", $response,2); - print "Code: $code Message: $response" if ($DEBUG); + if ($response && $response =~ /^\d{3}\s/){ + ($code,$response) = split(" ", $response,2); + print "Code: $code Message: $response" if ($DEBUG); return ($code,$response); - } + } } else { $SIG{'ALRM'}=''; return (0,0); @@ -168,10 +168,10 @@ sub activate { $smtpUser .= "@" . $domain; } ($code,$response)= SMTP($sock,"VRFY $smtpUser\r\n"); - if ($code =~ /^5/){ + if (defined($code) && $code =~ /^5/){ $skip=1; last; - } elsif ($code =~ /^25\d/ && $response !~ /Cannot VRFY /i){ + } elsif ((defined($code) && defined($response)) && $code =~ /^25\d/ && $response !~ /Cannot VRFY /i){ if ("$user" eq "$randomString"){ $FalsePositive=1; last; @@ -197,10 +197,10 @@ sub activate { $smtpUser .= "@" . $domain; } ($code,$response)= SMTP($sock,"EXPN $smtpUser\r\n"); - if ($code =~ /^5/){ + if (defined($code) && $code =~ /^5/){ $skip=1; last; - } elsif ($code =~ /^25\d/ && $response !~ /Cannot EXPN /i){ + } elsif ((defined($code) && defined($response)) && $code =~ /^25\d/ && $response !~ /Cannot EXPN /i){ if ("$user" eq "$randomString"){ $FalsePositive=1; last; @@ -236,7 +236,7 @@ sub activate { ); if ($sock){ ($code,$response)= SMTP($sock,""); - if ($code){ + if ($code && $response){ for my $element (split " ", $response){ if (($element =~ /\./) && ($element !~ /SMTP/)){ chomp $element; @@ -257,7 +257,7 @@ sub activate { $smtpUser .= "@" . $domain; } ($code,$response)= SMTP($sock,"EXPN $smtpUser\r\n"); - if ($code =~ /^25\d/ && $response !~ /Cannot /i){ + if ((defined($code) && defined($response)) && $code =~ /^25\d/ && $response !~ /Cannot /i){ push @validUsers, $user; } } @@ -294,12 +294,12 @@ sub activate { for my $user (@testUsers){ my $smtpUser=$user; if ($expnUseDomain){ - $smtpUser .= "@" . $domain; + $smtpUser .= "@" . $domain; } ($code,$response)= SMTP($sock,"VRFY $smtpUser\r\n"); - if ($code =~ /^25\d/ && $response !~ /Cannot /i){ - push @validUsers, $user; - } + if (($code && $response) && $code =~ /^25\d/ && $response !~ /Cannot /i){ + push @validUsers, $user; + } } close $sock; } diff --git a/content/SSH/SSH.gsm b/content/SSH/SSH.gsm index 9af50bc..7be56c1 100644 --- a/content/SSH/SSH.gsm +++ b/content/SSH/SSH.gsm @@ -163,17 +163,9 @@ sub activate { }; # And now the code for the actual test: - - # This check is now incorporated in the service discovery module - # Get the banner: See if we're supporting protocol 1 - #my @banner=$MainScan->ReadFile("$outputDir/banners/${port}.txt"); - #for my $line (@banner){ - # chomp $line; - # if (index($line,"SSH-1.")==0){ - # $MainScan->ConfigError($host, "issue", "SSHProto", "Host supports SSH protocol 1.x"); - # last; - # } - #} + # Do we run against Windows machines as well? 1=YES, 0=NO (Only Unix machines) + # CAUTION: This can cause account lockout!! + my $RunAgainstWindows=1; my ($osDetermined,$unix)=(0,0); # Do we know the OS, and is the target running Unix? @@ -190,18 +182,18 @@ sub activate { if ($osDetermined){ # Don't run anything if we don't know the OS - my $patator=$MainScan->getPath("patator.py"); - my $output="$outputDir/raw/patator-$port.txt"; - if ($patator && $unix){ + my $medusa=$MainScan->getPath("medusa"); + my $output="$outputDir/raw/medusa-$port.txt"; + if ($medusa && ($unix || $RunAgainstWindows)){ my ($username,$password)=('root',""); - $MainScan->System("$patator ssh_login port=$port host=$host user=$username password=FILE0 0=$resourceDir/passwords.txt persistent=1 -x ignore:mesg='Authentication failed.' -x ignore,reset,retry:mesg='No existing session' -x quit:code=0 > $output 2>&1"); + $MainScan->System("$medusa -h $host -u $username -P \"$resourceDir/passwords.txt\" -e ns -f -n $port -M ssh > $output 2>&1"); @file=$MainScan->ReadFile($output); for my $line (@file){ - if (($line =~ /SSH/) && ($line !~ /Error/)){ + if (($line =~ /ACCOUNT FOUND: \[ssh\]/)){ # Logged in $password=$line; - $password =~ s/^[\S\s]+\s+\|\s+([\S\s]+)\|[\S\s]+\|[\S\s]+$/$1/; - $password =~ s/\s+$//g; + $password =~ s/^ACCOUNT FOUND: \[ssh\] Host: $host User: $username Password: ([\S\s]+) \[SUCCESS\]\s+$/$1/; + #$password =~ s/\s+$//g; #$MainScan->StoreGuessedPassword($target,"comp","SSH",$username,$password,"GSM-SSH-1","Logged in as $username password $password"); # Instead of storing it in a flat file, use the credential manager $credentialManager->addCredential( @@ -218,6 +210,7 @@ sub activate { } } } + $self->SetScanComplete("$name","$target"); } } else { diff --git a/content/SSH/passwords.txt b/content/SSH/passwords.txt index b0f371e..3159528 100644 --- a/content/SSH/passwords.txt +++ b/content/SSH/passwords.txt @@ -1,4 +1,8 @@ - +welcome1 +Welcome1 +Welcome1! +welcome1! +WELCOME1 toor root Root diff --git a/content/SSL/SSL.gsm b/content/SSL/SSL.gsm index 029c843..5ea2356 100644 --- a/content/SSL/SSL.gsm +++ b/content/SSL/SSL.gsm @@ -163,58 +163,87 @@ sub activate { # And now the code for the actual test: - my $sslscan=$MainScan->getPath("sslscan"); - return 0 if (!$sslscan); - my $error=$MainScan->System("$sslscan $socket > ${outputDir}/raw/sslscan-${socket}.txt 2>&1"); - if (!$error){ - my @ciphers=$MainScan->ReadFile("${outputDir}/raw/sslscan-${socket}.txt"); - my ($pref,$weak,$two,$badpref,$null,$prefnull)=(0,0,0,0,0,0); - for my $cipher (@ciphers){ - if ($cipher =~ /Prefered Server Cipher/){ - $pref=1; next; + # First of all, double check this isn't HTTPS. If it is, we'll let that module deal with it. + # Sometimes HTTPS isn't detected at an earlier stage, and ends up just being categorised "SSL". + my $wget=$MainScan->getPath("wget"); + if ($wget){ + my $error=$MainScan->System("$wget https://$socket/ --no-check-certificate -q " . + "-O ${outputDir}/raw/sslwgetcheck-${port}.txt >/dev/null 2>&1"); + if (!$error){ + # This is HTTPS. Record that.... + my $confirmed="${outputDir}/confirmedtcpports.txt"; + $MainScan->SetStatValue("$confirmed",$port,"HTTPS [By SSL GSM/WGET]"); + + # List the service in the appropriate protocol file + my $_outfile=$MainScan->ResultsDirectory . "/services/https.txt"; + my $string="${host}:${protocol}/$port"; + if (!$MainScan->GetStatKey("$_outfile","${host}:${protocol}/$port")){ + $MainScan->SetStatKey("$_outfile","$string") } - if ($pref){ - if ($cipher =~ /(NULL)/){ - $prefnull=1; next; + + # Move the wget output to the banners directory + $MainScan->System("mv ${outputDir}/raw/sslwgetcheck-${port}.txt ${outputDir}/banners/${port}.txt"); + + # Our work here is done + $self->SetScanComplete("$name","$target"); + return 0; + } + } + + # Not HTTPS. Carry on. + my $sslscan=$MainScan->getPath("sslscan"); + if ($sslscan){ + my $error=$MainScan->System("$sslscan $socket > ${outputDir}/raw/sslscan-${port}.txt 2>&1"); + if (!$error){ + my @ciphers=$MainScan->ReadFile("${outputDir}/raw/sslscan-${port}.txt"); + my ($pref,$weak,$two,$badpref,$null,$prefnull)=(0,0,0,0,0,0); + for my $cipher (@ciphers){ + if ($cipher =~ /Prefered Server Cipher/){ + $pref=1; next; + } + if ($pref){ + if ($cipher =~ /(NULL)/){ + $prefnull=1; next; + } + if ($cipher =~ /(\s56 bits)|(\s40 bits)/){ + $badpref=1; + } + } + if (($cipher =~ /Accepted/) && ($cipher =~ /(NULL)|(\s0 bits)/)){ + $null=1; next; + } + if (($cipher =~ /Accepted/) && ($cipher =~ /(\s40 bits)|(\s56 bits)/)){ + $weak=1; next; } - if ($cipher =~ /(\s56 bits)|(\s40 bits)/){ - $badpref=1; + if (($cipher =~ /Accepted/) && ($cipher =~ /SSLv2/)){ + $two=1; next; } } - if (($cipher =~ /Accepted/) && ($cipher =~ /(NULL)|(\s0 bits)/)){ - $null=1; next; + if ($weak && $null){ + my $message="SSL service supports short keys and NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-SSL-1",$message); + } elsif ($weak){ + my $message="SSL service supports short keys"; + $MainScan->RecordIssue($target,"GSM-SSL-2",$message); + } elsif ($null){ + my $message="SSL service supports NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-SSL-3",$message); } - if (($cipher =~ /Accepted/) && ($cipher =~ /(\s40 bits)|(\s56 bits)/)){ - $weak=1; next; + if ($two){ + my $message="SSL service supports SSL protocol v2"; + $MainScan->RecordVulnerability($target,"GSM-SSL-4",$message); } - if (($cipher =~ /Accepted/) && ($cipher =~ /SSLv2/)){ - $two=1; next; + if ($prefnull){ + my $message="SSL service negotiates NULL ciphers"; + $MainScan->RecordVulnerability($target,"GSM-SSL-5",$message); + } elsif ($badpref){ + my $message="SSL service negotiates insecure cipher suites"; + $MainScan->RecordVulnerability($target,"GSM-SSL-6",$message); } + } else { + $Log->Error("GSM thread $threadID ($name -> $target): Couldn't check SSL ciphers - error $error"); } - if ($weak && $null){ - my $message="SSL service supports short keys and NULL ciphers"; - $MainScan->RecordVulnerability($target,"GSM-SSL-1",$message); - } elsif ($weak){ - my $message="SSL service supports short keys"; - $MainScan->RecordIssue($target,"GSM-SSL-2",$message); - } elsif ($null){ - my $message="SSL service supports NULL ciphers"; - $MainScan->RecordVulnerability($target,"GSM-SSL-3",$message); - } - if ($two){ - my $message="SSL service supports SSL protocol v2"; - $MainScan->RecordVulnerability($target,"GSM-SSL-4",$message); - } - if ($prefnull){ - my $message="SSL service negotiates NULL ciphers"; - $MainScan->RecordVulnerability($target,"GSM-SSL-5",$message); - } elsif ($badpref){ - my $message="SSL service negotiates insecure cipher suites"; - $MainScan->RecordVulnerability($target,"GSM-SSL-6",$message); - } - } else { - $Log->Error("GSM thread $threadID ($name -> $target): Couldn't check SSL ciphers - error $error"); - } + } my $openssl=$MainScan->getPath("openssl"); my $vhost=""; @@ -256,6 +285,43 @@ sub activate { $MainScan->RecordIssue($target,"GSM-SSL-7",$message); } + if (-x "/opt/neet/pkg/testssl/testssl.sh" && !$self->IsScanComplete("${name}_testssl-$port",$target)){ + $MainScan->System("/opt/neet/pkg/testssl/testssl.sh" . " $socket > ${outputDir}/raw/testssl-${port}.txt 2>&1"); + if (-f "${outputDir}/raw/testssl-${port}.txt"){ + my @output=$MainScan->ReadFile("${outputDir}/raw/testssl-${port}.txt"); + for my $line (@output){ + if ($line =~ /CRIME/ && $line =~ /is vulnerable/){ + my $message="SSL service vulnerable to CRIME"; + $MainScan->RecordVulnerability($target,"GSM-SSL-8",$message); + next; + } + if ($line =~ /BREACH/ && $line =~ /is vulnerable/){ + my $message="SSL service vulnerable to BREACH"; + $MainScan->RecordVulnerability($target,"GSM-SSL-9",$message); + next; + } + if ($line =~ /Heartbleed/ && $line !~ /\(ok\)/){ + my $message="SSL service vulnerable to Heartbleed"; + $MainScan->RecordVulnerability($target,"GSM-SSL-10",$message); + next; + } + if ($line =~ /\sCCS\s/ && $line =~ /VULNERABLE/){ + my $message="SSL service vulnerable to Change Cipher Spec"; + $MainScan->RecordVulnerability($target,"GSM-SSL-11",$message); + next; + } + if ($line =~ /SSLv2/ && $line !~ /\(ok\)/){ + my $message="SSL service supports SSLv2"; + $MainScan->RecordVulnerability($target,"GSM-SSL-12",$message); + next; + } + } + + + + $self->SetScanComplete("${name}_testssl-$port","$target"); + } + } #>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> #>>>>>>>>>>>>> End of module-specific code >>>>>>>>>>>>>> diff --git a/content/Topology/Topology.gsm b/content/Topology/Topology.gsm index 7dea734..c668022 100644 --- a/content/Topology/Topology.gsm +++ b/content/Topology/Topology.gsm @@ -173,8 +173,8 @@ sub activate { } } else { # Traceroute, ping -R, tcptraceroute and Forwarding checks - $MainScan->System($MainScan->getPath("traceroute") . " -I -m 20 -n -w 3 $host > ${outputDir}/topology/iCMPtraceroute.txt 2>&1"); - $MainScan->System($MainScan->getPath("traceroute") . " -m 20 -n -w 3 $host > ${outputDir}/topology/uDPtraceroute.txt 2>&1"); + $MainScan->System($MainScan->getPath("traceroute") . " -I -m 20 -w 3 $host > ${outputDir}/topology/iCMPtraceroute.txt 2>&1"); + $MainScan->System($MainScan->getPath("traceroute") . " -m 20 -w 3 $host > ${outputDir}/topology/uDPtraceroute.txt 2>&1"); $MainScan->System($MainScan->getPath("tcptraceroute") . " $host 80 > ${outputDir}/topology/tCPtraceroute.txt 2>&1"); $MainScan->System("ping -R -c1 -n $host > ${outputDir}/topology/ping-R.txt 2>&1"); } diff --git a/content/UnixVA/UnixVA.gsm b/content/UnixVA/UnixVA.gsm index cdd29d7..274d532 100644 --- a/content/UnixVA/UnixVA.gsm +++ b/content/UnixVA/UnixVA.gsm @@ -224,7 +224,7 @@ sub activate { $_vuln=1; } - if ($rc == 99){ + if ($rc && $rc == 99){ $Log->Warn("GSM thread $threadID ($name -> $target): $cname timed out","LOGONLY"); } else { if ($_vuln){ diff --git a/content/VERSION b/content/VERSION index e25d8d9..0664a8f 100644 --- a/content/VERSION +++ b/content/VERSION @@ -1 +1 @@ -1.1.5 +1.1.6