@@ -32,7 +32,9 @@ def initialize
32
32
'Author' =>
33
33
[
34
34
'tebo <tebo [at] attackresearch [dot] com>' , # Original
35
- 'Ben Campbell' # Refactoring
35
+ 'Ben Campbell' , # Refactoring
36
+ 'Brandon McCann "zeknox" <bmccann [at] accuvant.com>' , # admin check
37
+ 'Tom Sellers <tom <at> fadedcode.net>' # admin check/bug fix
36
38
] ,
37
39
'References' =>
38
40
[
@@ -69,6 +71,7 @@ def initialize
69
71
OptString . new ( 'SMBPass' , [ false , "SMB Password" ] ) ,
70
72
OptString . new ( 'SMBUser' , [ false , "SMB Username" ] ) ,
71
73
OptString . new ( 'SMBDomain' , [ false , "SMB Domain" , '' ] ) ,
74
+ OptBool . new ( 'CHECK_ADMIN' , [ false , "Check for Admin rights" , false ] ) ,
72
75
OptBool . new ( 'PRESERVE_DOMAINS' , [ false , "Respect a username that contains a domain name." , true ] ) ,
73
76
OptBool . new ( 'RECORD_GUEST' , [ false , "Record guest-privileged random logins to the database" , false ] )
74
77
] , self . class )
@@ -124,6 +127,25 @@ def check_login_status(domain, user, pass)
124
127
# Windows SMB will return an error code during Session Setup, but nix Samba requires a Tree Connect:
125
128
simple . connect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
126
129
status_code = 'STATUS_SUCCESS'
130
+
131
+ if datastore [ 'CHECK_ADMIN' ]
132
+ status_code = :not_admin
133
+ # Drop the existing connection to IPC$ in order to connect to admin$
134
+ simple . disconnect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
135
+ begin
136
+ simple . connect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ admin$" )
137
+ status_code = :admin_access
138
+ simple . disconnect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ admin$" )
139
+ rescue
140
+ status_code = :not_admin
141
+ ensure
142
+ begin
143
+ simple . connect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
144
+ rescue ::Rex ::Proto ::SMB ::Exceptions ::NoReply
145
+ end
146
+ end
147
+ end
148
+
127
149
rescue ::Rex ::Proto ::SMB ::Exceptions ::ErrorCode => e
128
150
status_code = e . get_error ( e . error_code )
129
151
rescue ::Rex ::Proto ::SMB ::Exceptions ::LoginError => e
@@ -187,7 +209,16 @@ def accepts_bogus_domains?(user, pass, rhost)
187
209
end
188
210
189
211
def valid_credentials? ( status )
190
- return ( status == "STATUS_SUCCESS" || @correct_credentials_status_codes . include? ( status ) )
212
+
213
+ case status
214
+ when 'STATUS_SUCCESS' , :admin_access , :not_admin
215
+ return true
216
+ when *@correct_credentials_status_codes
217
+ return true
218
+ else
219
+ return false
220
+ end
221
+
191
222
end
192
223
193
224
def try_user_pass ( domain , user , pass )
@@ -214,7 +245,7 @@ def try_user_pass(domain, user, pass)
214
245
output_message << " (#{ smb_peer_os } ) #{ user } : #{ pass } [#{ status } ]" . gsub ( '%' , '%%' )
215
246
216
247
case status
217
- when 'STATUS_SUCCESS'
248
+ when 'STATUS_SUCCESS' , :admin_access , :not_admin
218
249
# Auth user indicates if the login was as a guest or not
219
250
if ( simple . client . auth_user )
220
251
print_good ( output_message % "SUCCESSFUL LOGIN" )
@@ -275,7 +306,7 @@ def note_creds(domain,user,pass,reason)
275
306
def report_creds ( domain , user , pass , active )
276
307
login_name = ""
277
308
278
- if accepts_bogus_domains? ( user , pass , rhost )
309
+ if accepts_bogus_domains? ( user , pass , rhost ) || domain . blank?
279
310
login_name = user
280
311
else
281
312
login_name = "#{ domain } \\ #{ user } "
0 commit comments