final touches and specs
add finishing touches to postgres Loginscanner and add specs to cover the behaviourbug/bundler_fix
parent
507fe566a4
commit
e025fa1791
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue