Merge branch 'staging/electro-release' into feature/MSP-9739/mremote_refactor

bug/bundler_fix
David Maloney 2014-05-30 13:28:11 -05:00
commit 5757c95fcb
No known key found for this signature in database
GPG Key ID: DEDBA9DC3A913DB2
5 changed files with 48 additions and 1561 deletions

View File

@ -27,7 +27,7 @@ group :db do
# Needed for Msf::DbManager
gem 'activerecord', '>= 3.0.0', '< 4.0.0'
# Metasploit::Creential database models
gem 'metasploit-credential', git: 'github-metasploit-credential:rapid7/metasploit-credential.git', tag: 'v0.1.2-metasploit-credential'
gem 'metasploit-credential', git: 'github-metasploit-credential:rapid7/metasploit-credential.git', tag: 'v0.1.8-metasploit-credential'
# Database models shared between framework and Pro.
gem 'metasploit_data_models', '~> 0.17.1'
# Needed for module caching in Mdm::ModuleDetails

View File

@ -1,9 +1,9 @@
GIT
remote: github-metasploit-credential:rapid7/metasploit-credential.git
revision: 2f8384cd5f7d0124e276a6e4b7fa8193dd96f56c
tag: v0.1.2-metasploit-credential
revision: 2be17e6327b4a5caa9a22ffc0b064923a25a222c
tag: v0.1.8-metasploit-credential
specs:
metasploit-credential (0.1.2.pre.metasploit.pre.credential)
metasploit-credential (0.1.8.pre.electro.pre.release)
metasploit-concern (~> 0.0.4)
metasploit_data_models (~> 0.17.0)
rubyntlm

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
require 'metasploit/credential/creation'
# -*- coding: binary -*-
module Msf
@ -9,345 +10,13 @@ module Msf
module Auxiliary::Report
# This method is responsible for creation {Metasploit::Credential::Core} objects
# and all sub-objects that it is dependent upon.
#
# @option opts [Symbol] :origin_type The Origin type we are trying to create
# @option opts [String] :address The address of the {Mdm::Host} to link this Origin to
# @option opts [Fixnum] :port The port number of the {Mdm::Service} to link this Origin to
# @option opts [String] :service_name The service name to use for the {Mdm::Service}
# @option opts [String] :protocol The protocol type of the {Mdm::Service} to link this Origin to
# @option opts [String] :module_fullname The fullname of the Metasploit Module to link this Origin to
# @option opts [Fixnum] :workspace_id The ID of the {Mdm::Workspace} to use for the {Mdm::Host}
# @option opts [Fixnum] :task_id The ID of the {Mdm::Task} to link this Origin to
# @option opts [String] :filename The filename of the file that was imported
# @option opts [Fixnum] :user_id The ID of the {Mdm::User} to link this Origin to
# @option opts [Fixnum] :session_id The ID of the {Mdm::Session} to link this Origin to
# @option opts [String] :post_reference_name The reference name of the Metasploit Post module to link the origin to
# @option opts [String] :private_data The actual data for the private (e.g. password, hash, key etc)
# @option opts [Symbol] :private_type The type of {Metasploit::Credential::Private} to create
# @option opts [String] :username The username to use for the {Metasploit::Credential::Public}
# @raise [KeyError] if a required option is missing
# @raise [ArgumentError] if an invalid :private_type is specified
# @raise [ArgumentError] if an invalid :origin_type is specified
# @return [NilClass] if there is no active database connection
# @return [Metasploit::Credential::Core]
# @example Reporting a Bruteforced Credential
# create_credential(
# origin_type: :service,
# address: '192.168.1.100',
# port: 445,
# service_name: 'smb',
# protocol: 'tcp',
# module_fullname: 'auxiliary/scanner/smb/smb_login',
# workspace_id: myworkspace.id,
# private_data: 'password1',
# private_type: :password,
# username: 'Administrator'
# )
def create_credential(opts={})
return nil unless framework.db.active
origin = create_credential_origin(opts)
include Metasploit::Credential::Creation
core_opts = {
origin: origin,
workspace_id: opts.fetch(:workspace_id)
}
if opts.has_key?(:realm_key) && opts.has_key?(:realm_value)
core_opts[:realm] = create_credential_realm(opts)
end
if opts.has_key?(:private_type) && opts.has_key?(:private_data)
core_opts[:private] = create_credential_private(opts)
end
if opts.has_key?(:username)
core_opts[:public] = create_credential_public(opts)
end
create_credential_core(core_opts)
# This method overrides the method from Metasploit::Credential to check for an active db
def active_db?
framework.db.active
end
# This method is responsible for creating {Metasploit::Credential::Core} objects.
#
# @option opts [Metasploit::Credential::Origin] :origin The origin object to tie the core to
# @option opts [Metasploit::Credential::Public] :public The {Metasploit::Credential::Public} component
# @option opts [Metasploit::Credential::Private] :private The {Metasploit::Credential::Private} component
# @option opts [Fixnum] :workspace_id The ID of the {Mdm::Workspace} to tie the Core to
# @return [NilClass] if there is no active database connection
# @return [Metasploit::Credential::Core]
def create_credential_core(opts={})
return nil unless framework.db.active
origin = opts.fetch(:origin)
workspace_id = opts.fetch(:workspace_id)
if opts[:private]
private_id = opts[:private].id
else
private_id = nil
end
if opts[:public]
public_id = opts[:public].id
else
public_id = nil
end
if opts[:realm]
realm_id = opts[:realm].id
else
realm_id = nil
end
core = Metasploit::Credential::Core.where(private_id: private_id, public_id: public_id, realm_id: realm_id, workspace_id: workspace_id).first_or_create
if core.origin_id.nil?
core.origin = origin
end
core.save!
core
end
# This method is responsible for creating a {Metasploit::Credential::Login} object
# which ties a {Metasploit::Credential::Core} to the {Mdm::Service} it is a valid
# credential for.
#
# @option opts [String] :access_level The access level to assign to this login if we know it
# @option opts [String] :address The address of the {Mdm::Host} to link this Login to
# @option opts [DateTime] :last_attempted_at The last time this Login was attempted
# @option opts [Metasploit::Credential::Core] :core The {Metasploit::Credential::Core} to link this login to
# @option opts [Fixnum] :port The port number of the {Mdm::Service} to link this Login to
# @option opts [String] :service_name The service name to use for the {Mdm::Service}
# @option opts [String] :status The status for the Login object
# @option opts [String] :protocol The protocol type of the {Mdm::Service} to link this Login to
# @option opts [Fixnum] :workspace_id The ID of the {Mdm::Workspace} to use for the {Mdm::Host}
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no active database connection
# @return [Metasploit::Credential::Login]
def create_credential_login(opts)
return nil unless framework.db.active
access_level = opts.fetch(:access_level, nil)
core = opts.fetch(:core)
last_attempted_at = opts.fetch(:last_attempted_at, nil)
status = opts.fetch(:status)
service_object = create_credential_service(opts)
login_object = Metasploit::Credential::Login.where(core_id: core.id, service_id: service_object.id).first_or_create
login_object.access_level = access_level if access_level
login_object.last_attempted_at = last_attempted_at if last_attempted_at
login_object.status = status
login_object.save!
login_object
end
# This method is responsible for the creation of {Metasploit::Credential::Private} objects.
# It will create the correct subclass based on the type.
#
# @option opts [String] :private_data The actual data for the private (e.g. password, hash, key etc)
# @option opts [Symbol] :private_type The type of {Metasploit::Credential::Private} to create
# @raise [ArgumentError] if a valid type is not supplied
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no active database connection
# @return [Metasploit::Credential::Password] if the private_type was :password
# @return [Metasploit::Credential::SSHKey] if the private_type was :ssh_key
# @return [Metasploit::Credential::NTLMHash] if the private_type was :ntlm_hash
# @return [Metasploit::Credential::NonreplayableHash] if the private_type was :nonreplayable_hash
def create_credential_private(opts={})
return nil unless framework.db.active
private_data = opts.fetch(:private_data)
private_type = opts.fetch(:private_type)
case private_type
when :password
private_object = Metasploit::Credential::Password.where(data: private_data).first_or_create
when :ssh_key
private_object = Metasploit::Credential::SSHKey.where(data: private_data).first_or_create
when :ntlm_hash
private_object = Metasploit::Credential::NTLMHash.where(data: private_data).first_or_create
when :nonreplayable_hash
private_object = Metasploit::Credential::NonreplayableHash.where(data: private_data).first_or_create
else
raise ArgumentError, "Invalid Private type: #{private_type}"
end
private_object.save!
private_object
end
# This method is responsible for the creation of {Metasploit::Credential::Public} objects.
#
# @option opts [String] :username The username to use for the {Metasploit::Credential::Public}
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no active database connection
# @return [Metasploit::Credential::Public]
def create_credential_public(opts={})
return nil unless framework.db.active
username = opts.fetch(:username)
public_object = Metasploit::Credential::Public.where(username: username).first_or_create
public_object.save!
public_object
end
# This method is responsible for creating the {Metasploit::Credential::Realm} objects
# that may be required.
#
# @option opts [String] :realm_key The type of Realm this is (e.g. 'Active Directory Domain')
# @option opts [String] :realm_value The actual Realm name (e.g. contosso)
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no active database connection
# @return [Metasploit::Credential::Realm] if it successfully creates or finds the object
def create_credential_realm(opts={})
return nil unless framework.db.active
realm_key = opts.fetch(:realm_key)
realm_value = opts.fetch(:realm_value)
realm_object = Metasploit::Credential::Realm.where(key: realm_key, value: realm_value).first_or_create
realm_object.save!
realm_object
end
# This method is responsible for creating the various Credential::Origin objects.
# It takes a key for the Origin type and delegates to the correct sub-method.
#
# @option opts [Symbol] :origin_type The Origin type we are trying to create
# @option opts [String] :address The address of the {Mdm::Host} to link this Origin to
# @option opts [Fixnum] :port The port number of the {Mdm::Service} to link this Origin to
# @option opts [String] :service_name The service name to use for the {Mdm::Service}
# @option opts [String] :protocol The protocol type of the {Mdm::Service} to link this Origin to
# @option opts [String] :module_fullname The fullname of the Metasploit Module to link this Origin to
# @option opts [Fixnum] :workspace_id The ID of the {Mdm::Workspace} to use for the {Mdm::Host}
# @option opts [Fixnum] :task_id The ID of the {Mdm::Task} to link this Origin to
# @option opts [String] :filename The filename of the file that was imported
# @option opts [Fixnum] :user_id The ID of the {Mdm::User} to link this Origin to
# @option opts [Fixnum] :session_id The ID of the {Mdm::Session} to link this Origin to
# @option opts [String] :post_reference_name The reference name of the Metasploit Post module to link the origin to
# @raise [ArgumentError] if an invalid origin_type was provided
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no connected database
# @return [Metasploit::Credential::Origin::Manual] if :origin_type was :manual
# @return [Metasploit::Credential::Origin::Import] if :origin_type was :import
# @return [Metasploit::Credential::Origin::Service] if :origin_type was :service
# @return [Metasploit::Credential::Origin::Session] if :origin_type was :session
def create_credential_origin(opts={})
return nil unless framework.db.active
case opts[:origin_type]
when :import
create_credential_origin_import(opts)
when :manual
create_credential_origin_manual(opts)
when :service
create_credential_origin_service(opts)
when :session
create_credential_origin_session(opts)
else
raise ArgumentError, "Unknown Origin Type #{opts[:origin_type]}"
end
end
# This method is responsible for creating {Metasploit::Credential::Origin::Import} objects.
#
# @option opts [Fixnum] :task_id The ID of the {Mdm::Task} to link this Origin to
# @option opts [String] :filename The filename of the file that was imported
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no connected database
# @return [Metasploit::Credential::Origin::Manual] The created {Metasploit::Credential::Origin::Import} object
def create_credential_origin_import(opts={})
return nil unless framework.db.active
task_id = opts.fetch(:task_id)
filename = opts.fetch(:filename)
origin_object = Metasploit::Credential::Origin::Import.where(filename: filename, task_id: task_id).first_or_create
origin_object.save!
origin_object
end
# This method is responsible for creating {Metasploit::Credential::Origin::Manual} objects.
#
# @option opts [Fixnum] :user_id The ID of the {Mdm::User} to link this Origin to
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no connected database
# @return [Metasploit::Credential::Origin::Manual] The created {Metasploit::Credential::Origin::Manual} object
def create_credential_origin_manual(opts={})
return nil unless framework.db.active
user_id = opts.fetch(:user_id)
origin_object = Metasploit::Credential::Origin::Manual.where(user_id: user_id).first_or_create
origin_object.save!
origin_object
end
# This method is responsible for creating {Metasploit::Credential::Origin::Service} objects.
# If there is not a matching {Mdm::Host} it will create it. If there is not a matching
# {Mdm::Service} it will create that too.
#
# @option opts [String] :address The address of the {Mdm::Host} to link this Origin to
# @option opts [Fixnum] :port The port number of the {Mdm::Service} to link this Origin to
# @option opts [String] :service_name The service name to use for the {Mdm::Service}
# @option opts [String] :protocol The protocol type of the {Mdm::Service} to link this Origin to
# @option opts [String] :module_fullname The fullname of the Metasploit Module to link this Origin to
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no connected database
# @return [Metasploit::Credential::Origin::Service] The created {Metasploit::Credential::Origin::Service} object
def create_credential_origin_service(opts={})
return nil unless framework.db.active
module_fullname = opts.fetch(:module_fullname)
service_object = create_credential_service(opts)
origin_object = Metasploit::Credential::Origin::Service.where(service_id: service_object.id, module_full_name: module_fullname).first_or_create
origin_object.save!
origin_object
end
# This method is responsible for creating {Metasploit::Credential::Origin::Session} objects.
#
# @option opts [Fixnum] :session_id The ID of the {Mdm::Session} to link this Origin to
# @option opts [String] :post_reference_name The reference name of the Metasploit Post module to link the origin to
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no connected database
# @return [Metasploit::Credential::Origin::Session] The created {Metasploit::Credential::Origin::Session} object
def create_credential_origin_session(opts={})
return nil unless framework.db.active
session_id = opts.fetch(:session_id)
post_reference_name = opts.fetch(:post_reference_name)
origin_object = Metasploit::Credential::Origin::Session.where(session_id: session_id, post_reference_name: post_reference_name).first_or_create
origin_object.save!
origin_object
end
# This method is responsible for creating a barebones {Mdm::Service} object
# for use by Credential object creation.
#
# @option opts [String] :address The address of the {Mdm::Host}
# @option opts [Fixnum] :port The port number of the {Mdm::Service}
# @option opts [String] :service_name The service name to use for the {Mdm::Service}
# @option opts [String] :protocol The protocol type of the {Mdm::Service}
# @option opts [Fixnum] :workspace_id The ID of the {Mdm::Workspace} to use for the {Mdm::Host}
# @raise [KeyError] if a required option is missing
# @return [NilClass] if there is no connected database
# @return [Mdm::Service]
def create_credential_service(opts={})
return nil unless framework.db.active
address = opts.fetch(:address)
port = opts.fetch(:port)
service_name = opts.fetch(:service_name)
protocol = opts.fetch(:protocol)
workspace_id = opts.fetch(:workspace_id)
# Find or create the host object we need
host_object = Mdm::Host.where(address: address, workspace_id: workspace_id).first_or_create
host_object.save!
# Next we find or create the Service object we need
service_object = Mdm::Service.where(host_id: host_object.id, port: port, proto: protocol).first_or_create
service_object.name = service_name
service_object.save!
service_object
end
# Shortcut method for detecting when the DB is active
def db
framework.db.active

