clean and fix imports

main
Marshall Hallenbeck 2023-05-07 18:51:01 -04:00
parent 13f4ebbb2b
commit fcfebc21e2
12 changed files with 130 additions and 109 deletions

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
from os import mkdir from os import mkdir
from os.path import exists from os.path import exists
from os.path import join as path_join from os.path import join as path_join

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json
from impacket.ldap import ldapasn1 as ldapasn1_impacket from impacket.ldap import ldapasn1 as ldapasn1_impacket
@ -60,7 +61,8 @@ class CMEModule:
} }
if "mslaps-encryptedpassword" in values: if "mslaps-encryptedpassword" in values:
context.log.fail( context.log.fail(
"LAPS password is encrypted and currently CrackMapExec doesn't support the decryption..." "LAPS password is encrypted and currently CrackMapExec doesn't"
" support the decryption..."
) )
return return
@ -73,7 +75,8 @@ class CMEModule:
) )
else: else:
context.log.fail( context.log.fail(
"No result found with attribute ms-MCS-AdmPwd or msLAPS-Password" "No result found with attribute ms-MCS-AdmPwd or"
" msLAPS-Password"
) )
laps_computers = sorted(laps_computers, key=lambda x: x[0]) laps_computers = sorted(laps_computers, key=lambda x: x[0])

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import socket
import ldap3 import ldap3
import ssl import ssl
@ -75,7 +76,8 @@ class CMEModule:
except Exception as e: except Exception as e:
context.log.fail("\n [!] " + dcTarget + " -", str(e)) context.log.fail("\n [!] " + dcTarget + " -", str(e))
context.log.fail( context.log.fail(
" * Ensure DNS is resolving properly, and that you can reach LDAPS on this host" " * Ensure DNS is resolving properly, and that you can reach"
" LDAPS on this host"
) )
# Conduct a bind to LDAPS with channel binding supported # Conduct a bind to LDAPS with channel binding supported

View File

@ -2,19 +2,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import sys
from impacket import system_errors, version from impacket import system_errors
from impacket.dcerpc.v5.rpcrt import DCERPCException from impacket.dcerpc.v5.rpcrt import DCERPCException
from impacket.structure import Structure from impacket.structure import Structure
from impacket.examples import logger
from impacket.examples.utils import parse_target
from impacket.dcerpc.v5 import transport, rprn from impacket.dcerpc.v5 import transport, rprn
from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER, NDRSTRUCT, NDRUNION, NULL from impacket.dcerpc.v5.ndr import NDRCALL, NDRPOINTER, NDRSTRUCT, NDRUNION, NULL
from impacket.dcerpc.v5.dtypes import DWORD, LPWSTR, ULONG, WSTR from impacket.dcerpc.v5.dtypes import DWORD, LPWSTR, ULONG, WSTR
from impacket.dcerpc.v5.rprn import ( from impacket.dcerpc.v5.rprn import checkNullString, STRING_HANDLE, PBYTE_ARRAY
checkNullString,
STRING_HANDLE,
PBYTE_ARRAY,
)
KNOWN_PROTOCOLS = { KNOWN_PROTOCOLS = {
135: {"bindstr": r"ncacn_ip_tcp:%s[135]"}, 135: {"bindstr": r"ncacn_ip_tcp:%s[135]"},
@ -232,18 +226,12 @@ class DRIVER_INFO_2_ARRAY(Structure):
class DRIVER_INFO_UNION(NDRUNION): class DRIVER_INFO_UNION(NDRUNION):
commonHdr = (("tag", ULONG),) commonHdr = (("tag", ULONG),)
union = { union = {1: ("pNotUsed", PDRIVER_INFO_1), 2: ("Level2", PDRIVER_INFO_2)}
1: ("pNotUsed", PDRIVER_INFO_1),
2: ("Level2", PDRIVER_INFO_2),
}
# MS-RPRN - 3.1.4.1.8.3 # MS-RPRN - 3.1.4.1.8.3
class DRIVER_CONTAINER(NDRSTRUCT): class DRIVER_CONTAINER(NDRSTRUCT):
structure = ( structure = (("Level", DWORD), ("DriverInfo", DRIVER_INFO_UNION))
("Level", DWORD),
("DriverInfo", DRIVER_INFO_UNION),
)
################################################################################ ################################################################################

View File

@ -6,9 +6,13 @@
# v0.4 # v0.4
import base64 import base64
import re
import sys
from pypykatz.pypykatz import pypykatz from pypykatz.pypykatz import pypykatz
from cme.helpers.bloodhound import add_user_bh
class CMEModule: class CMEModule:
name = "procdump" name = "procdump"
@ -69,7 +73,7 @@ class CMEModule:
) )
) )
except Exception as e: except Exception as e:
context.log.fail("Error writing file to share {}: {}".format(share, e)) context.log.fail(f"Error writing file to share {self.share}: {e}")
# get pid lsass # get pid lsass
command = 'tasklist /v /fo csv | findstr /i "lsass"' command = 'tasklist /v /fo csv | findstr /i "lsass"'

