@@ -28,13 +28,18 @@ def __init__(self, args, db, host):
2828 self .conn = None
2929 self .admin_privs = False
3030 self .logger = None
31- self .password = None
32- self .username = None
31+ self .password = ''
32+ self .username = ''
33+ self .kerberos = True if self .args .kerberos else False
34+ self .aesKey = None if not self .args .aesKey else self .args .aesKey
35+ self .kdcHost = None if not self .args .kdcHost else self .args .kdcHost
3336 self .failed_logins = 0
3437 self .local_ip = None
3538
3639 try :
3740 self .host = gethostbyname (self .hostname )
41+ if self .args .kerberos :
42+ self .host = self .hostname
3843 except Exception as e :
3944 logging .debug ('Error resolving hostname {}: {}' .format (self .hostname , e ))
4045 return
@@ -60,6 +65,9 @@ def create_conn_obj(self):
6065 def check_if_admin (self ):
6166 return
6267
68+ def kerberos_login (self ):
69+ return
70+
6371 def plaintext_login (self , domain , username , password ):
6472 return
6573
@@ -133,94 +141,113 @@ def over_fail_limit(self, username):
133141 return False
134142
135143 def login (self ):
136- for cred_id in self .args .cred_id :
137- with sem :
138- if cred_id .lower () == 'all' :
139- creds = self .db .get_credentials ()
140- else :
141- creds = self .db .get_credentials (filterTerm = int (cred_id ))
142-
143- for cred in creds :
144- logging .debug (cred )
145- try :
146- c_id , domain , username , password , credtype , pillaged_from = cred
147-
148- if credtype and password :
149-
150- if not domain : domain = self .domain
151-
152- if self .args .local_auth :
153- domain = self .domain
154- elif self .args .domain :
155- domain = self .args .domain
156-
157- if credtype == 'hash' and not self .over_fail_limit (username ):
158- if self .hash_login (domain , username , password ): return True
159-
160- elif credtype == 'plaintext' and not self .over_fail_limit (username ):
161- if self .plaintext_login (domain , username , password ): return True
162-
163- except IndexError :
164- self .logger .error ("Invalid database credential ID!" )
165-
166- for user in self .args .username :
167- if not isinstance (user , str ) and isfile (user .name ):
168- for usr in user :
169- if self .args .hash :
170- with sem :
171- for ntlm_hash in self .args .hash :
172- if isinstance (ntlm_hash , str ):
173- if not self .over_fail_limit (usr .strip ()):
174- if self .hash_login (self .domain , usr .strip (), ntlm_hash ): return True
175-
176- elif not isinstance (ntlm_hash , str ) and isfile (ntlm_hash .name ):
177- for f_hash in ntlm_hash :
144+ if self .args .kerberos :
145+ if self .kerberos_login (self .aesKey , self .kdcHost ): return True
146+ else :
147+ for cred_id in self .args .cred_id :
148+ with sem :
149+ if cred_id .lower () == 'all' :
150+ creds = self .db .get_credentials ()
151+ else :
152+ creds = self .db .get_credentials (filterTerm = int (cred_id ))
153+
154+ for cred in creds :
155+ logging .debug (cred )
156+ try :
157+ c_id , domain , username , password , credtype , pillaged_from = cred
158+
159+ if credtype and password :
160+
161+ if not domain : domain = self .domain
162+
163+ if self .args .local_auth :
164+ domain = self .domain
165+ elif self .args .domain :
166+ domain = self .args .domain
167+
168+ if credtype == 'hash' and not self .over_fail_limit (username ):
169+ if self .hash_login (domain , username , password ): return True
170+
171+ elif credtype == 'plaintext' and not self .over_fail_limit (username ):
172+ if self .plaintext_login (domain , username , password ): return True
173+
174+ except IndexError :
175+ self .logger .error ("Invalid database credential ID!" )
176+
177+ for user in self .args .username :
178+ if not isinstance (user , str ) and isfile (user .name ):
179+ for usr in user :
180+ if "\\ " in usr :
181+ tmp = usr
182+ usr = tmp .split ('\\ ' )[1 ].strip ()
183+ self .domain = tmp .split ('\\ ' )[0 ]
184+ if self .args .hash :
185+ with sem :
186+ for ntlm_hash in self .args .hash :
187+ if isinstance (ntlm_hash , str ):
178188 if not self .over_fail_limit (usr .strip ()):
179- if self .hash_login (self .domain , usr .strip (), f_hash .strip ()): return True
180- ntlm_hash .seek (0 )
181-
182- elif self .args .password :
183- with sem :
184- for password in self .args .password :
185- if isinstance (password , str ):
186- if not self .over_fail_limit (usr .strip ()):
187- if self .plaintext_login (self .domain , usr .strip (), password ): return True
188-
189- elif not isinstance (password , str ) and isfile (password .name ):
190- for f_pass in password :
189+ if self .hash_login (self .domain , usr .strip (), ntlm_hash ): return True
190+
191+ elif not isinstance (ntlm_hash , str ) and isfile (ntlm_hash .name ) and self .args .no_bruteforce == False :
192+ for f_hash in ntlm_hash :
193+ if not self .over_fail_limit (usr .strip ()):
194+ if self .hash_login (self .domain , usr .strip (), f_hash .strip ()): return True
195+ ntlm_hash .seek (0 )
196+
197+ elif not isinstance (ntlm_hash , str ) and isfile (ntlm_hash .name ) and self .args .no_bruteforce == True :
198+ user .seek (0 )
199+ for usr , f_pass in zip (user , ntlm_hash ):
200+ if not self .over_fail_limit (usr .strip ()):
201+ if self .plaintext_login (self .domain , usr .strip (), f_hash .strip ()): return True
202+
203+ elif self .args .password :
204+ with sem :
205+ for password in self .args .password :
206+ if isinstance (password , str ):
191207 if not self .over_fail_limit (usr .strip ()):
192- if self .plaintext_login (self .domain , usr .strip (), f_pass .strip ()): return True
193- password .seek (0 )
194-
195- elif isinstance (user , str ):
196- if hasattr (self .args , 'hash' ) and self .args .hash :
197- with sem :
198- for ntlm_hash in self .args .hash :
199- if isinstance (ntlm_hash , str ):
200- if not self .over_fail_limit (user ):
201- if self .hash_login (self .domain , user , ntlm_hash ): return True
202-
203- elif not isinstance (ntlm_hash , str ) and isfile (ntlm_hash .name ):
204- for f_hash in ntlm_hash :
208+ if self .plaintext_login (self .domain , usr .strip (), password ): return True
209+
210+ elif not isinstance (password , str ) and isfile (password .name ) and self .args .no_bruteforce == False :
211+ for f_pass in password :
212+ if not self .over_fail_limit (usr .strip ()):
213+ if self .plaintext_login (self .domain , usr .strip (), f_pass .strip ()): return True
214+ password .seek (0 )
215+
216+ elif not isinstance (password , str ) and isfile (password .name ) and self .args .no_bruteforce == True :
217+ user .seek (0 )
218+ for usr , f_pass in zip (user , password ):
219+ if not self .over_fail_limit (usr .strip ()):
220+ if self .plaintext_login (self .domain , usr .strip (), f_pass .strip ()): return True
221+
222+ elif isinstance (user , str ):
223+ if hasattr (self .args , 'hash' ) and self .args .hash :
224+ with sem :
225+ for ntlm_hash in self .args .hash :
226+ if isinstance (ntlm_hash , str ):
205227 if not self .over_fail_limit (user ):
206- if self .hash_login (self .domain , user , f_hash .strip ()): return True
207- ntlm_hash .seek (0 )
208-
209- elif self .args .password :
210- with sem :
211- for password in self .args .password :
212- if isinstance (password , str ):
213- if not self .over_fail_limit (user ):
214- if hasattr (self .args , 'domain' ):
215- if self .plaintext_login (self .domain , user , password ): return True
216- else :
217- if self .plaintext_login (user , password ): return True
218-
219- elif not isinstance (password , str ) and isfile (password .name ):
220- for f_pass in password :
228+ if self .hash_login (self .domain , user , ntlm_hash ): return True
229+
230+ elif not isinstance (ntlm_hash , str ) and isfile (ntlm_hash .name ):
231+ for f_hash in ntlm_hash :
232+ if not self .over_fail_limit (user ):
233+ if self .hash_login (self .domain , user , f_hash .strip ()): return True
234+ ntlm_hash .seek (0 )
235+
236+ elif self .args .password :
237+ with sem :
238+ for password in self .args .password :
239+ if isinstance (password , str ):
221240 if not self .over_fail_limit (user ):
222241 if hasattr (self .args , 'domain' ):
223- if self .plaintext_login (self .domain , user , f_pass . strip () ): return True
242+ if self .plaintext_login (self .domain , user , password ): return True
224243 else :
225- if self .plaintext_login (user , f_pass .strip ()): return True
226- password .seek (0 )
244+ if self .plaintext_login (user , password ): return True
245+
246+ elif not isinstance (password , str ) and isfile (password .name ):
247+ for f_pass in password :
248+ if not self .over_fail_limit (user ):
249+ if hasattr (self .args , 'domain' ):
250+ if self .plaintext_login (self .domain , user , f_pass .strip ()): return True
251+ else :
252+ if self .plaintext_login (user , f_pass .strip ()): return True
253+ password .seek (0 )
0 commit comments