View File

@ -1,420 +0,0 @@
require 'spec_helper'
require 'msf/core/auxiliary/report'
describe Msf::Auxiliary::Report do
include_context 'Msf::DBManager'
let(:dummy_class) {
Class.new do
include Msf::Auxiliary::Report
attr_accessor :framework
def initialize(framework_instance)
@framework = framework_instance
end
end
}
let(:session) { FactoryGirl.create(:mdm_session) }
let(:task) { FactoryGirl.create(:mdm_task)}
let(:user) { FactoryGirl.create(:mdm_user)}
subject(:test_object) { dummy_class.new(framework) }
context '#create_credential_origin_import' do
it 'creates a Metasploit::Credential::Origin object' do
opts = {
filename: "test_import.xml",
task_id: task.id
}
expect { test_object.create_credential_origin_import(opts)}.to change{Metasploit::Credential::Origin::Import.count}.by(1)
end
it 'should return nil if there is no database connection' do
expect(test_object.framework.db).to receive(:active).and_return(false)
expect(test_object.create_credential_origin_import).to be_nil
end
context 'when called twice with the same options' do
it 'does not create duplicate objects' do
opts = {
filename: "test_import.xml",
task_id: task.id
}
test_object.create_credential_origin_import(opts)
expect { test_object.create_credential_origin_import(opts)}.to_not change{Metasploit::Credential::Origin::Import.count}
end
end
context 'when missing an option' do
it 'throws a KeyError' do
opts = {
filename: "test_import.xml"
}
expect{ test_object.create_credential_origin_import(opts)}.to raise_error KeyError
end
end
end
context '#create_credential_origin_manual' do
it 'creates a Metasploit::Credential::Origin object' do
opts = {
user_id: user.id
}
expect { test_object.create_credential_origin_manual(opts)}.to change{Metasploit::Credential::Origin::Manual.count}.by(1)
end
it 'should return nil if there is no database connection' do
expect(test_object.framework.db).to receive(:active).and_return(false)
expect(test_object.create_credential_origin_manual).to be_nil
end
context 'when called twice with the same options' do
it 'does not create duplicate objects' do
opts = {
user_id: user.id
}
test_object.create_credential_origin_manual(opts)
expect { test_object.create_credential_origin_manual(opts)}.to_not change{Metasploit::Credential::Origin::Manual.count}
end
end
context 'when missing an option' do
it 'throws a KeyError' do
opts = {}
expect{ test_object.create_credential_origin_manual(opts)}.to raise_error KeyError
end
end
end
context '#create_credential_origin_service' do
it 'creates a Metasploit::Credential::Origin object' do
opts = {
address: '192.168.172.3',
port: 445,
service_name: 'smb',
protocol: 'tcp',
module_fullname: 'auxiliary/scanner/smb/smb_login',
workspace_id: framework.db.workspace.id,
origin_type: :service
}
expect { test_object.create_credential_origin_service(opts)}.to change{Metasploit::Credential::Origin::Service.count}.by(1)
end
it 'should return nil if there is no database connection' do
my_module = test_object
expect(my_module.framework.db).to receive(:active).and_return(false)
expect(my_module.create_credential_origin_service).to be_nil
end
context 'when there is a matching host record' do
it 'uses the existing host record' do
opts = {
address: '192.168.172.3',
port: 445,
service_name: 'smb',
protocol: 'tcp',
module_fullname: 'auxiliary/scanner/smb/smb_login',
workspace_id: framework.db.workspace.id,
origin_type: :service
}
FactoryGirl.create(:mdm_host, address: opts[:address], workspace_id: opts[:workspace_id])
expect { test_object.create_credential_origin_service(opts)}.to_not change{Mdm::Host.count}
end
end
context 'when there is not a matching host record' do
it 'create a new host record' do
opts = {
address: '192.168.172.3',
port: 445,
service_name: 'smb',
protocol: 'tcp',
module_fullname: 'auxiliary/scanner/smb/smb_login',
workspace_id: framework.db.workspace.id,
origin_type: :service
}
expect { test_object.create_credential_origin_service(opts)}.to change{Mdm::Host.count}.by(1)
end
end
context 'when there is a matching service record' do
it 'uses the existing service record' do
opts = {
address: '192.168.172.3',
port: 445,
service_name: 'smb',
protocol: 'tcp',
module_fullname: 'auxiliary/scanner/smb/smb_login',
workspace_id: framework.db.workspace.id,
origin_type: :service
}
host = FactoryGirl.create(:mdm_host, address: opts[:address], workspace_id: opts[:workspace_id])
FactoryGirl.create(:mdm_service, host_id: host.id, port: opts[:port], proto: opts[:protocol])
expect { test_object.create_credential_origin_service(opts)}.to_not change{Mdm::Service.count}
end
end
context 'when there is no matching service record' do
it 'creates a new service record' do
opts = {
address: '192.168.172.3',
port: 445,
service_name: 'smb',
protocol: 'tcp',
module_fullname: 'auxiliary/scanner/smb/smb_login',
workspace_id: framework.db.workspace.id,
origin_type: :service
}
expect { test_object.create_credential_origin_service(opts)}.to change{Mdm::Service.count}.by(1)
end
end
context 'when called twice with the same options' do
it 'does not create duplicate objects' do
opts = {
address: '192.168.172.3',
port: 445,
service_name: 'smb',
protocol: 'tcp',
module_fullname: 'auxiliary/scanner/smb/smb_login',
workspace_id: framework.db.workspace.id,
origin_type: :service
}
test_object.create_credential_origin_service(opts)
expect { test_object.create_credential_origin_service(opts)}.to_not change{Metasploit::Credential::Origin::Service.count}
end
end
context 'when missing an option' do
it 'throws a KeyError' do
opts = {}
expect{ test_object.create_credential_origin_service(opts)}.to raise_error KeyError
end
end
end
context '#create_credential_origin_session' do
it 'creates a Metasploit::Credential::Origin object' do
opts = {
post_reference_name: 'windows/gather/hashdump',
session_id: session.id
}
expect { test_object.create_credential_origin_session(opts)}.to change{Metasploit::Credential::Origin::Session.count}.by(1)
end
it 'should return nil if there is no database connection' do
expect(test_object.framework.db).to receive(:active).and_return(false)
expect(test_object.create_credential_origin_session).to be_nil
end
context 'when called twice with the same options' do
it 'does not create duplicate objects' do
opts = {
post_reference_name: 'windows/gather/hashdump',
session_id: session.id
}
test_object.create_credential_origin_session(opts)
expect { test_object.create_credential_origin_session(opts)}.to_not change{Metasploit::Credential::Origin::Session.count}
end
end
context 'when missing an option' do
it 'throws a KeyError' do
opts = {}
expect{ test_object.create_credential_origin_session(opts) }.to raise_error KeyError
end
end
end
context '#create_credential_origin' do
it 'should return nil if there is no database connection' do
expect(test_object.framework.db).to receive(:active).and_return(false)
expect(test_object.create_credential_origin).to be_nil
end
it 'calls the correct method to create Origin::Import records' do
opts = {
filename: "test_import.xml",
origin_type: :import,
task_id: task.id
}
my_module = test_object
expect(my_module).to receive(:create_credential_origin_import)
my_module.create_credential_origin(opts)
end
it 'calls the correct method to create Origin::Manual records' do
opts = {
origin_type: :manual,
user_id: user.id
}
my_module = test_object
expect(my_module).to receive(:create_credential_origin_manual)
my_module.create_credential_origin(opts)
end
it 'calls the correct method to create Origin::Service records' do
opts = {
address: '192.168.172.3',
port: 445,
service_name: 'smb',
protocol: 'tcp',
module_fullname: 'auxiliary/scanner/smb/smb_login',
workspace_id: framework.db.workspace.id,
origin_type: :service
}
expect(test_object).to receive(:create_credential_origin_service)
test_object.create_credential_origin(opts)
end
it 'calls the correct method to create Origin::Session records' do
opts = {
origin_type: :session,
post_reference_name: 'windows/gather/hashdump',
session_id: session.id
}
my_module = test_object
expect(my_module).to receive(:create_credential_origin_session)
my_module.create_credential_origin(opts)
end
it 'raises an exception if there is no origin type' do
opts = {
post_reference_name: 'windows/gather/hashdump',
session_id: session.id
}
expect{test_object.create_credential_origin(opts)}.to raise_error ArgumentError, "Unknown Origin Type "
end
it 'raises an exception if given an invalid origin type' do
opts = {
origin_type: 'aaaaa',
post_reference_name: 'windows/gather/hashdump',
session_id: session.id
}
expect{test_object.create_credential_origin(opts)}.to raise_error ArgumentError, "Unknown Origin Type aaaaa"
end
end
context '#create_credential_realm' do
it 'creates a Metasploit::Credential::Realm object' do
opts = {
realm_key: 'Active Directory Domain',
realm_value: 'contosso'
}
expect { test_object.create_credential_realm(opts)}.to change{Metasploit::Credential::Realm.count}.by(1)
end
it 'should return nil if there is no database connection' do
expect(test_object.framework.db).to receive(:active).and_return(false)
expect(test_object.create_credential_realm).to be_nil
end
context 'when called twice with the same options' do
it 'does not create duplicate objects' do
opts = {
realm_key: 'Active Directory Domain',
realm_value: 'contosso'
}
test_object.create_credential_realm(opts)
expect { test_object.create_credential_realm(opts)}.to_not change{Metasploit::Credential::Realm.count}
end
end
context 'when missing an option' do
it 'throws a KeyError' do
opts = {}
expect{ test_object.create_credential_origin_manual(opts)}.to raise_error KeyError
end
end
end
context '#create_credential_private' do
it 'should return nil if there is no database connection' do
expect(test_object.framework.db).to receive(:active).and_return(false)
expect(test_object.create_credential_private).to be_nil
end
context 'when missing an option' do
it 'throws a KeyError' do
opts = {}
expect{ test_object.create_credential_private(opts)}.to raise_error KeyError
end
end
context 'when :private_type is password' do
it 'creates a Metasploit::Credential::Password' do
opts = {
private_data: 'password1',
private_type: :password
}
expect{ test_object.create_credential_private(opts) }.to change{Metasploit::Credential::Password.count}.by(1)
end
end
context 'when :private_type is sshkey' do
it 'creates a Metasploit::Credential::SSHKey' do
opts = {
private_data: OpenSSL::PKey::RSA.generate(2048).to_s,
private_type: :ssh_key
}
expect{ test_object.create_credential_private(opts) }.to change{Metasploit::Credential::SSHKey.count}.by(1)
end
end
context 'when :private_type is ntlmhash' do
it 'creates a Metasploit::Credential::NTLMHash' do
opts = {
private_data: Metasploit::Credential::NTLMHash.data_from_password_data('password1'),
private_type: :ntlm_hash
}
expect{ test_object.create_credential_private(opts) }.to change{Metasploit::Credential::NTLMHash.count}.by(1)
end
end
context 'when :private_type is nonreplayable_hash' do
it 'creates a Metasploit::Credential::NonreplayableHash' do
opts = {
private_data: '10b222970537b97919db36ec757370d2',
private_type: :nonreplayable_hash
}
expect{ test_object.create_credential_private(opts) }.to change{Metasploit::Credential::NonreplayableHash.count}.by(1)
end
end
end
context '#create_credential_core' do
let(:origin) { FactoryGirl.create(:metasploit_credential_origin_service) }
let(:public) { FactoryGirl.create(:metasploit_credential_public)}
let(:private) { FactoryGirl.create(:metasploit_credential_password)}
let(:realm) { FactoryGirl.create(:metasploit_credential_realm)}
it 'raises a KeyError if any required option is missing' do
opts = {}
expect{ test_object.create_credential_core(opts)}.to raise_error KeyError
end
it 'returns nil if there is no active database connection' do
expect(test_object.framework.db).to receive(:active).and_return(false)
expect(test_object.create_credential_core).to be_nil
end
it 'creates a Metasploit::Credential::Core' do
opts = {
origin: origin,
public: public,
private: private,
realm: realm,
workspace_id: origin.service.host.workspace_id
}
expect{test_object.create_credential_core(opts)}.to change{Metasploit::Credential::Core.count}.by(1)
end
end
end