final touches and specs

add finishing touches to postgres
Loginscanner and add specs to cover
the behaviour
bug/bundler_fix
David Maloney 2014-05-07 18:32:36 -05:00
parent 507fe566a4
commit e025fa1791
No known key found for this signature in database
GPG Key ID: DEDBA9DC3A913DB2
2 changed files with 149 additions and 0 deletions

View File

@ -0,0 +1,71 @@
require 'metasploit/framework/login_scanner/base'
require 'postgres_msf'
module Metasploit
module Framework
module LoginScanner
# This is the LoginScanner class for dealing with PostgreSQL database servers.
# It is responsible for taking a single target, and a list of credentials
# and attempting them. It then saves the results.
class Postgres
include Metasploit::Framework::LoginScanner::Base
# This method attempts a single login with a single credential against the target
# @param credential [Credential] The credential object to attmpt to login with
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
def attempt_login(credential)
result_options = {
credential: credential
}
db_name = credential.realm || 'template1'
if ::Rex::Socket.is_ipv6?(host)
uri = "tcp://[#{host}]:#{port}"
else
uri = "tcp://#{host}:#{port}"
end
pg_conn = nil
begin
pg_conn = Msf::Db::PostgresPR::Connection.new(db_name,credential.public,credential.private,uri)
rescue RuntimeError => e
case e.to_s.split("\t")[1]
when "C3D000"
result_options.merge!({
status: :failed,
proof: "C3D000, Creds were good but database was bad"
})
when "C28000", "C28P01"
result_options.merge!({
status: :failed,
proof: "Invalid username or password"
})
else
result_options.merge!({
status: :failed,
proof: e.message
})
end
end
if pg_conn
pg_conn.close
result_options[:status] = :success
else
result_options[:status] = :failed
end
::Metasploit::Framework::LoginScanner::Result.new(result_options)
end
end
end
end
end

View File

@ -0,0 +1,78 @@
require 'spec_helper'
require 'metasploit/framework/login_scanner/postgres'
describe Metasploit::Framework::LoginScanner::Postgres do
let(:public) { 'root' }
let(:private) { 'toor' }
let(:realm) { 'template1' }
let(:full_cred) {
Metasploit::Framework::LoginScanner::Credential.new(
paired: true,
public: public,
private: private,
realm: realm
)
}
let(:cred_no_realm) {
Metasploit::Framework::LoginScanner::Credential.new(
paired: true,
public: public,
private: private
)
}
subject(:login_scanner) { described_class.new }
it_behaves_like 'Metasploit::Framework::LoginScanner::Base'
context '#attempt_login' do
context 'when the login is successful' do
it 'returns a result object with a status of success' do
fake_conn = "fake_connection"
Msf::Db::PostgresPR::Connection.should_receive(:new).and_return fake_conn
fake_conn.should_receive(:close)
expect(login_scanner.attempt_login(full_cred).status).to eq :success
end
end
context 'when there is no realm on the credential' do
it 'uses template1 as the default realm' do
Msf::Db::PostgresPR::Connection.should_receive(:new).with('template1', 'root', 'toor', 'tcp://:')
login_scanner.attempt_login(cred_no_realm)
end
end
context 'when the realm is invalid but the rest of the credential is not' do
it 'includes the details in the result proof' do
Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "blah\tC3D000"
result = login_scanner.attempt_login(cred_no_realm)
expect(result.status).to eq :failed
expect(result.proof).to eq "C3D000, Creds were good but database was bad"
end
end
context 'when the username or password is invalid' do
it 'includes a message in proof, indicating why it failed' do
Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "blah\tC28000"
result = login_scanner.attempt_login(cred_no_realm)
expect(result.status).to eq :failed
expect(result.proof).to eq "Invalid username or password"
end
end
context 'when any other type of error occurs' do
it 'returns a failure with the error message in the proof' do
Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "unknown error"
result = login_scanner.attempt_login(cred_no_realm)
expect(result.status).to eq :failed
expect(result.proof).to eq "unknown error"
end
end
end
end