View File

@ -2,6 +2,7 @@
# Credit to https://github.com/dirkjanm/adidnsdump @_dirkjan # Credit to https://github.com/dirkjanm/adidnsdump @_dirkjan
# module by @mpgn_x64 # module by @mpgn_x64
from os.path import expanduser
import codecs import codecs
import socket import socket
from builtins import str from builtins import str
@ -40,8 +41,9 @@ def get_dns_resolver(server, context):
dnsresolver.nameservers = [server] dnsresolver.nameservers = [server]
except socket.error: except socket.error:
context.info( context.info(
"Using System DNS to resolve unknown entries. Make sure resolving your target domain works here or specify an IP" "Using System DNS to resolve unknown entries. Make sure resolving your"
" as target host to use that server for queries" " target domain works here or specify an IP as target host to use that"
" server for queries"
) )
return dnsresolver return dnsresolver
@ -137,7 +139,8 @@ class CMEModule:
except ldap.LDAPSearchError as e: except ldap.LDAPSearchError as e:
if e.getErrorString().find("sizeLimitExceeded") >= 0: if e.getErrorString().find("sizeLimitExceeded") >= 0:
context.log.debug( context.log.debug(
"sizeLimitExceeded exception caught, giving up and processing the data received" "sizeLimitExceeded exception caught, giving up and processing the"
" data received"
) )
# We reached the sizeLimit, process the answers we have already and that's it. Until we implement # We reached the sizeLimit, process the answers we have already and that's it. Until we implement
# paged queries # paged queries
@ -205,7 +208,7 @@ class CMEModule:
) )
context.log.highlight("Found %d records" % len(outdata)) context.log.highlight("Found %d records" % len(outdata))
path = os.path.expanduser( path = expanduser(
"~/.cme/logs/{}_network_{}.log".format( "~/.cme/logs/{}_network_{}.log".format(
connection.domain, datetime.now().strftime("%Y-%m-%d_%H%M%S") connection.domain, datetime.now().strftime("%Y-%m-%d_%H%M%S")
) )
@ -225,7 +228,8 @@ class CMEModule:
context.log.success("Dumped {} records to {}".format(len(outdata), path)) context.log.success("Dumped {} records to {}".format(len(outdata), path))
if not self.showall and not self.showhosts: if not self.showall and not self.showhosts:
context.log.display( context.log.display(
"To extract CIDR from the {} ip, run the following command: cat your_file | mapcidr -aa -silent | mapcidr -a -silent".format( "To extract CIDR from the {} ip, run the following command: cat"
" your_file | mapcidr -aa -silent | mapcidr -a -silent".format(
len(outdata) len(outdata)
) )
) )

View File

@ -130,13 +130,10 @@ class KerberosAttacks:
).decode(), ).decode(),
) )
else: else:
logging.error( cme_logger.error(
"Skipping %s/%s due to incompatible e-type %d" "Skipping"
% ( f" {decodedTGS['ticket']['sname']['name-string'][0]}/{decodedTGS['ticket']['sname']['name-string'][1]} due"
decodedTGS["ticket"]["sname"]["name-string"][0], f" to incompatible e-type {decodedTGS['ticket']['enc-part']['etype']:d}"
decodedTGS["ticket"]["sname"]["name-string"][1],
decodedTGS["ticket"]["enc-part"]["etype"],
)
) )
return entry return entry

