@@ -21,14 +21,16 @@ class Metasploit3 < Msf::Auxiliary
21
21
22
22
def initialize
23
23
super (
24
- 'Name' => 'SMB Local User Enumeration (LookupSid)' ,
24
+ 'Name' => 'SMB SID User Enumeration (LookupSid)' ,
25
25
'Description' => 'Determine what users exist via brute force SID lookups.
26
26
This module can enumerate both local and domain accounts by setting
27
27
ACTION to either LOCAL or DOMAIN' ,
28
28
'Author' => 'hdm' ,
29
29
'License' => MSF_LICENSE ,
30
30
'DefaultOptions' =>
31
31
{
32
+ # Samba doesn't like this option, so we disable so we are compatible with
33
+ # both Windows and Samba for enumeration.
32
34
'DCERPC::fake_bind_multi' => false
33
35
} ,
34
36
'Actions' =>
@@ -49,6 +51,10 @@ def initialize
49
51
deregister_options ( 'RPORT' , 'RHOST' )
50
52
end
51
53
54
+ # Constants used by this module
55
+ LSA_UUID = '12345778-1234-abcd-ef00-0123456789ab'
56
+ LSA_VERS = '0.0'
57
+ LSA_PIPES = %W{ LSARPC NETLOGON SAMR BROWSER SRVSVC }
52
58
53
59
# Locate an available SMB PIPE for the specified service
54
60
def smb_find_dcerpc_pipe ( uuid , vers , pipes )
@@ -128,11 +134,6 @@ def smb_parse_sid_lookup(data)
128
134
[ uinfo [ 3 ] , name ]
129
135
end
130
136
131
-
132
- @@lsa_uuid = '12345778-1234-abcd-ef00-0123456789ab'
133
- @@lsa_vers = '0.0'
134
- @@lsa_pipes = %W{ LSARPC NETLOGON SAMR BROWSER SRVSVC }
135
-
136
137
# Fingerprint a single host
137
138
def run_host ( ip )
138
139
@@ -145,7 +146,7 @@ def run_host(ip)
145
146
lsa_handle = nil
146
147
begin
147
148
# find the lsarpc pipe
148
- lsa_pipe = smb_find_dcerpc_pipe ( @@lsa_uuid , @@lsa_vers , @@lsa_pipes )
149
+ lsa_pipe = smb_find_dcerpc_pipe ( LSA_UUID , LSA_VERS , LSA_PIPES )
149
150
break if not lsa_pipe
150
151
151
152
# OpenPolicy2()
@@ -201,20 +202,27 @@ def run_host(ip)
201
202
resp = dcerpc . last_response ? dcerpc . last_response . stub_data : nil
202
203
domain_sid , domain_name = smb_parse_sid ( resp )
203
204
204
-
205
205
# Store SID, local domain name, joined domain name
206
206
print_status ( "#{ ip } PIPE(#{ lsa_pipe } ) LOCAL(#{ host_name } - #{ host_sid } ) DOMAIN(#{ domain_name } - #{ domain_sid } )" )
207
207
208
-
209
208
domain = {
210
209
:name => host_name ,
211
210
:txt_sid => host_sid ,
212
211
:users => { } ,
213
212
:groups => { }
214
213
}
215
214
216
- target_sid = host_sid if action . name =~ /LOCAL/i
217
- target_sid = domain_sid if action . name =~ /DOMAIN/i
215
+ target_sid = case action . name . upcase
216
+ when 'LOCAL'
217
+ host_sid
218
+ when 'DOMAIN'
219
+ # Fallthrough to the host SID if no domain SID was returned
220
+ unless domain_sid
221
+ print_error ( "#{ ip } No domain SID identified, falling back to the local SID..." )
222
+ end
223
+ domain_sid || host_sid
224
+ end
225
+
218
226
# Brute force through a common RID range
219
227
500 . upto ( datastore [ 'MaxRID' ] . to_i ) do |rid |
220
228
@@ -269,10 +277,9 @@ def run_host(ip)
269
277
)
270
278
271
279
print_status ( "#{ ip } #{ domain [ :name ] . upcase } [#{ domain [ :users ] . keys . map { |k | domain [ :users ] [ k ] } . join ( ", " ) } ]" )
272
-
273
- # cleanup
274
280
disconnect
275
281
return
282
+
276
283
rescue ::Timeout ::Error
277
284
rescue ::Interrupt
278
285
raise $!
0 commit comments