Compare commits

..
17 Commits
Author SHA1 Message Date
Alexander Neff 7ece66762e Update paramiko to latest version due to debian update 2024-05-29 10:51:22 -04:00
Alexander Neff 81e4360004 Merge branch 'main' into kali 2024-05-29 10:47:21 -04:00
Alexander Neff f06d50d931 Fix lock file 2024-05-27 18:49:51 -04:00
Alexander Neff 8e511c192c Merge branch 'ItsAlwaysDNS' into kali 2024-05-27 18:49:18 -04:00
Alexander Neff e86e13f7fd Add commit name kali to the kali packaging branch 2024-04-27 18:54:12 -04:00
Alexander Neff c873246a11 Add msldap=^0.5.10 2024-04-23 18:33:11 -04:00
Alexander Neff 144690d846 Merging neff-dependencies into kali-packaging 2024-04-22 16:17:11 -04:00
Alexander Neff ee88b806b7 Merging main into kali-packaging 2024-04-22 15:52:50 -04:00
Alexander Neff e37c868529 Losening the sqlalchemy version 2024-04-20 19:55:20 -04:00
Alexander Neff bc50a2ce87 Merge main into kali-packaging 2024-04-18 19:11:21 -04:00
Alexander Neff 2189b45c5b Merge branch 'main' into kali-packaging 2024-04-01 19:41:54 -04:00
Alexander Neff 9aaff6fa06 Adjusting versions 2024-04-01 10:04:29 -04:00
Alexander Neff 9d2d1b65d1 Merge branch 'main' into kali-packaging 2024-04-01 09:21:59 -04:00
Marshall Hallenbeck 49513cc1c3 fixes for sqlalchemy downgrade if needed 2024-03-29 18:06:52 -04:00
Alexander Neff 35fe8b33e6 Reset sqlalchemy to original state 2024-03-27 19:18:06 +01:00
Alexander Neff 160681056b Bump aardwolf and asyauth to prevent installation from crashing 2024-03-27 19:03:05 +01:00
Alexander Neff 3e2e57dd7a Pinning dependencies to kali versions, see #211 2024-03-27 03:05:50 +01:00
25 changed files with 167 additions and 756 deletions

No files matched your search

