diff --git a/lib/metasploit/framework/login_scanner/postgres.rb b/lib/metasploit/framework/login_scanner/postgres.rb index 91eeb144bf..93b2024aaa 100644 --- a/lib/metasploit/framework/login_scanner/postgres.rb +++ b/lib/metasploit/framework/login_scanner/postgres.rb @@ -62,6 +62,11 @@ module Metasploit end rescue Rex::ConnectionError, EOFError, Timeout::Error => e result_options.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e) + rescue Msf::Db::PostgresPR::AuthenticationMethodMismatch => e + result_options.merge!({ + status: Metasploit::Model::Login::Status::INCORRECT, + proof: e.message + }) end if pg_conn diff --git a/lib/postgres/postgres-pr/connection.rb b/lib/postgres/postgres-pr/connection.rb index c18b0caff9..f8288a747a 100644 --- a/lib/postgres/postgres-pr/connection.rb +++ b/lib/postgres/postgres-pr/connection.rb @@ -19,6 +19,9 @@ module PostgresPR PROTO_VERSION = 3 << 16 #196608 +class AuthenticationMethodMismatch < StandardError +end + class Connection # Allow easy access to these instance variables @@ -58,7 +61,10 @@ class Connection @transaction_status = nil @params = {} establish_connection(uri) - + + # Check if the password supplied is a Postgres-style md5 hash + md5_hash_match = password.match(/md5([a-f0-9]{32})/) + @conn << StartupMessage.new(PROTO_VERSION, 'user' => user, 'database' => database).dump loop do @@ -67,19 +73,24 @@ class Connection case msg when AuthentificationClearTextPassword raise ArgumentError, "no password specified" if password.nil? + raise AuthenticationMethodMismatch, "Server expected clear text password auth" if md5_hash_match @conn << PasswordMessage.new(password).dump - when AuthentificationCryptPassword raise ArgumentError, "no password specified" if password.nil? + raise AuthenticationMethodMismatch, "Server expected crypt password auth" if md5_hash_match @conn << PasswordMessage.new(password.crypt(msg.salt)).dump - when AuthentificationMD5Password raise ArgumentError, "no password specified" if password.nil? require 'digest/md5' - m = Digest::MD5.hexdigest(password + user) + if md5_hash_match + m = md5_hash_match[1] + else + m = Digest::MD5.hexdigest(password + user) + end m = Digest::MD5.hexdigest(m + msg.salt) m = 'md5' + m + @conn << PasswordMessage.new(m).dump when AuthentificationKerberosV4, AuthentificationKerberosV5, AuthentificationSCMCredential