55import contextlib
66
77from os .path import isfile
8- from threading import BoundedSemaphore
8+ from threading import BoundedSemaphore , Lock
99from functools import wraps
1010from time import sleep
1111from ipaddress import ip_address
2525from impacket .krb5 .ccache import CCache
2626
2727sem = BoundedSemaphore (1 )
28+ fail_lock = Lock ()
2829global_failed_logins = 0
2930user_failed_logins = {}
3031
@@ -315,26 +316,28 @@ def call_modules(self):
315316 def inc_failed_login (self , username ):
316317 global global_failed_logins , user_failed_logins
317318
318- if username not in user_failed_logins :
319- user_failed_logins [username ] = 0
319+ with fail_lock :
320+ if username not in user_failed_logins :
321+ user_failed_logins [username ] = 0
320322
321- user_failed_logins [username ] += 1
322- global_failed_logins += 1
323- self .failed_logins += 1
323+ user_failed_logins [username ] += 1
324+ global_failed_logins += 1
325+ self .failed_logins += 1
324326
325327 def over_fail_limit (self , username ):
326328 global global_failed_logins , user_failed_logins
327329
328- if global_failed_logins == self .args .gfail_limit :
329- return True
330+ with fail_lock :
331+ if global_failed_logins == self .args .gfail_limit :
332+ return True
330333
331- if self .failed_logins == self .args .fail_limit :
332- return True
334+ if self .failed_logins == self .args .fail_limit :
335+ return True
333336
334- if username in user_failed_logins and self .args .ufail_limit == user_failed_logins [username ]: # noqa: SIM103
335- return True
337+ if username in user_failed_logins and self .args .ufail_limit == user_failed_logins [username ]: # noqa: SIM103
338+ return True
336339
337- return False
340+ return False
338341
339342 def query_db_creds (self ):
340343 """Queries the database for credentials to be used for authentication.
@@ -481,8 +484,6 @@ def try_credentials(self, domain, username, owned, secret, cred_type, data=None)
481484 - NTLM-hash (/kerberos)
482485 - AES-key
483486 """
484- if self .over_fail_limit (username ):
485- return False
486487 if self .args .continue_on_success and owned :
487488 return False
488489
@@ -498,6 +499,8 @@ def try_credentials(self, domain, username, owned, secret, cred_type, data=None)
498499 sleep (value )
499500
500501 with sem :
502+ if self .over_fail_limit (username ):
503+ return False
501504 if cred_type == "plaintext" :
502505 if self .kerberos :
503506 self .logger .debug ("Trying to authenticate using Kerberos" )
0 commit comments