Skip to content

Commit c1780a1

Browse files
authored
Merge pull request Pennyw0rth#411 from Pennyw0rth/neff-improve-login
Increase plaintext&hash login speeds
2 parents 43da2af + 85b2b6e commit c1780a1

1 file changed

Lines changed: 29 additions & 10 deletions

File tree

nxc/protocols/smb.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -303,17 +303,18 @@ def enum_host_info(self):
303303
self.kdcHost = result["host"] if result else None
304304
self.logger.info(f"Resolved domain: {self.domain} with dns, kdcHost: {self.kdcHost}")
305305

306+
# If we want to authenticate we should create another connection object, because we already logged in
307+
if self.args.username or self.args.cred_id or self.kerberos or self.args.use_kcache:
308+
self.create_conn_obj()
309+
306310
def print_host_info(self):
307311
signing = colored(f"signing:{self.signing}", host_info_colors[0], attrs=["bold"]) if self.signing else colored(f"signing:{self.signing}", host_info_colors[1], attrs=["bold"])
308312
smbv1 = colored(f"SMBv1:{self.smbv1}", host_info_colors[2], attrs=["bold"]) if self.smbv1 else colored(f"SMBv1:{self.smbv1}", host_info_colors[3], attrs=["bold"])
309313
self.logger.display(f"{self.server_os}{f' x{self.os_arch}' if self.os_arch else ''} (name:{self.hostname}) (domain:{self.targetDomain}) ({signing}) ({smbv1})")
310314
return True
311315

312316
def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False):
313-
logging.getLogger("impacket").disabled = True
314-
# Re-connect since we logged off
315317
self.logger.debug(f"KDC set to: {kdcHost}")
316-
self.create_conn_obj()
317318
lmhash = ""
318319
nthash = ""
319320

@@ -371,9 +372,7 @@ def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="",
371372
if self.args.continue_on_success and self.signing:
372373
with contextlib.suppress(Exception):
373374
self.conn.logoff()
374-
375375
self.create_conn_obj()
376-
377376
return True
378377
except SessionKeyDecryptionError:
379378
# success for now, since it's a vulnerability - previously was an error
@@ -406,7 +405,6 @@ def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="",
406405

407406
def plaintext_login(self, domain, username, password):
408407
# Re-connect since we logged off
409-
self.create_conn_obj()
410408
try:
411409
self.password = password
412410
self.username = username
@@ -452,14 +450,15 @@ def plaintext_login(self, domain, username, password):
452450
return False
453451
except (ConnectionResetError, NetBIOSTimeout, NetBIOSError) as e:
454452
self.logger.fail(f"Connection Error: {e}")
453+
self.create_conn_obj()
455454
return False
456455
except BrokenPipeError:
457456
self.logger.fail("Broken Pipe Error while attempting to login")
457+
self.create_conn_obj()
458458
return False
459459

460460
def hash_login(self, domain, username, ntlm_hash):
461461
# Re-connect since we logged off
462-
self.create_conn_obj()
463462
lmhash = ""
464463
nthash = ""
465464
try:
@@ -516,12 +515,15 @@ def hash_login(self, domain, username, ntlm_hash):
516515
return False
517516
except (ConnectionResetError, NetBIOSTimeout, NetBIOSError) as e:
518517
self.logger.fail(f"Connection Error: {e}")
518+
self.create_conn_obj()
519519
return False
520520
except BrokenPipeError:
521521
self.logger.fail("Broken Pipe Error while attempting to login")
522+
self.create_conn_obj()
522523
return False
523524

524525
def create_smbv1_conn(self):
526+
self.logger.debug(f"Creating SMBv1 connection to {self.host}")
525527
try:
526528
self.conn = SMBConnection(
527529
self.remoteName,
@@ -539,10 +541,10 @@ def create_smbv1_conn(self):
539541
except (Exception, NetBIOSTimeout) as e:
540542
self.logger.info(f"Error creating SMBv1 connection to {self.host}: {e}")
541543
return False
542-
543544
return True
544545

545546
def create_smbv3_conn(self):
547+
self.logger.debug(f"Creating SMBv3 connection to {self.host}")
546548
try:
547549
self.conn = SMBConnection(
548550
self.remoteName,
@@ -565,8 +567,25 @@ def create_smbv3_conn(self):
565567
return False
566568
return True
567569

568-
def create_conn_obj(self):
569-
return bool(self.create_smbv1_conn() or self.create_smbv3_conn())
570+
def create_conn_obj(self, no_smbv1=False):
571+
"""
572+
Tries to create a connection object to the target host.
573+
On first try, it will try to create a SMBv1 connection.
574+
On further tries, it will remember which SMB version is supported and create a connection object accordingly.
575+
576+
:param no_smbv1: If True, it will not try to create a SMBv1 connection
577+
"""
578+
# Initial negotiation
579+
if not no_smbv1 and self.smbv1 is None:
580+
self.smbv1 = self.create_smbv1_conn()
581+
if self.smbv1:
582+
return True
583+
else:
584+
return self.create_smbv3_conn()
585+
elif not no_smbv1 and self.smbv1:
586+
return self.create_smbv1_conn()
587+
else:
588+
return self.create_smbv3_conn()
570589

571590
def check_if_admin(self):
572591
self.logger.debug(f"Checking if user is admin on {self.host}")

0 commit comments

Comments
 (0)