View File

@ -8,7 +8,6 @@ from os import getenv
from impacket.krb5.ccache import CCache from impacket.krb5.ccache import CCache
from cme.connection import * from cme.connection import *
from cme.helpers.bloodhound import add_user_bh from cme.helpers.bloodhound import add_user_bh
from cme.helpers.logger import highlight
from cme.logger import CMEAdapter from cme.logger import CMEAdapter
from aardwolf.connection import RDPConnection from aardwolf.connection import RDPConnection
from aardwolf.commons.queuedata.constants import VIDEO_FORMAT from aardwolf.commons.queuedata.constants import VIDEO_FORMAT
@ -96,7 +95,10 @@ class rdp(connection):
rdp_parser.add_argument( rdp_parser.add_argument(
"--no-bruteforce", "--no-bruteforce",
action="store_true", action="store_true",
help="No spray when using file for username and password (user1 => password1, user2 => password2", help=(
"No spray when using file for username and password (user1 =>"
" password1, user2 => password2"
),
) )
rdp_parser.add_argument( rdp_parser.add_argument(
"--continue-on-success", "--continue-on-success",
@ -175,11 +177,13 @@ class rdp(connection):
def print_host_info(self): def print_host_info(self):
if self.domain is None: if self.domain is None:
self.logger.display( self.logger.display(
f"Probably old, doesn't not support HYBRID or HYBRID_EX (nla:{self.nla})" "Probably old, doesn't not support HYBRID or HYBRID_EX"
f" (nla:{self.nla})"
) )
else: else:
self.logger.display( self.logger.display(
f"{self.server_os} (name:{self.hostname}) (domain:{self.domain}) (nla:{self.nla})" f"{self.server_os} (name:{self.hostname}) (domain:{self.domain})"
f" (nla:{self.nla})"
) )
return True return True
@ -340,6 +344,7 @@ class rdp(connection):
"{}\\{}{} {}".format( "{}\\{}{} {}".format(
domain, domain,
username, username,
(
# Show what was used between cleartext, nthash, aesKey and ccache # Show what was used between cleartext, nthash, aesKey and ccache
" from ccache" " from ccache"
if useCache if useCache
@ -348,6 +353,7 @@ class rdp(connection):
kerb_pass kerb_pass
if not self.config.get("CME", "audit_mode") if not self.config.get("CME", "audit_mode")
else self.config.get("CME", "audit_mode") * 8 else self.config.get("CME", "audit_mode") * 8
)
), ),
self.mark_pwned(), self.mark_pwned(),
) )
@ -364,13 +370,17 @@ class rdp(connection):
if word in str(e): if word in str(e):
reason = self.rdp_error_status[word] reason = self.rdp_error_status[word]
self.logger.fail( self.logger.fail(
f"{domain}\\{username}{' from ccache' if useCache else ':%s' % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode') * 8)} {f'({reason})' if reason else str(e)}", (
color="magenta" f"{domain}\\{username}{' from ccache' if useCache else ':%s' % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode') * 8)} {f'({reason})' if reason else str(e)}"
),
color=(
"magenta"
if ( if (
(reason or "CredSSP" in str(e)) (reason or "CredSSP" in str(e))
and reason != "KDC_ERR_C_PRINCIPAL_UNKNOWN" and reason != "KDC_ERR_C_PRINCIPAL_UNKNOWN"
) )
else "red", else "red"
),
) )
elif "Authentication failed!" in str(e): elif "Authentication failed!" in str(e):
self.logger.success( self.logger.success(
@ -386,13 +396,17 @@ class rdp(connection):
if "cannot unpack non-iterable NoneType object" == str(e): if "cannot unpack non-iterable NoneType object" == str(e):
reason = "User valid but cannot connect" reason = "User valid but cannot connect"
self.logger.fail( self.logger.fail(
f"{domain}\\{username}{' from ccache' if useCache else ':%s' % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode') * 8)} {f'({reason})' if reason else ''}", (
color="magenta" f"{domain}\\{username}{' from ccache' if useCache else ':%s' % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode') * 8)} {f'({reason})' if reason else ''}"
),
color=(
"magenta"
if ( if (
(reason or "CredSSP" in str(e)) (reason or "CredSSP" in str(e))
and reason != "STATUS_LOGON_FAILURE" and reason != "STATUS_LOGON_FAILURE"
) )
else "red", else "red"
),
) )
return False return False
@ -428,13 +442,17 @@ class rdp(connection):
if "cannot unpack non-iterable NoneType object" == str(e): if "cannot unpack non-iterable NoneType object" == str(e):
reason = "User valid but cannot connect" reason = "User valid but cannot connect"
self.logger.fail( self.logger.fail(
f"{domain}\\{username}:{password} {f'({reason})' if reason else ''}", (
color="magenta" f"{domain}\\{username}:{password} {f'({reason})' if reason else ''}"
),
color=(
"magenta"
if ( if (
(reason or "CredSSP" in str(e)) (reason or "CredSSP" in str(e))
and reason != "STATUS_LOGON_FAILURE" and reason != "STATUS_LOGON_FAILURE"
) )
else "red", else "red"
),
) )
return False return False
@ -473,13 +491,17 @@ class rdp(connection):
reason = "User valid but cannot connect" reason = "User valid but cannot connect"
self.logger.fail( self.logger.fail(
f"{domain}\\{username}:{ntlm_hash} {f'({reason})' if reason else ''}", (
color="magenta" f"{domain}\\{username}:{ntlm_hash} {f'({reason})' if reason else ''}"
),
color=(
"magenta"
if ( if (
(reason or "CredSSP" in str(e)) (reason or "CredSSP" in str(e))
and reason != "STATUS_LOGON_FAILURE" and reason != "STATUS_LOGON_FAILURE"
) )
else "red", else "red"
),
) )
return False return False

View File

@ -5,10 +5,12 @@
# Code refactored and added to by @mjhallenbeck (Marshall-Hallenbeck on GitHub) # Code refactored and added to by @mjhallenbeck (Marshall-Hallenbeck on GitHub)
import logging import logging
from impacket.dcerpc.v5 import transport, lsat, lsad, samr from impacket.dcerpc.v5 import transport, lsat, lsad, samr
from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_GSS_NEGOTIATE from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_GSS_NEGOTIATE
from impacket.nmb import NetBIOSError
from impacket.smbconnection import SessionError
from cme.logger import cme_logger from cme.logger import cme_logger
@ -150,10 +152,10 @@ class SAMRQuery:
dce = rpc_transport.get_dce_rpc() dce = rpc_transport.get_dce_rpc()
dce.connect() dce.connect()
dce.bind(samr.MSRPC_UUID_SAMR) dce.bind(samr.MSRPC_UUID_SAMR)
except impacket.nmb.NetBIOSError as e: except NetBIOSError as e:
logging.error(f"NetBIOSError on Connection: {e}") logging.error(f"NetBIOSError on Connection: {e}")
return return
except impacket.smbconnection.SessionError as e: except SessionError as e:
logging.error(f"SessionError on Connection: {e}") logging.error(f"SessionError on Connection: {e}")
return return
return dce return dce
@ -232,6 +234,7 @@ class LSAQuery:
self.__kerberos = kerberos self.__kerberos = kerberos
self.dce = self.get_dce() self.dce = self.get_dce()
self.policy_handle = self.get_policy_handle() self.policy_handle = self.get_policy_handle()
self.logger = cme_logger
def get_transport(self): def get_transport(self):
string_binding = f"ncacn_np:{self.__remote_name}[\\pipe\\lsarpc]" string_binding = f"ncacn_np:{self.__remote_name}[\\pipe\\lsarpc]"
@ -260,7 +263,7 @@ class LSAQuery:
dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE) dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE)
dce.connect() dce.connect()
dce.bind(lsat.MSRPC_UUID_LSAT) dce.bind(lsat.MSRPC_UUID_LSAT)
except impacket.nmb.NetBIOSError as e: except NetBIOSError as e:
self.logger.fail(f"NetBIOSError on Connection: {e}") self.logger.fail(f"NetBIOSError on Connection: {e}")
return None return None
return dce return dce

