Skip to content

Commit caba9f6

Browse files
committed
Refactor privilege check logic
1 parent cfc8f2f commit caba9f6

1 file changed

Lines changed: 37 additions & 31 deletions

File tree

nxc/protocols/ssh.py

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ def __init__(self, args, db, host):
2020
self.protocol = "SSH"
2121
self.remote_version = "Unknown SSH Version"
2222
self.server_os_platform = "Linux"
23+
self.shell_access = False
24+
self.admin_privs = False
2325
self.uac = ""
2426
super().__init__(args, db, host)
2527

@@ -116,12 +118,11 @@ def plaintext_login(self, username, password, private_key=""):
116118
)
117119
cred_id = self.db.add_credential("plaintext", username, password)
118120

119-
# Some IOT devices will not raise exception in self.conn._transport.auth_password / self.conn._transport.auth_publickey
120-
# Also an early check if we are on Linux or not, as on windows only stderr and not stdout is returned ("id" is not implemented)
121-
_, stdout, _ = self.conn.exec_command("id")
122-
stdout = stdout.read().decode(self.args.codec, errors="ignore")
121+
self.check_shell(cred_id)
123122

124-
self.check_privs(cred_id, stdout)
123+
out = process_secret(self.password) if not self.args.key_file else f"{process_secret(self.password)} (keyfile: {self.args.key_file})"
124+
display_shell_access = f"{self.uac}{self.server_os_platform}{' - Shell access!' if self.shell_access else ''}"
125+
self.logger.success(f"{self.username}:{process_secret(out)} {self.mark_pwned()} {highlight(display_shell_access)}")
125126
return True
126127
except AuthenticationException as e:
127128
if "Private key file is encrypted" in str(e):
@@ -140,42 +141,47 @@ def plaintext_login(self, username, password, private_key=""):
140141
self.conn.close()
141142
return False
142143

143-
def check_privs(self, cred_id, stdout):
144-
shell_access = False
144+
def check_shell(self, cred_id):
145145
host_id = self.db.get_hosts(self.host)[0].id
146146

147-
# If we have stdout we know it must be linux, "id" is not implemented on Windows
148-
if not stdout:
149-
self.server_os_platform = "Windows"
150-
_, stdout, _ = self.conn.exec_command("whoami /priv")
151-
stdout = stdout.read().decode(self.args.codec, errors="ignore")
152-
if "SeDebugPrivilege" in stdout:
153-
self.admin_privs = True
154-
elif "SeUndockPrivilege" in stdout:
155-
self.admin_privs = True
156-
self.uac = "with UAC - "
157-
158-
if not stdout:
159-
self.logger.debug(f"User: {self.username} can't get a basic shell")
160-
self.server_os_platform = "Network Devices"
161-
shell_access = False
162-
else:
163-
shell_access = True
164-
165-
self.db.add_loggedin_relation(cred_id, host_id, shell=shell_access)
166-
167-
if shell_access and self.server_os_platform == "Linux":
147+
# Some IOT devices will not raise exception in self.conn._transport.auth_password / self.conn._transport.auth_publickey
148+
# Check Linux
149+
stdout = self.conn.exec_command("id")[1].read().decode(self.args.codec, errors="ignore")
150+
if stdout:
151+
self.server_os_platform = "Linux"
152+
self.logger.debug(f"Linux detected for user: {stdout}")
153+
self.shell_access = True
168154
self.check_linux_priv()
169155
if self.admin_privs:
170156
self.logger.debug(f"User {self.username} logged in successfully and is root!")
171157
if self.args.key_file:
172158
self.db.add_admin_user("key", self.username, self.password, host_id=host_id, cred_id=cred_id)
173159
else:
174160
self.db.add_admin_user("plaintext", self.username, self.password, host_id=host_id, cred_id=cred_id)
161+
return
162+
163+
# Check Windows
164+
stdout = self.conn.exec_command("whoami /priv")[1].read().decode(self.args.codec, errors="ignore")
165+
if stdout:
166+
self.server_os_platform = "Windows"
167+
self.logger.debug(f"Windows detected for user: {stdout}")
168+
self.shell_access = True
169+
self.check_windows_priv(stdout)
170+
self.db.add_loggedin_relation(cred_id, host_id, shell=self.shell_access)
171+
return
172+
173+
# No shell access
174+
self.shell_access = False
175+
self.logger.debug(f"User: {self.username} can't get a basic shell")
176+
self.server_os_platform = "Network Devices"
177+
self.db.add_loggedin_relation(cred_id, host_id, shell=self.shell_access)
175178

176-
out = process_secret(self.password) if not self.args.key_file else f"{process_secret(self.password)} (keyfile: {self.args.key_file})"
177-
display_shell_access = f"{self.uac}{self.server_os_platform}{' - Shell access!' if shell_access else ''}"
178-
self.logger.success(f"{self.username}:{process_secret(out)} {self.mark_pwned()} {highlight(display_shell_access)}")
179+
def check_windows_priv(self, stdout):
180+
if "SeDebugPrivilege" in stdout:
181+
self.admin_privs = True
182+
elif "SeUndockPrivilege" in stdout:
183+
self.admin_privs = True
184+
self.uac = "with UAC - "
179185

180186
def check_linux_priv(self):
181187
self.admin_privs = False

0 commit comments

Comments
 (0)