Skip to content

Commit b08a5f6

Browse files
committed
Change how ldap_login generate its specific credentials for SCHANNEL && KERBEROS auth
1 parent 66ce020 commit b08a5f6

File tree

3 files changed

+27
-89
lines changed

3 files changed

+27
-89
lines changed

lib/metasploit/framework/credential_collection.rb

+2-28
Original file line numberDiff line numberDiff line change
@@ -212,23 +212,6 @@ class CredentialCollection < PrivateCredentialCollection
212212
# @return [Boolean]
213213
attr_accessor :anonymous_login
214214

215-
# @!attribute ignore_private
216-
# Whether to ignore private (password). This is usually set when Kerberos
217-
# or Schannel authentication is requested and the credentials are
218-
# retrieved from cache or from a file. This attribute should be true in
219-
# these scenarios, otherwise validation will fail since the password is not
220-
# provided.
221-
# @return [Boolean]
222-
attr_accessor :ignore_private
223-
224-
# @!attribute ignore_public
225-
# Whether to ignore public (username). This is usually set when Schannel
226-
# authentication is requested and the credentials are retrieved from a
227-
# file (certificate). This attribute should be true in this case,
228-
# otherwise validation will fail since the password is not provided.
229-
# @return [Boolean]
230-
attr_accessor :ignore_public
231-
232215
# @option opts [Boolean] :blank_passwords See {#blank_passwords}
233216
# @option opts [String] :pass_file See {#pass_file}
234217
# @option opts [String] :password See {#password}
@@ -267,15 +250,6 @@ def each_filtered
267250
alias each each_filtered
268251

269252
def each_unfiltered(&block)
270-
if ignore_private
271-
if ignore_public
272-
yield Metasploit::Framework::Credential.new(public: nil, private: nil, realm: realm)
273-
else
274-
yield Metasploit::Framework::Credential.new(public: username, private: nil, realm: realm)
275-
end
276-
return
277-
end
278-
279253
prepended_creds.each { |c| yield c }
280254

281255
if anonymous_login
@@ -468,14 +442,14 @@ def empty?
468442
#
469443
# @return [Boolean]
470444
def has_users?
471-
username.present? || user_file.present? || userpass_file.present? || !additional_publics.empty? || !!ignore_public
445+
username.present? || user_file.present? || userpass_file.present? || !additional_publics.empty?
472446
end
473447

474448
# Returns true when there are any private values set
475449
#
476450
# @return [Boolean]
477451
def has_privates?
478-
super || userpass_file.present? || user_as_pass || !!ignore_private
452+
super || userpass_file.present? || user_as_pass
479453
end
480454

481455
end

modules/auxiliary/scanner/ldap/ldap_login.rb

+24-13
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,9 @@ def validate_connect_options!
8989
end
9090

9191
def run_host(ip)
92-
ignore_public = datastore['LDAP::Auth'] == Msf::Exploit::Remote::AuthOption::SCHANNEL
93-
ignore_private =
94-
datastore['LDAP::Auth'] == Msf::Exploit::Remote::AuthOption::SCHANNEL ||
95-
(Msf::Exploit::Remote::AuthOption::KERBEROS && !datastore['ANONYMOUS_LOGIN'] && !datastore['PASSWORD'])
96-
97-
cred_collection = build_credential_collection(
98-
username: datastore['USERNAME'],
99-
password: datastore['PASSWORD'],
100-
realm: datastore['DOMAIN'],
101-
anonymous_login: datastore['ANONYMOUS_LOGIN'],
102-
blank_passwords: false,
103-
ignore_public: ignore_public,
104-
ignore_private: ignore_private
92+
cred_collection = build_specific_credential_collection(
93+
void_login: datastore['LDAP::Auth'] == Msf::Exploit::Remote::AuthOption::SCHANNEL,
94+
no_password_login: datastore['LDAP::Auth'] == Msf::Exploit::Remote::AuthOption::KERBEROS && !datastore['ANONYMOUS_LOGIN'] && !datastore['PASSWORD']
10595
)
10696

10797
opts = {
@@ -202,4 +192,25 @@ def session_setup(result)
202192

203193
start_session(self, nil, merge_me, false, my_session.rstream, my_session)
204194
end
195+
196+
def build_specific_credential_collection(void_login:, no_password_login:)
197+
if void_login
198+
Metasploit::Framework::PrivateCredentialCollection.new({
199+
nil_password: true
200+
})
201+
elsif no_password_login
202+
Metasploit::Framework::CredentialCollection.new({
203+
username: datastore['USERNAME'],
204+
nil_password: true
205+
})
206+
else
207+
build_credential_collection(
208+
username: datastore['USERNAME'],
209+
password: datastore['PASSWORD'],
210+
realm: datastore['DOMAIN'],
211+
anonymous_login: datastore['ANONYMOUS_LOGIN'],
212+
blank_passwords: false
213+
)
214+
end
215+
end
205216
end

spec/lib/metasploit/framework/credential_collection_spec.rb

+1-48
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616
prepended_creds: prepended_creds,
1717
additional_privates: additional_privates,
1818
additional_publics: additional_publics,
19-
password_spray: password_spray,
20-
ignore_public: ignore_public,
21-
ignore_private: ignore_private
19+
password_spray: password_spray
2220
)
2321
end
2422

@@ -41,8 +39,6 @@
4139
let(:additional_privates) { [] }
4240
let(:additional_publics) { [] }
4341
let(:password_spray) { false }
44-
let(:ignore_public) { nil }
45-
let(:ignore_private) { nil }
4642

4743
describe "#each" do
4844
specify do
@@ -596,34 +592,6 @@
596592
)
597593
end
598594
end
599-
600-
context 'when :ignore_public is true and :username is nil' do
601-
let(:ignore_public) { true }
602-
let(:username) { nil }
603-
specify do
604-
expect { |b| collection.each(&b) }.to_not yield_control
605-
end
606-
end
607-
608-
context 'when :ignore_private is true and password is nil' do
609-
let(:ignore_private) { true }
610-
let(:password) { nil }
611-
specify do
612-
expect { |b| collection.each(&b) }.to yield_successive_args(
613-
Metasploit::Framework::Credential.new(public: username, private: nil)
614-
)
615-
end
616-
617-
context 'when :ignore_public is also true and username is nil' do
618-
let(:ignore_public) { true }
619-
let(:username) { nil }
620-
specify do
621-
expect { |b| collection.each(&b) }.to yield_successive_args(
622-
Metasploit::Framework::Credential.new(public: nil, private: nil)
623-
)
624-
end
625-
end
626-
end
627595
end
628596

629597
describe "#empty?" do
@@ -693,21 +661,6 @@
693661
expect(collection.empty?).to eq true
694662
end
695663
end
696-
697-
context "and :ignore_public is set" do
698-
let(:ignore_public) { true }
699-
specify do
700-
expect(collection.empty?).to eq true
701-
end
702-
703-
context "and :ignore_private is also set" do
704-
let(:ignore_private) { true }
705-
specify do
706-
expect(collection.empty?).to eq false
707-
end
708-
end
709-
end
710-
711664
end
712665
end
713666
end

0 commit comments

Comments
 (0)