View File

@ -2,7 +2,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging import logging
import sys
from io import StringIO from io import StringIO
import paramiko import paramiko
@ -32,12 +31,18 @@ class ssh(connection):
ssh_parser.add_argument( ssh_parser.add_argument(
"--no-bruteforce", "--no-bruteforce",
action="store_true", action="store_true",
help="No spray when using file for username and password (user1 => password1, user2 => password2", help=(
"No spray when using file for username and password (user1 =>"
" password1, user2 => password2"
),
) )
ssh_parser.add_argument( ssh_parser.add_argument(
"--key-file", "--key-file",
type=str, type=str,
help="Authenticate using the specified private key. Treats the password parameter as the key's passphrase.", help=(
"Authenticate using the specified private key. Treats the password"
" parameter as the key's passphrase."
),
) )
ssh_parser.add_argument( ssh_parser.add_argument(
"--port", type=int, default=22, help="SSH port (default: 22)" "--port", type=int, default=22, help="SSH port (default: 22)"

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from cme.helpers.misc import validate_ntlm
from cme.cmedb import DatabaseNavigator, print_table, print_help from cme.cmedb import DatabaseNavigator, print_table, print_help
@ -310,7 +309,8 @@ class navigator(DatabaseNavigator):
def do_clear_database(self, line): def do_clear_database(self, line):
if ( if (
input( input(
"This will destroy all data in the current database, are you SURE you want to run this? (y/n): " "This will destroy all data in the current database, are you SURE you"
" want to run this? (y/n): "
) )
== "y" == "y"
): ):

View File

@ -5,28 +5,15 @@ import hashlib
from datetime import datetime from datetime import datetime
import os import os
import requests import requests
from impacket.smbconnection import SMBConnection, SessionError from impacket.smbconnection import SMBConnection
from cme.config import process_secret from cme.config import process_secret
from cme.connection import * from cme.connection import *
from cme.helpers.logger import highlight
from cme.helpers.bloodhound import add_user_bh from cme.helpers.bloodhound import add_user_bh
from cme.protocols.ldap.smbldap import LDAPConnect from cme.protocols.ldap.smbldap import LDAPConnect
from cme.logger import CMEAdapter from cme.logger import CMEAdapter
from pypsrp.client import Client from pypsrp.client import Client
from impacket.examples.secretsdump import LocalOperations, LSASecrets, SAMHashes from impacket.examples.secretsdump import LocalOperations, LSASecrets, SAMHashes
import logging
# The following disables the InsecureRequests warning and the 'Starting new HTTPS connection' log message
# from requests.packages.urllib3.exceptions import InsecureRequestWarning
#
# requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# class SuppressFilter(logging.Filter):
# # remove warning https://github.com/diyan/pywinrm/issues/269
# def filter(self, record):
# return "wsman" not in record.getMessage()
class winrm(connection): class winrm(connection):
@ -59,7 +46,10 @@ class winrm(connection):
winrm_parser.add_argument( winrm_parser.add_argument(
"--no-bruteforce", "--no-bruteforce",
action="store_true", action="store_true",
help="No spray when using file for username and password (user1 => password1, user2 => password2", help=(
"No spray when using file for username and password (user1 =>"
" password1, user2 => password2"
),
) )
winrm_parser.add_argument( winrm_parser.add_argument(
"--continue-on-success", "--continue-on-success",
@ -273,7 +263,8 @@ class winrm(connection):
} }
if "mslaps-encryptedpassword" in values: if "mslaps-encryptedpassword" in values:
self.logger.fail( self.logger.fail(
"LAPS password is encrypted and currently CrackMapExec doesn't support the decryption..." "LAPS password is encrypted and currently CrackMapExec doesn't"
" support the decryption..."
) )
return False return False
elif "mslaps-password" in values: elif "mslaps-password" in values:
@ -286,7 +277,8 @@ class winrm(connection):
msMCSAdmPwd = values["ms-mcs-admpwd"] msMCSAdmPwd = values["ms-mcs-admpwd"]
else: else:
self.logger.fail( self.logger.fail(
"No result found with attribute ms-MCS-AdmPwd or msLAPS-Password" "No result found with attribute ms-MCS-AdmPwd or"
" msLAPS-Password"
) )
self.logger.debug( self.logger.debug(
"Host: {:<20} Password: {} {}".format( "Host: {:<20} Password: {} {}".format(
@ -295,9 +287,8 @@ class winrm(connection):
) )
else: else:
self.logger.fail( self.logger.fail(
"msMCSAdmPwd or msLAPS-Password is empty or account cannot read LAPS property for {}".format( "msMCSAdmPwd or msLAPS-Password is empty or account cannot read LAPS"
self.hostname " property for {}".format(self.hostname)
)
) )
return False return False
@ -306,9 +297,8 @@ class winrm(connection):
if msMCSAdmPwd == "": if msMCSAdmPwd == "":
self.logger.fail( self.logger.fail(
"msMCSAdmPwd or msLAPS-Password is empty or account cannot read LAPS property for {}".format( "msMCSAdmPwd or msLAPS-Password is empty or account cannot read LAPS"
self.hostname " property for {}".format(self.hostname)
)
) )
return False return False
if ntlm_hash: if ntlm_hash:
@ -347,7 +337,8 @@ class winrm(connection):
self.logger.debug(f"winrm create_conn_obj() - Requesting URL: {url}") self.logger.debug(f"winrm create_conn_obj() - Requesting URL: {url}")
res = requests.post(url, verify=False, timeout=self.args.http_timeout) res = requests.post(url, verify=False, timeout=self.args.http_timeout)
self.logger.debug( self.logger.debug(
f"winrm create_conn_obj() - Received response code: {res.status_code}" "winrm create_conn_obj() - Received response code:"
f" {res.status_code}"
) )
self.endpoint = url self.endpoint = url
if self.endpoint.startswith("https://"): if self.endpoint.startswith("https://"):
@ -526,7 +517,8 @@ class winrm(connection):
r = self.conn.execute_cmd(self.args.execute) r = self.conn.execute_cmd(self.args.execute)
except: except:
self.logger.info( self.logger.info(
"Cannot execute command, probably because user is not local admin, but powershell command should be ok!" "Cannot execute command, probably because user is not local admin, but"
" powershell command should be ok!"
) )
r = self.conn.execute_ps(self.args.execute) r = self.conn.execute_ps(self.args.execute)
self.logger.success("Executed command") self.logger.success("Executed command")
@ -539,7 +531,8 @@ class winrm(connection):
def sam(self): def sam(self):
self.conn.execute_cmd( self.conn.execute_cmd(
"reg save HKLM\SAM C:\\windows\\temp\\SAM && reg save HKLM\SYSTEM C:\\windows\\temp\\SYSTEM" "reg save HKLM\SAM C:\\windows\\temp\\SAM && reg save HKLM\SYSTEM"
" C:\\windows\\temp\\SYSTEM"
) )
self.conn.fetch("C:\\windows\\temp\\SAM", self.output_filename + ".sam") self.conn.fetch("C:\\windows\\temp\\SAM", self.output_filename + ".sam")
self.conn.fetch("C:\\windows\\temp\\SYSTEM", self.output_filename + ".system") self.conn.fetch("C:\\windows\\temp\\SYSTEM", self.output_filename + ".system")
@ -560,7 +553,8 @@ class winrm(connection):
def lsa(self): def lsa(self):
self.conn.execute_cmd( self.conn.execute_cmd(
"reg save HKLM\SECURITY C:\\windows\\temp\\SECURITY && reg save HKLM\SYSTEM C:\\windows\\temp\\SYSTEM" "reg save HKLM\SECURITY C:\\windows\\temp\\SECURITY && reg save HKLM\SYSTEM"
" C:\\windows\\temp\\SYSTEM"
) )
self.conn.fetch( self.conn.fetch(
"C:\\windows\\temp\\SECURITY", f"{self.output_filename}.security" "C:\\windows\\temp\\SECURITY", f"{self.output_filename}.security"