+1
View File
@@ -23,6 +23,7 @@ def gen_cli_args():
VERSION = importlib.metadata.version("netexec")
COMMIT = ""
CODENAME = "ItsAlwaysDNS"
COMMIT = "kali"
nxc_logger.debug(f"NXC VERSION: {VERSION} - {CODENAME} - {COMMIT}")
generic_parser = argparse.ArgumentParser(add_help=False, formatter_class=DisplayDefaultsNotNone)
+5 -15
View File
@@ -412,22 +412,12 @@ class connection:
for ntlm_hash in self.args.hash:
if isfile(ntlm_hash):
with open(ntlm_hash) as ntlm_hash_file:
for i, line in enumerate(ntlm_hash_file):
line = line.strip()
if len(line) != 32 and len(line) != 65:
self.logger.fail(f"Invalid NTLM hash length on line {(i + 1)} (len {len(line)}): {line}")
continue
else:
secret.append(line)
cred_type.append("hash")
for line in ntlm_hash_file:
secret.append(line.strip())
cred_type.append("hash")
else:
if len(ntlm_hash) != 32 and len(ntlm_hash) != 65:
self.logger.fail(f"Invalid NTLM hash length {len(ntlm_hash)}, authentication not sent")
exit(1)
else:
secret.append(ntlm_hash)
cred_type.append("hash")
self.logger.debug(secret)
secret.append(ntlm_hash)
cred_type.append("hash")
# Parse AES keys
if self.args.aesKey:
+1 -1
View File
@@ -12,7 +12,7 @@ from nxc.paths import WORKSPACE_DIR
def create_db_engine(db_path):
return create_engine(f"sqlite:///{db_path}", isolation_level="AUTOCOMMIT", future=True)
return create_engine(f"sqlite:///{db_path}", isolation_level="AUTOCOMMIT", future=True, connect_args={"check_same_thread": False})
def open_config(config_path):
-8
View File
@@ -247,14 +247,6 @@ conf = {
"services": [{"name": "CSFalconService", "description": "CrowdStrike Falcon Sensor Service"}],
"pipes": [{"name": "CrowdStrike\\{*", "processes": ["CSFalconContainer.exe", "CSFalconService.exe"]}]
},
{
"name": "Cortex",
"services": [
{"name": "xdrhealth", "description": "Cortex XDR Health Helper"},
{"name": "cyserver", "description": " Cortex XDR"}
],
"pipes": []
},
{
"name": "Cybereason",
"services": [
-365
View File
@@ -1,365 +0,0 @@
# Module by @syl
# https://twitter.com/5yrull
# S-1-5-21-3750225908-897271529-2201778708-1103
# 'S-1-5-21-3750225908-897271529-2201778708'
# (Pdb) resp = lsad.hLsarQueryInformationPolicy2(dce, policyHandle, lsad.POLICY_INFORMATION_CLASS.PolicyAccountDomainInformation)
# (Pdb) domainSid = resp['PolicyInformation']['PolicyAccountDomainInfo']['DomainSid'].formatCanonical()
# (Pdb) domainSid
# 'S-1-5-21-3750225908-897271529-2201778708'
# (Pdb) lsat.hLsarLookupSids(dce, policyHandle, ['S-1-5-21-3750225908-897271529-2201778708-1103'],lsat.LSAP_LOOKUP_LEVEL.LsapLookupWksta)
# <impacket.dcerpc.v5.lsat.LsarLookupSidsResponse object at 0x7f041cba9d50>
# (Pdb) resp = lsat.hLsarLookupSids(dce, policyHandle, ['S-1-5-21-3750225908-897271529-2201778708-1103'],lsat.LSAP_LOOKUP_LEVEL.LsapLookupWksta)
# (Pdb) resp
# <impacket.dcerpc.v5.lsat.LsarLookupSidsResponse object at 0x7f041cba9de0>
# (Pdb) resp.__dict__
# {'_isNDR64': False, 'fields': {'ReferencedDomains': <impacket.dcerpc.v5.lsat.PLSAPR_REFERENCED_DOMAIN_LIST object at 0x7f041cba9ea0>, 'TranslatedNames': <impacket.dcerpc.v5.lsat.LSAPR_TRANSLATED_NAMES object at 0x7f041cba9450>, 'MappedCount': <impacket.dcerpc.v5.ndr.NDRULONG object at 0x7f041cba9270>, 'ErrorCode': <impacket.dcerpc.v5.ndr.NDRULONG object at 0x7f041cba8460>}}
# (Pdb) resp.TranslatedNames
# *** AttributeError: 'LsarLookupSidsResponse' object has no attribute 'TranslatedNames'
# (Pdb) resp["TranslatedNames"]
# <impacket.dcerpc.v5.lsat.LSAPR_TRANSLATED_NAMES object at 0x7f041cba9450>
# (Pdb) resp["TranslatedNames"].__dict__
# {'_isNDR64': False, 'fields': {'Entries': <impacket.dcerpc.v5.ndr.NDRULONG object at 0x7f041cba9960>, 'Names': <impacket.dcerpc.v5.lsat.PLSAPR_TRANSLATED_NAME_ARRAY object at 0x7f041cba9a80>}}
# (Pdb) resp["TranslatedNames"]["Names"]
# [<impacket.dcerpc.v5.lsat.LSAPR_TRANSLATED_NAME object at 0x7f041cba8a60>]
# (Pdb) resp["TranslatedNames"]["Names"][0].__dict_
# *** AttributeError: 'LSAPR_TRANSLATED_NAME' object has no attribute '__dict_'
# (Pdb) resp["TranslatedNames"]["Names"][0].__dict__
# {'_isNDR64': False, 'fields': {'Use': <impacket.dcerpc.v5.samr.SID_NAME_USE object at 0x7f041cba8c70>, 'Name': <impacket.dcerpc.v5.dtypes.RPC_UNICODE_STRING object at 0x7f041cba8be0>, 'DomainIndex': <impacket.dcerpc.v5.ndr.NDRLONG object at 0x7f041cba8ca0>}}
# (Pdb) resp["TranslatedNames"]["Names"][0]["name"]
# *** KeyError: 'name'
# (Pdb) resp["TranslatedNames"]["Names"][0]["Name"]
# 'George.Hotz'
# (Pdb)
from impacket.smbconnection import SessionError
from impacket.dcerpc.v5 import transport, lsat, lsad
from impacket.dcerpc.v5.samr import SID_NAME_USE
from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED
from impacket.dcerpc.v5.rpcrt import DCERPCException
from winacl.dtyp.security_descriptor import SECURITY_DESCRIPTOR
from winacl.functions.constants import SE_OBJECT_TYPE
from winacl.dtyp.ace import FILE_ACCESS_MASK
from termcolor import colored
def get_dce_from_smb(conn):
string_binding = rf"ncacn_np:{conn.remoteName}[\pipe\lsarpc]"
rpctransport = transport.DCERPCTransportFactory(string_binding)
rpctransport.set_dport(conn.port)
rpctransport.setRemoteHost(conn.host)
rpctransport.set_credentials(conn.username, conn.password, conn.domain, conn.lmhash, conn.nthash)
return rpctransport.get_dce_rpc()
def lookup_sid(dce, sid):
dce.connect()
dce.bind(lsat.MSRPC_UUID_LSAT)
policy_response = lsad.hLsarOpenPolicy2(dce, MAXIMUM_ALLOWED | lsat.POLICY_LOOKUP_NAMES)
policy_handle = policy_response["PolicyHandle"]
sid_response = lsat.hLsarLookupSids(dce, policy_handle, [sid],lsat.LSAP_LOOKUP_LEVEL.LsapLookupWksta)
sid_name = sid_response["TranslatedNames"]["Names"][0]["Name"]
dce.disconnect()
return sid_name
AVAILABLE_FILTERS = ["ace_mask", "ace_sid", "owner", "group"]
READ_CONTROL = 0x00020000
FILE_SHARE_READ = 0x00000001
FILE_NON_DIRECTORY_FILE = 0x00000040
FILE_DIRECTORY_FILE = 0x00000001
IMPERSONATION = 0x00000002
class SMBACLEnumerator:
AVAILABLE_FILTERS = ["ace_mask", "ace_sid", "owner", "group"]
def __init__(self, connection, context, module_options) -> None:
self.connection = connection
self.smb_connection = connection.conn
self.context = context
self.module_options = module_options
self.filters = self.parse_filters(self.module_options)
self.shares = self.get_shares()
def get_shares(self):
shares = self.connection.shares()
def parse_filters(self, options: dict) -> dict:
...
def get_security_descriptor() -> None:
...
# def get_security_descriptor(file, smb_connection, context, share_name, file_path, filters=None):
# """
# Retrieve the security descriptor of a file on a share.
# Parameters
# ----------
# file: File object.
# smb_connection: SMB connection instance.
# context: Context for logging.
# share_name: Name of the SMB share.
# file_path: Path of the file.
# filters: Optional filters for security descriptor components.
# Returns
# -------
# None: If the file does not meet the filter criteria.
# """
# file_full_path = file_path + file.get_longname()
# tree_id = smb_connection.connectTree(share_name)
# file_id = create_file(smb_connection, tree_id, file_full_path)
# try:
# security_descriptor = smb_connection._SMBConnection.query_sec_info(tree_id, file_id)
# security_descriptor_obj = parse_security_descriptor(security_descriptor)
# if filters and not passes_filters(security_descriptor_obj, filters):
# return
# log_security_descriptor(context, file_full_path, security_descriptor_obj)
# except SessionError as e:
# context.log.debug(e)
# def create_file(smb_connection, tree_id, file_full_path):
# """Create a file in the SMB share and return its ID."""
# return smb_connection.createFile(
# tree_id,
# file_full_path,
# desiredAccess=READ_CONTROL,
# shareMode=FILE_SHARE_READ,
# creationOption=FILE_NON_DIRECTORY_FILE,
# creationDisposition=FILE_DIRECTORY_FILE,
# fileAttributes=0,
# impersonationLevel=IMPERSONATION,
# )
# def parse_security_descriptor(security_descriptor):
# """Parse the security descriptor from bytes to an object."""
# return SECURITY_DESCRIPTOR.from_bytes(
# security_descriptor, object_type=SE_OBJECT_TYPE.SE_FILE_OBJECT
# )
# def passes_filters(security_descriptor_obj, filters):
# """
# Check if the security descriptor object passes the given filter criteria.
# Parameters
# ----------
# security_descriptor_obj: The security descriptor object.
# filters: Dictionary of filter criteria.
# Returns
# -------
# bool: True if the descriptor passes all filters, False otherwise.
# """
# for filter_type, values in filters.items():
# if filter_type == "owner" and str(security_descriptor_obj.Owner) not in values:
# return False
# if filter_type == "group" and str(security_descriptor_obj.Group) not in values:
# return False
# if filter_type == "ace_sid":
# sids = [str(ace.Sid) for ace in security_descriptor_obj.Dacl.aces]
# if not any(sid in sids for sid in values):
# return False
# if filter_type == "ace_mask":
# masks = [FILE_ACCESS_MASK(ace.Mask).name for ace in security_descriptor_obj.Dacl.aces]
# if not any(mask in masks for mask in values):
# return False
# return True
def log_security_descriptor(context, file_path, descriptor_obj):
"""
Log details about the security descriptor.
Parameters
----------
context: Context for logging.
file_path: Path of the file.
descriptor_obj: The security descriptor object.
"""
context.log.success(file_path)
context.log.highlight(f"\t Owner: {descriptor_obj.Owner}")
context.log.highlight(f"\t Group: {descriptor_obj.Group}")
context.log.highlight(f"\t SACL: {descriptor_obj.Sacl}")
if descriptor_obj.Dacl is not None:
context.log.highlight(f"\t ACEs[{len(descriptor_obj.Dacl.aces)}]: ")
for ace in descriptor_obj.Dacl.aces:
ace_str = str(ace)
if "\r\n" in ace_str:
ace_formatted = ace_str.split("\r\n")[:-1]
for line in ace_formatted:
context.log.highlight(f"\t\t {line}")
context.log.highlight("\t\t " + len(ace_formatted[0]) * "=")
else:
context.log.highlight(f"\t\t {ace_str}")
def get_security_descriptor(conn, file, smb_connection, context, share_name, file_path, filters=None):
"""Retrieving the security descriptor of a certain file on a share"""
tree_id = smb_connection.connectTree(share_name)
dce = get_dce_from_smb(conn)
desired_access = 0x00020000 # READ_CONTROL
share_mode = 0x00000001 # FILE_SHARE_READ
create_options = 0x00000040 # FILE_NON_DIRECTORY_FILE
file_attrs = 0
create_disposition = 0x00000001 # FILE_DIRECTORY_FILE
file_full_path = file_path + file.get_longname()
try:
file_id = smb_connection.createFile(
tree_id,
file_full_path,
desiredAccess=desired_access,
shareMode=share_mode,
creationOption=create_options,
creationDisposition=create_disposition,
fileAttributes=file_attrs,
impersonationLevel=0x00000002, # Impersonation
)
security_descriptor = smb_connection._SMBConnection.query_sec_info(tree_id, file_id)
security_descriptor_obj = SECURITY_DESCRIPTOR.from_bytes(
security_descriptor, object_type=SE_OBJECT_TYPE.SE_FILE_OBJECT
)
if filters:
for _filter, values in filters.items():
if _filter == "owner" and str(security_descriptor_obj.Owner) not in values:
return
if _filter == "group" and str(security_descriptor_obj.Group) not in values:
return
if _filter == "ace_sid":
sids = [str(_ace.Sid) for _ace in security_descriptor_obj.Dacl.aces]
for sid in values:
if sid in sids:
continue
else:
return
if _filter == "ace_mask":
masks = [FILE_ACCESS_MASK(_ace.Mask).name for _ace in security_descriptor_obj.Dacl.aces]
for mask in values:
if mask in masks:
continue
else:
return
context.log.success(file_full_path)
# Also get the user's group to mark it as Owned
# smb_connection._SMBConnection._SMB__userName
username = smb_connection._SMBConnection._SMB__userName
owner = lookup_sid(dce, str(security_descriptor_obj.Owner))
if owner == username:
owner = owner + colored("Pwn3d!", "red")
group = lookup_sid(dce, str(security_descriptor_obj.Group))
context.log.highlight(f"\t Owner: {owner}")
context.log.highlight(f"\t Group: {group}")
context.log.highlight(f"\t SACL: {security_descriptor_obj.Sacl}")
if security_descriptor_obj.Dacl is not None:
context.log.highlight("\t ACEs:")
for ace in security_descriptor_obj.Dacl.aces:
ace_sid_name = lookup_sid(dce, str(ace.Sid))
mask_formatted = FILE_ACCESS_MASK(ace.Mask).name
if mask_formatted is None:
continue
owned = colored(" (Own3d!)", "red") if ace_sid_name == username else ""
context.log.highlight(f"\t\t {ace_sid_name} - {mask_formatted}{owned}")
except SessionError as e:
context.log.debug(e)
def enumerate_files(conn, smb_connection, share_name, current_path, context, filters=None):
"""Recursive function that enumerates the directories"""
try:
print(f"{smb_connection=} {share_name=} {current_path=}")
file_list = smb_connection.listPath(share_name, current_path + "*")
for file in file_list:
if (
file.is_directory()
and not file.is_system()
and file.get_longname() not in [".", ".."]
):
next_path = current_path + file.get_longname() + "/"
context.log.debug(f"Trying to enumrate files in {next_path}")
enumerate_files(conn, smb_connection, share_name, next_path, context, filters)
if not file.is_directory() and not file.is_system():
context.log.debug(f"File Found {file.get_longname()}")
get_security_descriptor(conn, file, smb_connection, context, share_name, current_path, filters)
except SessionError as e:
context.log.error(e)
class NXCModule:
"""
A module to enumerate the ACLs of the files in a share.
Module by @syl, thanks to @Skelsec and @NeffIsBack
"""
name = "enum_share_acls"
description = ""
supported_protocols = ["smb"]
opsec_safe = False
multiple_hosts = True
def __init__(self, context=None, module_options=None):
self.context = context
self.module_options = module_options
self.server = None
self.file_path = None
self.lnk_path = None
self.lnk_name = None
self.cleanup = None
def options(self, context, module_options):
"""
group-mem: Specify group-mem to call the module
GROUP: Specify the GROUP option to query for that group's members
Usage:
nxc smb 127.0.0.1 -u administrator -p 'Password123!' -M enum_share_acls -o FILTER="ace_mask=FILE_ALL_ACCESS,ace_sid=S-1-5-32-544"
nxc smb 127.0.0.1 -u administrator -p 'Password123!' -M enum_share_acls -o FILTER="ace_mask=FILE_ALL_ACCESS|READ_CONTROL,ace_sid=S-1-5-32-544"
nxc smb 127.0.0.1 -u administrator -p 'Password123!' -M enum_share_acls -o FILTER="owner=S-1-5-32-544"
"""
self.FILTER = None
if "FILTER" in module_options:
self.FILTER = module_options["FILTER"]
def parse_filters(self):
parsed_filters = self.FILTER.split(",")
filters_dict = {}
masks = [m.name for m in FILE_ACCESS_MASK]
for _filter in parsed_filters:
splitted_filter = _filter.split("=")
if splitted_filter[0] not in AVAILABLE_FILTERS:
return None, f"{_filter} filter isn't available, please choose between {AVAILABLE_FILTERS}"
for __filter in AVAILABLE_FILTERS:
if __filter in _filter:
filters_dict[__filter] = splitted_filter[1]
if "|" in filters_dict[__filter]:
filters_dict[__filter] = filters_dict[__filter].split("|")
else:
filters_dict[__filter] = [splitted_filter[1],]
# Verify the filters
if "ace_mask" in filters_dict:
for mask_name in filters_dict["ace_mask"]:
if mask_name not in masks:
return None, f"{mask_name} ace_mask isn't valid, please choose between {mask_name}"
return filters_dict, None
def on_login(self, context, connection):
shares = connection.shares()
smb_connection = connection.conn
filters = None
if self.FILTER:
filters, err = self.parse_filters()
if err is not None:
context.log.error(err)
for share in shares:
share_name = share["name"]
context.log.display(f"Enumerating ACLs on share: {share_name}")
enumerate_files(connection, smb_connection, share_name, "/", context, filters)
+26 -26
View File
@@ -1,5 +1,7 @@
import os
import sys
import json
from xmltodict import parse
from time import sleep
from csv import reader
from base64 import b64encode
@@ -379,30 +381,28 @@ class NXCModule:
xml_doc_path = os.path.abspath(self.local_export_path + "/" + self.export_name)
xml_tree = ElementTree.parse(xml_doc_path)
root = xml_tree.getroot()
to_string = ElementTree.tostring(root, encoding="UTF-8", method="xml")
xml_to_dict = parse(to_string)
dump = json.dumps(xml_to_dict)
obj = json.loads(dump)
root_entries = root.find("./Root/Entry")
if root_entries is not None:
for entry in root_entries:
if entry is not None:
self.print_password(context, entry)
else:
context.log.highlight("None")
objects = root.findall("./Root/Group")
while objects:
current_object = objects.pop(0)
for entry in current_object.findall("./Entry"):
self.print_password(context, entry)
for history in entry.findall("./History"):
for history_entry in history.findall("./Entry"):
self.print_password(context, history_entry)
objects.extend(current_object.findall("./Group"))
def print_password(self, context, entries):
for entry in entries.findall("./String"):
key = entry.find("./Key")
value = entry.find("./Value")
key_text = key.text if key is not None else "None"
value_text = value.text if value is not None and value.text is not None else "None"
context.log.highlight(f"{key_text} : {value_text}")
context.log.highlight("-------------------------------------")
if len(obj["KeePassFile"]["Root"]["Group"]["Entry"]):
for obj2 in obj["KeePassFile"]["Root"]["Group"]["Entry"]:
for password in obj2["String"]:
if password["Key"] == "Password":
context.log.highlight(str(password["Key"]) + " : " + str(password["Value"]["#text"]))
else:
context.log.highlight(str(password["Key"]) + " : " + str(password["Value"]))
context.log.highlight("")
if len(obj["KeePassFile"]["Root"]["Group"]["Group"]):
for obj2 in obj["KeePassFile"]["Root"]["Group"]["Group"]:
try:
for obj3 in obj2["Entry"]:
for password in obj3["String"]:
if password["Key"] == "Password":
context.log.highlight(str(password["Key"]) + " : " + str(password["Value"]["#text"]))
else:
context.log.highlight(str(password["Key"]) + " : " + str(password["Value"]))
context.log.highlight("")
except KeyError:
pass
-5
View File
@@ -512,11 +512,6 @@ class NXCDBMenu(cmd.Cmd):
def do_exit(line):
sys.exit()
@staticmethod
def do_EOF(line):
sys.exit()
@staticmethod
def help_exit():
help_string = """
+2 -2
View File
@@ -3,7 +3,7 @@ from sqlalchemy.dialects.sqlite import Insert
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy import MetaData, Table, select, delete, func
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -86,7 +86,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
+1 -1
View File
@@ -752,7 +752,7 @@ class ldap(connection):
users = parse_result_attributes(resp)
# we print the total records after we parse the results since often SearchResultReferences are returned
self.logger.display(f"Enumerated {len(users):d} domain users: {self.domain}")
self.logger.display(f"Total records returned: {len(users):d}")
self.logger.highlight(f"{'-Username-':<30}{'-Last PW Set-':<20}{'-BadPW-':<8}{'-Description-':<60}")
for user in users:
# TODO: functionize this - we do this calculation in a bunch of places, different, including in the `pso` module
+2 -2
View File
@@ -2,7 +2,7 @@ from pathlib import Path
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy import MetaData, Table
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -66,7 +66,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
+2 -2
View File
@@ -2,7 +2,7 @@ from pathlib import Path
from sqlalchemy import MetaData, func, Table, select, insert, update, delete
from sqlalchemy.dialects.sqlite import Insert # used for upsert
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -89,7 +89,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
+2 -2
View File
@@ -3,7 +3,7 @@ from pathlib import Path
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy import MetaData, Table
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -69,7 +69,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
+8 -41
View File
@@ -34,7 +34,6 @@ from nxc.helpers.misc import gen_random_string, validate_ntlm
from nxc.logger import NXCAdapter
from nxc.protocols.smb.firefox import FirefoxTriage
from nxc.protocols.smb.kerberos import kerberos_login_with_S4U
from nxc.protocols.smb.smb_share import SMB_Share_Enumeration
from nxc.servers.smb import NXCSMBServer
from nxc.protocols.smb.wmiexec import WMIEXEC
from nxc.protocols.smb.atexec import TSCH_EXEC
@@ -148,9 +147,6 @@ class smb(connection):
def __init__(self, args, db, host):
self.domain = None
self.server_os = None
self.server_os_major = None
self.server_os_minor = None
self.server_os_build = None
self.os_arch = 0
self.hash = None
self.lmhash = ""
@@ -165,7 +161,6 @@ class smb(connection):
self.no_da = None
self.no_ntlm = False
self.protocol = "SMB"
self.is_guest = None
connection.__init__(self, args, db, host)
@@ -234,19 +229,7 @@ class smb(connection):
self.domain = self.hostname
self.targetDomain = self.hostname
# As of June 2024 Samba will always report the version as "Windows 6.1", apparently due to a bug https://stackoverflow.com/a/67577401/17395725
# Together with the reported build version "0" by Samba we can assume that it is a Samba server. Windows should always report a build version > 0
# Also only on Windows we should get an OS arch as for that we would need MSRPC
self.server_os = self.conn.getServerOS()
self.server_os_major = self.conn.getServerOSMajor()
self.server_os_minor = self.conn.getServerOSMinor()
self.server_os_build = self.conn.getServerOSBuild()
if "Windows 6.1" in self.server_os and self.server_os_build == 0 and self.os_arch == 0:
self.server_os = "Unix - Samba"
elif self.server_os_build == 0 and self.os_arch == 0:
self.server_os = "Unix"
self.logger.debug(f"Server OS: {self.server_os} {self.server_os_major}.{self.server_os_minor} build {self.server_os_build}")
self.logger.extra["hostname"] = self.hostname
if isinstance(self.server_os.lower(), bytes):
@@ -327,8 +310,7 @@ class smb(connection):
self.logger.debug(f"Got TGS for {self.args.delegate} through S4U")
self.conn.kerberosLogin(self.username, password, domain, lmhash, nthash, aesKey, kdcHost, useCache=useCache, TGS=tgs)
if "Unix" not in self.server_os:
self.check_if_admin()
self.check_if_admin()
if username == "":
self.username = self.conn.getCredentials()[0]
@@ -393,11 +375,8 @@ class smb(connection):
self.domain = domain
self.conn.login(self.username, self.password, domain)
self.logger.debug(f"Logged in with password to SMB with {domain}/{self.username}")
self.is_guest = bool(self.conn.isGuestSession())
self.logger.debug(f"{self.is_guest=}")
if "Unix" not in self.server_os:
self.check_if_admin()
self.check_if_admin()
self.logger.debug(f"Adding credential: {domain}/{self.username}:{self.password}")
self.db.add_credential("plaintext", domain, self.username, self.password)
user_id = self.db.get_credential("plaintext", domain, self.username, self.password)
@@ -405,7 +384,7 @@ class smb(connection):
self.db.add_loggedin_relation(user_id, host_id)
out = f"{domain}\\{self.username}:{process_secret(self.password)} {self.mark_guest()}{self.mark_pwned()}"
out = f"{domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}"
self.logger.success(out)
if not self.args.local_auth and self.username != "":
@@ -465,17 +444,14 @@ class smb(connection):
self.nthash = nthash
self.conn.login(self.username, "", domain, lmhash, nthash)
self.logger.debug(f"Logged in with hash to SMB with {domain}/{self.username}")
self.is_guest = bool(self.conn.isGuestSession())
self.logger.debug(f"{self.is_guest=}")
if "Unix" not in self.server_os:
self.check_if_admin()
user_id = self.db.add_credential("hash", domain, self.username, self.hash)
self.check_if_admin()
user_id = self.db.add_credential("hash", domain, self.username, nthash)
host_id = self.db.get_hosts(self.host)[0].id
self.db.add_loggedin_relation(user_id, host_id)
out = f"{domain}\\{self.username}:{process_secret(self.hash)} {self.mark_guest()}{self.mark_pwned()}"
out = f"{domain}\\{self.username}:{process_secret(self.hash)} {self.mark_pwned()}"
self.logger.success(out)
if not self.args.local_auth and self.username != "":
@@ -555,7 +531,6 @@ class smb(connection):
return bool(self.create_smbv1_conn() or self.create_smbv3_conn())
def check_if_admin(self):
self.logger.debug(f"Checking if user is admin on {self.host}")
rpctransport = SMBTransport(self.conn.getRemoteHost(), 445, r"\svcctl", smb_connection=self.conn)
dce = rpctransport.get_dce_rpc()
try:
@@ -569,7 +544,6 @@ class smb(connection):
# 0xF003F - SC_MANAGER_ALL_ACCESS
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
scmr.hROpenSCManagerW(dce, f"{self.host}\x00", "ServicesActive\x00", 0xF003F)
self.logger.debug(f"User is admin on {self.host}!")
self.admin_privs = True
except scmr.DCERPCException:
self.admin_privs = False
@@ -755,10 +729,6 @@ class smb(connection):
return response
def shares(self):
if self.args.shares != True:
smb_enumeration = SMB_Share_Enumeration(self, self.conn)
return smb_enumeration.enumerate_path(self.args.shares)
temp_dir = ntpath.normpath("\\" + gen_random_string())
permissions = []
@@ -1804,6 +1774,3 @@ class smb(connection):
except Exception as e:
self.logger.debug(f"Error calling remote_ops.finish(): {e}")
NTDS.finish()
def mark_guest(self):
return highlight(f"{highlight('(Guest)')}" if self.is_guest else "")
+2 -2
View File
@@ -6,7 +6,7 @@ from pathlib import Path
from sqlalchemy import MetaData, func, Table, select, delete
from sqlalchemy.dialects.sqlite import Insert # used for upsert
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -205,7 +205,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
+1 -1
View File
@@ -33,7 +33,7 @@ def proto_args(parser, parents):
cred_gathering_group.add_argument("--user", dest="userntds", type=str, help="Dump selected user from DC")
mapping_enum_group = smb_parser.add_argument_group("Mapping/Enumeration", "Options for Mapping/Enumerating")
mapping_enum_group.add_argument("--shares", nargs="?", default=False, const=True, help="enumerate shares and access")
mapping_enum_group.add_argument("--shares", action="store_true", help="enumerate shares and access")
mapping_enum_group.add_argument("--no-write-check", action="store_true", help="Skip write check on shares (avoid leaving traces when missing delete permissions)")
mapping_enum_group.add_argument("--filter-shares", nargs="+", help="Filter share by access, option 'read' 'write' or 'read,write'")
mapping_enum_group.add_argument("--sessions", action="store_true", help="enumerate active sessions")
+3 -5
View File
@@ -78,11 +78,10 @@ class UserSamrDump:
if resp2["ErrorCode"] != 0:
raise Exception("Connect error")
domain_name = resp2["Buffer"]["Buffer"][0]["Name"]
resp3 = samr.hSamrLookupDomainInSamServer(
self.dce,
serverHandle=resp["ServerHandle"],
name=domain_name,
name=resp2["Buffer"]["Buffer"][0]["Name"],
)
if resp3["ErrorCode"] != 0:
raise Exception("Connect error")
@@ -133,7 +132,7 @@ class UserSamrDump:
# set these for the while loop
enumerationContext = enumerate_users_resp["EnumerationContext"]
status = enumerate_users_resp["ErrorCode"]
self.print_user_info(users, domain_name)
self.print_user_info(users)
self.dce.disconnect()
def get_user_info(self, domain_handle, user_ids):
@@ -166,8 +165,7 @@ class UserSamrDump:
samr.hSamrCloseHandle(self.dce, open_user_resp["UserHandle"])
return users
def print_user_info(self, users, domain_name):
self.logger.display(f"Enumerated {len(users):d} local users: {domain_name}")
def print_user_info(self, users):
self.logger.highlight(f"{'-Username-':<30}{'-Last PW Set-':<20}{'-BadPW-':<8}{'-Description-':<60}")
for user in users:
self.logger.debug(f"Full user info: {user}")
-144
View File
@@ -1,144 +0,0 @@
from nxc.protocols import smb
from impacket.smbconnection import SMBConnection, SessionError
from impacket.smb import SharedFile
from impacket.dcerpc.v5 import transport, lsat, lsad
from winacl.dtyp.security_descriptor import SECURITY_DESCRIPTOR
from winacl.functions.constants import SE_OBJECT_TYPE
from winacl.dtyp.ace import FILE_ACCESS_MASK
from impacket.dcerpc.v5.dtypes import MAXIMUM_ALLOWED
from termcolor import colored
from typing import List
class SMB_Share_Enumeration:
def __init__(self, nxc_conn: smb, smb_conn: SMBConnection):
self.nxc_conn = nxc_conn
self.smb_conn = smb_conn
self.logger = nxc_conn.logger
def enumerate_path(self, path: str):
self.share = path.split(":")[0]
self.path = path.split(":")[1]
self.shares = [share["shi1_netname"][:-1] for share in self.nxc_conn.conn.listShares()]
if self.share not in self.shares:
self.logger.fail(f"Share {self.share} not found")
return
else:
self.logger.display(f"Enumerating ACLs on share: {self.share}")
self.enumerate_files(self.share, self.path, recursive=True)
def enumerate_files(self, share, path: str, recursive: bool = False):
"""Recursive function that enumerates the directories"""
self.logger.debug(f"Trying to enumrate files in {path}")
if path[-2:] not in ["\\", "/"]:
path += "/"
path.replace("\\", "/")
try:
file_list: List[SharedFile] = self.smb_conn.listPath(share, path + "*")
for file in file_list:
if (
file.is_directory()
and not file.is_system()
and file.get_longname() not in [".", ".."]
and recursive
):
next_path = path + file.get_longname() + "/"
self.enumerate_files(share, next_path, recursive=True)
if not file.is_directory() and not file.is_system():
self.logger.debug(f"File Found {file.get_longname()}")
self.get_security_descriptor(file, share, path)
except SessionError as e:
self.logger.error(e)
def get_security_descriptor(self, file, share, path, filters=None):
"""Retrieving the security descriptor of a certain file on a share"""
tree_id = self.smb_conn.connectTree(share)
dce = self.get_dce_from_smb()
desired_access = 0x00020000 # READ_CONTROL
share_mode = 0x00000001 # FILE_SHARE_READ
create_options = 0x00000040 # FILE_NON_DIRECTORY_FILE
file_attrs = 0
create_disposition = 0x00000001 # FILE_DIRECTORY_FILE
file_full_path = path + file.get_longname()
try:
file_id = self.smb_conn.createFile(
tree_id,
file_full_path,
desiredAccess=desired_access,
shareMode=share_mode,
creationOption=create_options,
creationDisposition=create_disposition,
fileAttributes=file_attrs,
impersonationLevel=0x00000002, # Impersonation
)
security_descriptor = self.smb_conn._SMBConnection.query_sec_info(tree_id, file_id)
security_descriptor_obj = SECURITY_DESCRIPTOR.from_bytes(
security_descriptor, object_type=SE_OBJECT_TYPE.SE_FILE_OBJECT
)
if filters:
for _filter, values in filters.items():
if _filter == "owner" and str(security_descriptor_obj.Owner) not in values:
return
if _filter == "group" and str(security_descriptor_obj.Group) not in values:
return
if _filter == "ace_sid":
sids = [str(_ace.Sid) for _ace in security_descriptor_obj.Dacl.aces]
for sid in values:
if sid in sids:
continue
else:
return
if _filter == "ace_mask":
masks = [FILE_ACCESS_MASK(_ace.Mask).name for _ace in security_descriptor_obj.Dacl.aces]
for mask in values:
if mask in masks:
continue
else:
return
self.logger.success(file_full_path)
# Also get the user's group to mark it as Owned
# self.smb_conn._SMBConnection._SMB__userName
username = self.smb_conn._SMBConnection._SMB__userName
owner = self.lookup_sid(dce, str(security_descriptor_obj.Owner))
if owner == username:
owner = owner + colored("Pwn3d!", "red")
group = self.lookup_sid(dce, str(security_descriptor_obj.Group))
self.logger.highlight(f"\t Owner: {owner}")
self.logger.highlight(f"\t Group: {group}")
self.logger.highlight(f"\t SACL: {security_descriptor_obj.Sacl}")
if security_descriptor_obj.Dacl is not None:
self.logger.highlight("\t ACEs:")
for ace in security_descriptor_obj.Dacl.aces:
ace_sid_name = self.lookup_sid(dce, str(ace.Sid))
mask_formatted = FILE_ACCESS_MASK(ace.Mask).name
if mask_formatted is None:
continue
owned = colored(" (Own3d!)", "red") if ace_sid_name == username else ""
self.logger.highlight(f"\t\t {ace_sid_name} - {mask_formatted}{owned}")
except SessionError as e:
self.logger.debug(e)
def get_dce_from_smb(self):
string_binding = rf"ncacn_np:{self.nxc_conn.remoteName}[\pipe\lsarpc]"
rpctransport = transport.DCERPCTransportFactory(string_binding)
rpctransport.set_dport(self.nxc_conn.port)
rpctransport.setRemoteHost(self.nxc_conn.host)
rpctransport.set_credentials(self.nxc_conn.username, self.nxc_conn.password, self.nxc_conn.domain, self.nxc_conn.lmhash, self.nxc_conn.nthash)
return rpctransport.get_dce_rpc()
def lookup_sid(self, dce, sid):
dce.connect()
dce.bind(lsat.MSRPC_UUID_LSAT)
policy_response = lsad.hLsarOpenPolicy2(dce, MAXIMUM_ALLOWED | lsat.POLICY_LOOKUP_NAMES)
policy_handle = policy_response["PolicyHandle"]
sid_response = lsat.hLsarLookupSids(dce, policy_handle, [sid],lsat.LSAP_LOOKUP_LEVEL.LsapLookupWksta)
sid_name = sid_response["TranslatedNames"]["Names"][0]["Name"]
dce.disconnect()
return sid_name
+2 -2
View File
@@ -2,7 +2,7 @@ from sqlalchemy.dialects.sqlite import Insert
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy import MetaData, Table, select, func, delete
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -111,7 +111,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
+2 -2
View File
@@ -1,7 +1,7 @@
from pathlib import Path
from sqlalchemy import MetaData, Table
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -74,7 +74,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
+2 -2
View File
@@ -3,7 +3,7 @@ from sqlalchemy.dialects.sqlite import Insert
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy import MetaData, Table, select, func, delete
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -94,7 +94,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
+2 -2
View File
@@ -2,7 +2,7 @@ from pathlib import Path
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy import MetaData, Table
from sqlalchemy.exc import (
IllegalStateChangeError,
# IllegalStateChangeError,
NoInspectionAvailable,
NoSuchTableError,
)
@@ -66,7 +66,7 @@ class database:
# due to the async nature of nxc, sometimes session state is a bit messy and this will throw:
# Method 'close()' can't be called here; method '_connection_for_bind()' is already in progress and
# this would cause an unexpected state change to <SessionTransactionState.CLOSED: 5>
except IllegalStateChangeError as e:
except Exception as e:
nxc_logger.debug(f"Error while closing session db object: {e}")
def clear_database(self):
Generated
+97 -110
View File
@@ -59,42 +59,41 @@ files = [
[[package]]
name = "aiosmb"
version = "0.4.10"
version = "0.4.4"
description = "Asynchronous SMB protocol implementation"
optional = false
python-versions = ">=3.7"
files = [
{file = "aiosmb-0.4.10-py3-none-any.whl", hash = "sha256:8b6f4c586fcd4e757e31aa3ea5a17060d9355d8994011ff6040acc18c578c023"},
{file = "aiosmb-0.4.10.tar.gz", hash = "sha256:b8de656e1b8fb7d6b1a766534f10e01ee0d1c254235c03449063e04092f5a3dd"},
{file = "aiosmb-0.4.4-py3-none-any.whl", hash = "sha256:ed70967243ec6634ac443de4e048c666f372ec863e49e8a2c1e01d640989f95e"},
{file = "aiosmb-0.4.4.tar.gz", hash = "sha256:20620498cf5e6794fea29ddcb46afbda8cbf714e3cf8e1da149699f03453637f"},
]
[package.dependencies]
asn1crypto = "*"
asyauth = ">=0.0.16"
asysocks = ">=0.2.9"
asyauth = ">=0.0.8"
asysocks = ">=0.2.2"
colorama = "*"
cryptography = "*"
minikerberos = ">=0.3.5"
prompt-toolkit = ">=3.0.2"
six = "*"
tqdm = "*"
unicrypto = ">=0.0.10"
unicrypto = ">=0.0.9"
wcwidth = "*"
winacl = ">=0.1.8"
winacl = ">=0.1.5"
[[package]]
name = "aiosqlite"
version = "0.19.0"
version = "0.17.0"
description = "asyncio bridge to the standard sqlite3 module"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.6"
files = [
{file = "aiosqlite-0.19.0-py3-none-any.whl", hash = "sha256:edba222e03453e094a3ce605db1b970c4b3376264e56f32e2a4959f948d66a96"},
{file = "aiosqlite-0.19.0.tar.gz", hash = "sha256:95ee77b91c8d2808bd08a59fbebf66270e9090c3d92ffbf260dc0db0b979577d"},
{file = "aiosqlite-0.17.0-py3-none-any.whl", hash = "sha256:6c49dc6d3405929b1d08eeccc72306d3677503cc5e5e43771efc1e00232e8231"},
{file = "aiosqlite-0.17.0.tar.gz", hash = "sha256:f0e6acc24bc4864149267ac82fb46dfb3be4455f99fe21df82609cc6e6baee51"},
]
[package.extras]
dev = ["aiounittest (==1.4.1)", "attribution (==1.6.2)", "black (==23.3.0)", "coverage[toml] (==7.2.3)", "flake8 (==5.0.4)", "flake8-bugbear (==23.3.12)", "flit (==3.7.1)", "mypy (==1.2.0)", "ufmt (==2.1.0)", "usort (==1.0.6)"]
docs = ["sphinx (==6.1.3)", "sphinx-mdinclude (==0.5.3)"]
[package.dependencies]
typing_extensions = ">=3.7.2"
[[package]]
name = "aiowinreg"
@@ -1555,17 +1554,17 @@ files = [
[[package]]
name = "pyasn1-modules"
version = "0.3.0"
description = "A collection of ASN.1-based protocols modules"
version = "0.2.8"
description = "A collection of ASN.1-based protocols modules."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
python-versions = "*"
files = [
{file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"},
{file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"},
{file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"},
{file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"},
]
[package.dependencies]
pyasn1 = ">=0.4.6,<0.6.0"
pyasn1 = ">=0.4.6,<0.5.0"
[[package]]
name = "pycodestyle"
@@ -1798,25 +1797,25 @@ kerberos = ["pyspnego[kerberos]"]
[[package]]
name = "pypykatz"
version = "0.6.9"
version = "0.6.6"
description = "Python implementation of Mimikatz"
optional = false
python-versions = ">=3.6"
files = [
{file = "pypykatz-0.6.9-py3-none-any.whl", hash = "sha256:ea5f43e0e754aacaa47510003c88bc65be2099b08812390b5a83b01aff61b1df"},
{file = "pypykatz-0.6.9.tar.gz", hash = "sha256:5e78b671823e0724c5483bee5870d4f7b2a58f031edda4fb3fe5488abea4b64b"},
{file = "pypykatz-0.6.6-py3-none-any.whl", hash = "sha256:c2167c06c6e0992b721e5c9e572fc4a847099bca2b179c65d820280cb0d344f9"},
{file = "pypykatz-0.6.6.tar.gz", hash = "sha256:7cf7842937d12f5e36448312431a41c88032d3db179660e32004e291cf3622ec"},
]
[package.dependencies]
aesedb = ">=0.1.4,<=0.2.0"
aiosmb = ">=0.4.8,<=0.5.0"
aiowinreg = ">=0.0.10,<=0.1.0"
minidump = ">=0.0.21,<=0.1.0"
minikerberos = ">=0.4.1,<=0.5.0"
msldap = ">=0.5.7,<=0.6.0"
aesedb = ">=0.1.3"
aiosmb = ">=0.4.4"
aiowinreg = ">=0.0.7"
minidump = ">=0.0.21"
minikerberos = ">=0.4.0"
msldap = ">=0.4.7"
tqdm = "*"
unicrypto = ">=0.0.10,<=0.1.0"
winacl = ">=0.1.7,<=0.2.0"
unicrypto = ">=0.0.10"
winacl = ">=0.1.6"
[[package]]
name = "pyspnego"
@@ -2035,90 +2034,82 @@ files = [
[[package]]
name = "sqlalchemy"
version = "2.0.25"
version = "1.4.50"
description = "Database Abstraction Library"
optional = false
python-versions = ">=3.7"
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
files = [
{file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd"},
{file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735"},
{file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a"},
{file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84"},
{file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"},
{file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570"},
{file = "SQLAlchemy-2.0.25-cp310-cp310-win32.whl", hash = "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669"},
{file = "SQLAlchemy-2.0.25-cp310-cp310-win_amd64.whl", hash = "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643"},
{file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002"},
{file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed"},
{file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed"},
{file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5"},
{file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9"},
{file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018"},
{file = "SQLAlchemy-2.0.25-cp311-cp311-win32.whl", hash = "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c"},
{file = "SQLAlchemy-2.0.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f"},
{file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d"},
{file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6"},
{file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39"},
{file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5"},
{file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95"},
{file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215"},
{file = "SQLAlchemy-2.0.25-cp312-cp312-win32.whl", hash = "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2"},
{file = "SQLAlchemy-2.0.25-cp312-cp312-win_amd64.whl", hash = "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5"},
{file = "SQLAlchemy-2.0.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0"},
{file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7"},
{file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62"},
{file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9"},
{file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23"},
{file = "SQLAlchemy-2.0.25-cp37-cp37m-win32.whl", hash = "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4"},
{file = "SQLAlchemy-2.0.25-cp37-cp37m-win_amd64.whl", hash = "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c"},
{file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e"},
{file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625"},
{file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3"},
{file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3"},
{file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9"},
{file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4"},
{file = "SQLAlchemy-2.0.25-cp38-cp38-win32.whl", hash = "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e"},
{file = "SQLAlchemy-2.0.25-cp38-cp38-win_amd64.whl", hash = "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d"},
{file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900"},
{file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf"},
{file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf"},
{file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f"},
{file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de"},
{file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d"},
{file = "SQLAlchemy-2.0.25-cp39-cp39-win32.whl", hash = "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24"},
{file = "SQLAlchemy-2.0.25-cp39-cp39-win_amd64.whl", hash = "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7"},
{file = "SQLAlchemy-2.0.25-py3-none-any.whl", hash = "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3"},
{file = "SQLAlchemy-2.0.25.tar.gz", hash = "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08"},
{file = "SQLAlchemy-1.4.50-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:54138aa80d2dedd364f4e8220eef284c364d3270aaef621570aa2bd99902e2e8"},
{file = "SQLAlchemy-1.4.50-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00665725063692c42badfd521d0c4392e83c6c826795d38eb88fb108e5660e5"},
{file = "SQLAlchemy-1.4.50-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85292ff52ddf85a39367057c3d7968a12ee1fb84565331a36a8fead346f08796"},
{file = "SQLAlchemy-1.4.50-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d0fed0f791d78e7767c2db28d34068649dfeea027b83ed18c45a423f741425cb"},
{file = "SQLAlchemy-1.4.50-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db4db3c08ffbb18582f856545f058a7a5e4ab6f17f75795ca90b3c38ee0a8ba4"},
{file = "SQLAlchemy-1.4.50-cp310-cp310-win32.whl", hash = "sha256:6c78e3fb4a58e900ec433b6b5f4efe1a0bf81bbb366ae7761c6e0051dd310ee3"},
{file = "SQLAlchemy-1.4.50-cp310-cp310-win_amd64.whl", hash = "sha256:d55f7a33e8631e15af1b9e67c9387c894fedf6deb1a19f94be8731263c51d515"},
{file = "SQLAlchemy-1.4.50-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:324b1fdd50e960a93a231abb11d7e0f227989a371e3b9bd4f1259920f15d0304"},
{file = "SQLAlchemy-1.4.50-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14b0cacdc8a4759a1e1bd47dc3ee3f5db997129eb091330beda1da5a0e9e5bd7"},
{file = "SQLAlchemy-1.4.50-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fb9cb60e0f33040e4f4681e6658a7eb03b5cb4643284172f91410d8c493dace"},
{file = "SQLAlchemy-1.4.50-cp311-cp311-win32.whl", hash = "sha256:8bdab03ff34fc91bfab005e96f672ae207d87e0ac7ee716d74e87e7046079d8b"},
{file = "SQLAlchemy-1.4.50-cp311-cp311-win_amd64.whl", hash = "sha256:52e01d60b06f03b0a5fc303c8aada405729cbc91a56a64cead8cb7c0b9b13c1a"},
{file = "SQLAlchemy-1.4.50-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:77fde9bf74f4659864c8e26ac08add8b084e479b9a18388e7db377afc391f926"},
{file = "SQLAlchemy-1.4.50-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cb501d585aa74a0f86d0ea6263b9c5e1d1463f8f9071392477fd401bd3c7cc"},
{file = "SQLAlchemy-1.4.50-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a7a66297e46f85a04d68981917c75723e377d2e0599d15fbe7a56abed5e2d75"},
{file = "SQLAlchemy-1.4.50-cp312-cp312-win32.whl", hash = "sha256:e86c920b7d362cfa078c8b40e7765cbc34efb44c1007d7557920be9ddf138ec7"},
{file = "SQLAlchemy-1.4.50-cp312-cp312-win_amd64.whl", hash = "sha256:6b3df20fbbcbcd1c1d43f49ccf3eefb370499088ca251ded632b8cbaee1d497d"},
{file = "SQLAlchemy-1.4.50-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:fb9adc4c6752d62c6078c107d23327aa3023ef737938d0135ece8ffb67d07030"},
{file = "SQLAlchemy-1.4.50-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1db0221cb26d66294f4ca18c533e427211673ab86c1fbaca8d6d9ff78654293"},
{file = "SQLAlchemy-1.4.50-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7dbe6369677a2bea68fe9812c6e4bbca06ebfa4b5cde257b2b0bf208709131"},
{file = "SQLAlchemy-1.4.50-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a9bddb60566dc45c57fd0a5e14dd2d9e5f106d2241e0a2dc0c1da144f9444516"},
{file = "SQLAlchemy-1.4.50-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82dd4131d88395df7c318eeeef367ec768c2a6fe5bd69423f7720c4edb79473c"},
{file = "SQLAlchemy-1.4.50-cp36-cp36m-win32.whl", hash = "sha256:1b9c4359d3198f341480e57494471201e736de459452caaacf6faa1aca852bd8"},
{file = "SQLAlchemy-1.4.50-cp36-cp36m-win_amd64.whl", hash = "sha256:35e4520f7c33c77f2636a1e860e4f8cafaac84b0b44abe5de4c6c8890b6aaa6d"},
{file = "SQLAlchemy-1.4.50-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:f5b1fb2943d13aba17795a770d22a2ec2214fc65cff46c487790192dda3a3ee7"},
{file = "SQLAlchemy-1.4.50-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:273505fcad22e58cc67329cefab2e436006fc68e3c5423056ee0513e6523268a"},
{file = "SQLAlchemy-1.4.50-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3257a6e09626d32b28a0c5b4f1a97bced585e319cfa90b417f9ab0f6145c33c"},
{file = "SQLAlchemy-1.4.50-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d69738d582e3a24125f0c246ed8d712b03bd21e148268421e4a4d09c34f521a5"},
{file = "SQLAlchemy-1.4.50-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34e1c5d9cd3e6bf3d1ce56971c62a40c06bfc02861728f368dcfec8aeedb2814"},
{file = "SQLAlchemy-1.4.50-cp37-cp37m-win32.whl", hash = "sha256:7b4396452273aedda447e5aebe68077aa7516abf3b3f48408793e771d696f397"},
{file = "SQLAlchemy-1.4.50-cp37-cp37m-win_amd64.whl", hash = "sha256:752f9df3dddbacb5f42d8405b2d5885675a93501eb5f86b88f2e47a839cf6337"},
{file = "SQLAlchemy-1.4.50-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:35c7ed095a4b17dbc8813a2bfb38b5998318439da8e6db10a804df855e3a9e3a"},
{file = "SQLAlchemy-1.4.50-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1fcee5a2c859eecb4ed179edac5ffbc7c84ab09a5420219078ccc6edda45436"},
{file = "SQLAlchemy-1.4.50-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbaf6643a604aa17e7a7afd74f665f9db882df5c297bdd86c38368f2c471f37d"},
{file = "SQLAlchemy-1.4.50-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2e70e0673d7d12fa6cd363453a0d22dac0d9978500aa6b46aa96e22690a55eab"},
{file = "SQLAlchemy-1.4.50-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b881ac07d15fb3e4f68c5a67aa5cdaf9eb8f09eb5545aaf4b0a5f5f4659be18"},
{file = "SQLAlchemy-1.4.50-cp38-cp38-win32.whl", hash = "sha256:8a219688297ee5e887a93ce4679c87a60da4a5ce62b7cb4ee03d47e9e767f558"},
{file = "SQLAlchemy-1.4.50-cp38-cp38-win_amd64.whl", hash = "sha256:a648770db002452703b729bdcf7d194e904aa4092b9a4d6ab185b48d13252f63"},
{file = "SQLAlchemy-1.4.50-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:4be4da121d297ce81e1ba745a0a0521c6cf8704634d7b520e350dce5964c71ac"},
{file = "SQLAlchemy-1.4.50-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f6997da81114daef9203d30aabfa6b218a577fc2bd797c795c9c88c9eb78d49"},
{file = "SQLAlchemy-1.4.50-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdb77e1789e7596b77fd48d99ec1d2108c3349abd20227eea0d48d3f8cf398d9"},
{file = "SQLAlchemy-1.4.50-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:128a948bd40780667114b0297e2cc6d657b71effa942e0a368d8cc24293febb3"},
{file = "SQLAlchemy-1.4.50-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2d526aeea1bd6a442abc7c9b4b00386fd70253b80d54a0930c0a216230a35be"},
{file = "SQLAlchemy-1.4.50-cp39-cp39-win32.whl", hash = "sha256:a7c9b9dca64036008962dd6b0d9fdab2dfdbf96c82f74dbd5d86006d8d24a30f"},
{file = "SQLAlchemy-1.4.50-cp39-cp39-win_amd64.whl", hash = "sha256:df200762efbd672f7621b253721644642ff04a6ff957236e0e2fe56d9ca34d2c"},
{file = "SQLAlchemy-1.4.50.tar.gz", hash = "sha256:3b97ddf509fc21e10b09403b5219b06c5b558b27fc2453150274fa4e70707dbf"},
]
[package.dependencies]
greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""}
typing-extensions = ">=4.6.0"
greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"}
[package.extras]
aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"]
aioodbc = ["aioodbc", "greenlet (!=0.4.17)"]
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"]
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"]
asyncio = ["greenlet (!=0.4.17)"]
asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"]
mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"]
asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"]
mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"]
mssql = ["pyodbc"]
mssql-pymssql = ["pymssql"]
mssql-pyodbc = ["pyodbc"]
mypy = ["mypy (>=0.910)"]
mysql = ["mysqlclient (>=1.4.0)"]
mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"]
mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"]
mysql-connector = ["mysql-connector-python"]
oracle = ["cx_oracle (>=8)"]
oracle-oracledb = ["oracledb (>=1.0.1)"]
oracle = ["cx-oracle (>=7)", "cx-oracle (>=7,<8)"]
postgresql = ["psycopg2 (>=2.7)"]
postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"]
postgresql-pg8000 = ["pg8000 (>=1.29.1)"]
postgresql-psycopg = ["psycopg (>=3.0.7)"]
postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"]
postgresql-psycopg2binary = ["psycopg2-binary"]
postgresql-psycopg2cffi = ["psycopg2cffi"]
postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"]
pymysql = ["pymysql"]
sqlcipher = ["sqlcipher3_binary"]
pymysql = ["pymysql", "pymysql (<1)"]
sqlcipher = ["sqlcipher3-binary"]
[[package]]
name = "sspilib"
@@ -2175,18 +2166,14 @@ widechars = ["wcwidth"]
[[package]]
name = "termcolor"
version = "2.4.0"
description = "ANSI color formatting for output in terminal"
version = "1.1.0"
description = "ANSII Color formatting for output in terminal."
optional = false
python-versions = ">=3.8"
python-versions = "*"
files = [
{file = "termcolor-2.4.0-py3-none-any.whl", hash = "sha256:9297c0df9c99445c2412e832e882a7884038a25617c60cea2ad69488d4040d63"},
{file = "termcolor-2.4.0.tar.gz", hash = "sha256:aab9e56047c8ac41ed798fa36d892a37aca6b3e9159f3e0c24bc64a9b3ac7b7a"},
{file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"},
]
[package.extras]
tests = ["pytest", "pytest-cov"]
[[package]]
name = "terminaltables"
version = "3.1.10"
@@ -2310,13 +2297,13 @@ watchdog = ["watchdog (>=2.3)"]
[[package]]
name = "winacl"
version = "0.1.9"
version = "0.1.8"
description = "ACL/ACE/Security Descriptor manipulation library in pure Python"
optional = false
python-versions = ">=3.6"
files = [
{file = "winacl-0.1.9-py3-none-any.whl", hash = "sha256:31ba781a35f3b1bd3c2ece994816c0a5fe113c73018689ab6118010ac0d15099"},
{file = "winacl-0.1.9.tar.gz", hash = "sha256:af70c2ec30178bf9e3c8a1c48c25e8781235fe2c1b321adb46e2f2ae1f8d4aab"},
{file = "winacl-0.1.8-py3-none-any.whl", hash = "sha256:f17028422c0b2dc6752c801350d37878919804728b776289521dc83622982a45"},
{file = "winacl-0.1.8.tar.gz", hash = "sha256:44271a302562de51629f68ef1540d40f3a26e7bc0173646b01a6779cedad644c"},
]
[package.dependencies]
@@ -2351,4 +2338,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = "^3.8.0"
content-hash = "87a6d3ee944dc3aa0122c51ec72fbdc6e6070eda5b812232a1c84ca967f9397e"
content-hash = "ffe66257d6e590d72b96001cf9bc5c6b3633c867f4648fa713be12b3e3d1584e"
+5 -6
View File
@@ -36,7 +36,7 @@ nxcdb = 'nxc.nxcdb:main'
python = "^3.8.0"
aardwolf = "^0.2.8"
aioconsole = "^0.6.2"
aiosqlite = "^0.19.0"
aiosqlite = "^0.17.0"
argcomplete = "^3.1.4"
asyauth = ">=0.0.20"
beautifulsoup4 = ">=4.11,<5"
@@ -52,19 +52,18 @@ msldap = "^0.5.10"
neo4j = "^5.0.0"
paramiko = "^3.3.1"
poetry-dynamic-versioning = "^1.2.0"
pyasn1-modules = "^0.3.0"
pyasn1-modules = "^0.2.8"
pylnk3 = "^0.4.2"
pypsrp = "^0.8.1"
pypykatz = "^0.6.8"
pypykatz = "0.6.6"
pywerview = "^0.3.3" # pywerview 5 requires libkrb5-dev installed which is not default on kali (as of 9/23)
python-dateutil = ">=2.8.2"
python-libnmap = "^0.7.3"
requests = ">=2.27.1"
rich = "^13.3.5"
sqlalchemy = "^2.0.4"
termcolor = ">=2.4.0"
sqlalchemy = "^1.4.50"
termcolor = "1.1.0"
terminaltables = "^3.1.0"
winacl = "^0.1.9"
xmltodict = "^0.13.0"
[tool.poetry.group.dev.dependencies]
-6
View File
@@ -1,6 +0,0 @@
DEADBEEFDEADBEEFDEADBEEFDEADBEEF
DEADBEEFDEADBEEFDEADBEEFDEADBEEF:DEADBEEFDEADBEEFDEADBEEFDEADBEEF
TooShort
ToooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooLong
fc525c9683e8fe067095ba2ddc971889
aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889
+1 -4
View File
@@ -137,10 +137,7 @@ netexec smb TARGET_HOST -u '' -p '' -M petitpotam
##### SMB Auth File
netexec smb TARGET_HOST -u TEST_USER_FILE -p TEST_PASSWORD_FILE --no-bruteforce
netexec smb TARGET_HOST -u TEST_USER_FILE -p TEST_PASSWORD_FILE --no-bruteforce --continue-on-success
netexec smb TARGET_HOST -u TEST_USER_FILE -p TEST_PASSWORD_FILE
##### SMB Hash File
netexec smb TARGET_HOST -u LOGIN_USERNAME -H tests/data/test_hashes.txt
netexec smb TARGET_HOST -u TEST_USER_FILE -H tests/data/test_hashes.txt
netexec smb TARGET_HOST -u TEST_USER_FILE -p tests/data/test_passwords.txt
##### WMI
netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS # need an extra space after this command due to regex
netexec wmi TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --wmi-namespace root/cimv2