Skip to content

Commit cfe231a

Browse files
feat(smb): check if successful login is guest privs
1 parent 67da598 commit cfe231a

2 files changed

Lines changed: 30 additions & 11 deletions

File tree

nxc/connection.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -412,12 +412,21 @@ def parse_credentials(self):
412412
for ntlm_hash in self.args.hash:
413413
if isfile(ntlm_hash):
414414
with open(ntlm_hash) as ntlm_hash_file:
415-
for line in ntlm_hash_file:
416-
secret.append(line.strip())
417-
cred_type.append("hash")
415+
for i, line in enumerate(ntlm_hash_file):
416+
if len(line) != 16 and len(line) != 32:
417+
self.logger.fail(f"Invalid NTLM hash length on line {i+1}: {line}")
418+
continue
419+
else:
420+
secret.append(line.strip())
421+
cred_type.append("hash")
418422
else:
419-
secret.append(ntlm_hash)
420-
cred_type.append("hash")
423+
if len(ntlm_hash) != 16 and len(ntlm_hash) != 32:
424+
self.logger.fail(f"Invalid NTLM hash length {len(ntlm_hash)}, authentication not sent")
425+
exit(1)
426+
else:
427+
secret.append(ntlm_hash)
428+
cred_type.append("hash")
429+
self.logger.debug(secret)
421430

422431
# Parse AES keys
423432
if self.args.aesKey:
@@ -554,7 +563,7 @@ def login(self):
554563
return True
555564

556565
def mark_pwned(self):
557-
return highlight(f"({pwned_label})" if self.admin_privs else "")
566+
return highlight(f" ({pwned_label})" if self.admin_privs else "")
558567

559568
def load_modules(self):
560569
self.logger.info(f"Loading modules for target: {self.host}")

nxc/protocols/smb.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ def __init__(self, args, db, host):
161161
self.no_da = None
162162
self.no_ntlm = False
163163
self.protocol = "SMB"
164+
self.is_guest = None
164165

165166
connection.__init__(self, args, db, host)
166167

@@ -375,7 +376,9 @@ def plaintext_login(self, domain, username, password):
375376
self.domain = domain
376377

377378
self.conn.login(self.username, self.password, domain)
378-
379+
self.logger.debug(f"Logged in with password to SMB with {domain}/{self.username}")
380+
self.is_guest = bool(self.conn.isGuestSession())
381+
self.logger.debug(f"{self.is_guest=}")
379382
self.check_if_admin()
380383
self.logger.debug(f"Adding credential: {domain}/{self.username}:{self.password}")
381384
self.db.add_credential("plaintext", domain, self.username, self.password)
@@ -384,7 +387,7 @@ def plaintext_login(self, domain, username, password):
384387

385388
self.db.add_loggedin_relation(user_id, host_id)
386389

387-
out = f"{domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}"
390+
out = f"{domain}\\{self.username}:{process_secret(self.password)}{self.mark_guest()}{self.mark_pwned()}"
388391
self.logger.success(out)
389392

390393
if not self.args.local_auth and self.username != "":
@@ -444,14 +447,16 @@ def hash_login(self, domain, username, ntlm_hash):
444447
self.nthash = nthash
445448

446449
self.conn.login(self.username, "", domain, lmhash, nthash)
447-
450+
self.logger.debug(f"Logged in with hash to SMB with {domain}/{self.username}")
451+
self.is_guest = bool(self.conn.isGuestSession())
452+
self.logger.debug(f"{self.is_guest=}")
448453
self.check_if_admin()
449-
user_id = self.db.add_credential("hash", domain, self.username, nthash)
454+
user_id = self.db.add_credential("hash", domain, self.username, self.hash)
450455
host_id = self.db.get_hosts(self.host)[0].id
451456

452457
self.db.add_loggedin_relation(user_id, host_id)
453458

454-
out = f"{domain}\\{self.username}:{process_secret(self.hash)} {self.mark_pwned()}"
459+
out = f"{domain}\\{self.username}:{process_secret(self.hash)}{self.mark_guest()}{self.mark_pwned()}"
455460
self.logger.success(out)
456461

457462
if not self.args.local_auth and self.username != "":
@@ -531,6 +536,7 @@ def create_conn_obj(self):
531536
return bool(self.create_smbv1_conn() or self.create_smbv3_conn())
532537

533538
def check_if_admin(self):
539+
self.logger.debug(f"Checking if user is admin on {self.host}")
534540
rpctransport = SMBTransport(self.conn.getRemoteHost(), 445, r"\svcctl", smb_connection=self.conn)
535541
dce = rpctransport.get_dce_rpc()
536542
try:
@@ -544,6 +550,7 @@ def check_if_admin(self):
544550
# 0xF003F - SC_MANAGER_ALL_ACCESS
545551
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
546552
scmr.hROpenSCManagerW(dce, f"{self.host}\x00", "ServicesActive\x00", 0xF003F)
553+
self.logger.debug(f"User is admin on {self.host}!")
547554
self.admin_privs = True
548555
except scmr.DCERPCException:
549556
self.admin_privs = False
@@ -1774,3 +1781,6 @@ def add_ntds_hash(ntds_hash, host_id):
17741781
except Exception as e:
17751782
self.logger.debug(f"Error calling remote_ops.finish(): {e}")
17761783
NTDS.finish()
1784+
1785+
def mark_guest(self):
1786+
return highlight(f" {highlight('(Guest)')}" if self.is_guest else "")

0 commit comments

Comments
 (0)