Skip to content

Commit 7ff2ba0

Browse files
David MaloneyDavid Maloney
authored andcommitted
first pass on fixing DB_ALL authbrute stuff
DB_ALL_CREDS worked but DB_ALL_USER and DB_ALL_PASS did not. working on fixing that. This commit also does some nice DRY work in the auth_brute mixin MSP-11986
1 parent fee49b0 commit 7ff2ba0

File tree

2 files changed

+91
-10
lines changed

2 files changed

+91
-10
lines changed

lib/metasploit/framework/credential_collection.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
class Metasploit::Framework::CredentialCollection
44

5+
# @!attribute additional_privates
6+
# Additional privates to be combined
7+
#
8+
# @return [Array<String>]
9+
attr_accessor :additional_privates
10+
11+
# @!attribute additional_publics
12+
# Additional public to be combined
13+
#
14+
# @return [Array<String>]
15+
attr_accessor :additional_publics
16+
517
# @!attribute blank_passwords
618
# Whether each username should be tried with a blank password
719
# @return [Boolean]
@@ -62,6 +74,24 @@ def initialize(opts = {})
6274
self.prepended_creds ||= []
6375
end
6476

77+
# Adds a string as an addition private credential
78+
# to be combined in the collection.
79+
#
80+
# @param [String] :private_str the string to use as a private
81+
# @return [void]
82+
def add_private(private_str='')
83+
additional_privates << private_str
84+
end
85+
86+
# Adds a string as an addition public credential
87+
# to be combined in the collection.
88+
#
89+
# @param [String] :public_str the string to use as a public
90+
# @return [void]
91+
def add_public(public_str='')
92+
additional_publics << public_str
93+
end
94+
6595
# Add {Credential credentials} that will be yielded by {#each}
6696
#
6797
# @see prepended_creds

lib/msf/core/auxiliary/auth_brute.rb

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,57 @@ def setup
4949
@@max_per_service = nil
5050
end
5151

52+
# Yields each {Metasploit::Credential::Core} in the {Mdm::Workspace} with
53+
# a private type of 'ntlm_hash'
54+
#
55+
# @yieldparam [Metasploit::Credential::Core]
56+
def each_ntlm_cred
57+
creds = Metasploit::Credential::Core.joins(:private).where(metasploit_credential_privates: { type: 'Metasploit::Credential::NTLMHash' }, workspace_id: myworkspace.id)
58+
creds.each do |cred|
59+
yield cred
60+
end
61+
end
62+
63+
# Yields each {Metasploit::Credential::Core} in the {Mdm::Workspace} with
64+
# a private type of 'password'
65+
#
66+
# @yieldparam [Metasploit::Credential::Core]
67+
def each_password_cred
68+
creds = Metasploit::Credential::Core.joins(:private).where(metasploit_credential_privates: { type: 'Metasploit::Credential::Password' }, workspace_id: myworkspace.id)
69+
creds.each do |cred|
70+
yield cred
71+
end
72+
end
73+
74+
# Yields each {Metasploit::Credential::Core} in the {Mdm::Workspace} with
75+
# a private type of 'ssh_key'
76+
#
77+
# @yieldparam [Metasploit::Credential::Core]
78+
def each_ssh_cred
79+
creds = Metasploit::Credential::Core.joins(:private).where(metasploit_credential_privates: { type: 'Metasploit::Credential::SSHKey' }, workspace_id: myworkspace.id)
80+
creds.each do |cred|
81+
yield cred
82+
end
83+
end
84+
85+
# Checks whether we should be adding creds from the DB to a CredCollection
86+
#
87+
# @return [TrueClass] if any of the datastore options for db creds are selected and the db is active
88+
# @return [FalseClass] if none of the datastore options are selected OR the db is not active
89+
def prepend_db_creds?
90+
(datastore['DB_ALL_CREDS'] || datastore['DB_ALL_PASS'] || datastore['DB_ALL_USERS']) && framework.db.active
91+
end
92+
5293
# This method takes a {Metasploit::Framework::CredentialCollection} and prepends existing NTLMHashes
5394
# from the database. This allows the users to use the DB_ALL_CREDS option.
5495
#
5596
# @param cred_collection [Metasploit::Framework::CredentialCollection]
5697
# the credential collection to add to
5798
# @return [Metasploit::Framework::CredentialCollection] the modified Credentialcollection
5899
def prepend_db_hashes(cred_collection)
59-
if datastore['DB_ALL_CREDS'] && framework.db.active
60-
creds = Metasploit::Credential::Core.joins(:private).where(metasploit_credential_privates: { type: 'Metasploit::Credential::NTLMHash' }, workspace_id: myworkspace.id)
61-
creds.each do |cred|
62-
cred_collection.prepend_cred(cred.to_credential)
100+
if prepend_db_creds?
101+
each_ntlm_cred do |cred|
102+
process_cred_for_collection(cred_collection,cred)
63103
end
64104
end
65105
cred_collection
@@ -73,9 +113,8 @@ def prepend_db_hashes(cred_collection)
73113
# @return [Metasploit::Framework::CredentialCollection] the modified Credentialcollection
74114
def prepend_db_keys(cred_collection)
75115
if datastore['DB_ALL_CREDS'] && framework.db.active
76-
creds = Metasploit::Credential::Core.joins(:private).where(metasploit_credential_privates: { type: 'Metasploit::Credential::SSHKey' }, workspace_id: myworkspace.id)
77-
creds.each do |cred|
78-
cred_collection.prepend_cred(cred.to_credential)
116+
each_ssh_cred do |cred|
117+
process_cred_for_collection(cred_collection,cred)
79118
end
80119
end
81120
cred_collection
@@ -89,14 +128,26 @@ def prepend_db_keys(cred_collection)
89128
# @return [Metasploit::Framework::CredentialCollection] the modified Credentialcollection
90129
def prepend_db_passwords(cred_collection)
91130
if datastore['DB_ALL_CREDS'] && framework.db.active
92-
creds = Metasploit::Credential::Core.joins(:private).where(metasploit_credential_privates: { type: 'Metasploit::Credential::Password' }, workspace_id: myworkspace.id)
93-
creds.each do |cred|
94-
cred_collection.prepend_cred(cred.to_credential)
131+
each_password_cred do |cred|
132+
process_cred_for_collection(cred_collection,cred)
95133
end
96134
end
97135
cred_collection
98136
end
99137

138+
# Takes a {Metasploit::Credential::Core} and converts it into a
139+
# {Metasploit::Framework::Credential} and processes it into the
140+
# {Metasploit::Framework::CredentialCollection} as dictated by the
141+
# selected datastore options.
142+
#
143+
# @param [Metasploit::Framework::CredentialCollection] the credential collection to add to
144+
# @param [Metasploit::Credential::Core] the Credential Core to process
145+
def process_cred_for_collection(cred_collection, cred)
146+
msf_cred = cred.to_credential
147+
cred_collection.prepend_cred(msf_cred) if datastore['DB_ALL_CREDS']
148+
cred_collection.add_private(msf_cred.private) if datastore['DB_ALL_PASS']
149+
cred_collection.add_public(msf_cred.public) if datastore['DB_ALL_USERS']
150+
end
100151

101152

102153
# Checks all three files for usernames and passwords, and combines them into

0 commit comments

Comments
 (0)