Skip to content

Commit 761da40

Browse files
authored
added comment lines
Signed-off-by: termanix <50464194+termanix@users.noreply.github.com>
1 parent fb51b53 commit 761da40

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

nxc/modules/change-password.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ def options(self, context, module_options):
4242
sys.exit(1)
4343

4444
def authenticate(self, context, connection, protocol, anonymous=False):
45+
# Authenticate to the target using DCE/RPC with either user credentials or a null session. Establishes a connection and binds to the SAMR service.
4546
try:
47+
# Map to the SAMR endpoint on the target
4648
string_binding = epm.hept_map(connection.host, samr.MSRPC_UUID_SAMR, protocol=protocol)
4749
rpctransport = transport.DCERPCTransportFactory(string_binding)
4850
rpctransport.setRemoteHost(connection.host)
@@ -62,6 +64,7 @@ def authenticate(self, context, connection, protocol, anonymous=False):
6264
)
6365
context.log.info(f"Connecting as {connection.domain}\\{connection.username}")
6466

67+
# Connect to the DCE/RPC endpoint and bind to the SAMR service
6568
dce = rpctransport.get_dce_rpc()
6669
dce.connect()
6770
context.log.info("[+] Successfully connected to DCE/RPC")
@@ -79,6 +82,7 @@ def on_login(self, context, connection):
7982

8083
new_lmhash, new_nthash = "", ""
8184

85+
# Parse new hash values if provided
8286
if self.newhash:
8387
try:
8488
new_lmhash, new_nthash = self.newhash.split(":")
@@ -89,6 +93,7 @@ def on_login(self, context, connection):
8993
self.anonymous = False
9094
self.dce = self.authenticate(context, connection, protocol="ncacn_np", anonymous=self.anonymous)
9195
except Exception as e:
96+
# Handle specific errors like password expiration or must be change
9297
if "STATUS_PASSWORD_MUST_CHANGE" in str(e) or "STATUS_PASSWORD_EXPIRED" in str(e):
9398
context.log.warning("Password must be changed. Trying with null session.")
9499
self.anonymous = True
@@ -100,29 +105,33 @@ def on_login(self, context, connection):
100105
raise
101106

102107
try:
108+
# Perform the SMB SAMR password change
103109
self._smb_samr_change(context, connection, target_username, target_domain, self.oldhash, self.newpass, new_nthash)
104110
except Exception as e:
105111
context.log.error(f"Password change failed: {e}")
106112

107113
def _smb_samr_change(self, context, connection, target_username, target_domain, oldHash, newPassword, newHash):
108114
try:
109115
if not self.anonymous:
110-
server_handle = samr.hSamrConnect(self.dce, connection.host + "\x00")["ServerHandle"]
116+
# Connect to the target server and retrieve handles
117+
server_handle = samr.hSamrConnect(self.dce, connection.host + "\x00")["ServerHandle"] # Does not work for null session auth.
111118
domain_sid = samr.hSamrLookupDomainInSamServer(self.dce, server_handle, target_domain)["DomainId"]
112119
domain_handle = samr.hSamrOpenDomain(self.dce, server_handle, domainId=domain_sid)["DomainHandle"]
113120
user_rid = samr.hSamrLookupNamesInDomain(self.dce, domain_handle, (target_username,))["RelativeIds"]["Element"][0]
114121
user_handle = samr.hSamrOpenUser(self.dce, domain_handle, userId=user_rid)["UserHandle"]
115122

116123
if self.reset:
124+
# Change the password with new password hash
117125
samr.hSamrSetNTInternal1(self.dce, user_handle, newPassword, newHash)
118126
context.log.success(f"Successfully changed password for {target_username}")
119127
else:
120-
128+
# Change the password with new password
121129
samr.hSamrUnicodeChangePasswordUser2(
122130
self.dce, "\x00", target_username, self.oldpass, newPassword, "", ""
123131
)
124132
context.log.success(f"Successfully changed password for {target_username}")
125133
else:
134+
# Handle anonymous/null session password change
126135
self.mustchangePassword(target_username, target_domain, self.oldpass, newPassword, "", oldHash, "", newHash)
127136
except Exception as e:
128137
context.log.fail(f"SMB-SAMR password change failed: {e}")
@@ -131,11 +140,14 @@ def _smb_samr_change(self, context, connection, target_username, target_domain,
131140

132141
def mustchangePassword(self, target_username, targetDomain, oldPassword, newPassword, oldPwdHashLM, oldPwdHashNT, newPwdHashLM, newPwdHashNT):
133142
if newPassword and oldPassword:
143+
# Change password using old and new plaintext passwords
134144
samr.hSamrUnicodeChangePasswordUser2(self.dce, "\x00", target_username, oldPassword, newPassword, "", "")
135145
self.context.log.success(f"Successfully changed password for {target_username}")
136146
elif newPassword and oldPwdHashNT:
147+
# Change password using hash for authentication
137148
samr.hSamrUnicodeChangePasswordUser2(self.dce, "\x00", target_username, oldPassword, newPassword, "", oldPwdHashNT)
138149
self.context.log.success(f"Successfully changed password for {target_username}")
139150
else:
151+
# Use NT internal function to set new password or hash
140152
samr.hSamrSetNTInternal1(self.dce, target_username, newPassword, newPwdHashNT)
141153
self.context.log.success(f"Successfully changed password for {target_username}")

0 commit comments

Comments
 (0)