Merge branch 'main' of github.com:SpecterOps/Nemesis into docker_compose

This commit is contained in:
Lee Chagolla-Christensen
2025-06-25 02:21:21 -07:00
6 changed files with 823 additions and 49 deletions
+13 -4
View File
@@ -718,11 +718,14 @@ services:
depends_on: [jaeger]
jaeger:
profiles: ["monitoring"]
image: jaegertracing/all-in-one
environment: { QUERY_BASE_PATH: /jaeger }
image: jaegertracing/jaeger:latest # v2.x image
user: "0:0"
environment:
- QUERY_BASE_PATH=/jaeger
volumes:
- jaeger_data:/badger
- jaeger_data:/badger # Persist trace data
- ./infra/jaeger/jaeger-config.yaml:/etc/jaeger/config.yaml
command: ["--config", "/etc/jaeger/config.yaml"]
labels:
- "traefik.enable=true"
- "traefik.http.routers.jaeger.rule=PathPrefix(`/jaeger`)"
@@ -730,6 +733,12 @@ services:
- "traefik.http.routers.jaeger.entrypoints=websecure"
- "traefik.http.routers.jaeger.tls=true"
- "traefik.http.routers.jaeger.middlewares=auth"
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:13133/status || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
loki:
profiles: ["monitoring"]
+61
View File
@@ -0,0 +1,61 @@
# Service configuration
service:
extensions: [jaeger_storage, jaeger_query, healthcheckv2]
pipelines:
traces:
receivers: [otlp, jaeger, zipkin]
processors: [batch]
exporters: [jaeger_storage_exporter]
# Extensions
extensions:
healthcheckv2:
use_v2: true
http:
endpoint: "0.0.0.0:13133"
jaeger_query:
storage:
traces: badger_store
base_path: /jaeger
jaeger_storage:
backends:
badger_store:
badger:
directories:
keys: "/badger/keys"
values: "/badger/values"
ephemeral: false
consistency: true
maintenance_interval: 1m0s
# Receivers
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
http:
endpoint: "0.0.0.0:4318"
jaeger:
protocols:
grpc:
endpoint: "0.0.0.0:14250"
thrift_http:
endpoint: "0.0.0.0:14268"
thrift_compact:
endpoint: "0.0.0.0:6831"
thrift_binary:
endpoint: "0.0.0.0:6832"
zipkin:
endpoint: "0.0.0.0:9411"
# Processors
processors:
batch:
# Exporters
exporters:
jaeger_storage_exporter:
trace_storage: badger_store
@@ -102,8 +102,6 @@ class LnkParser(EnrichmentModule):
enrichment_result.results = convert_datetime(lnk.get_json())
logger.info(f"lnk 3: {enrichment_result.results}")
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8") as tmp_display_file:
display = get_lnk_file_display(lnk)
tmp_display_file.write(display)
@@ -0,0 +1,479 @@
# enrichment_modules/lsass_dump/analyzer.py
import tempfile
import textwrap
from pathlib import Path
from datetime import datetime
import structlog
from common.models import EnrichmentResult, Transform, Finding, FindingCategory, FindingOrigin, FileObject
from common.state_helpers import get_file_enriched
from common.storage import StorageMinio
from file_enrichment_modules.module_loader import EnrichmentModule
from pypykatz.pypykatz import pypykatz
logger = structlog.get_logger(module=__name__)
class Credential:
"""Simple credential class to match the original structure"""
def __init__(self, hostname=None, ssp=None, domain=None, username=None,
password=None, lmhash=None, nthash=None, sha1=None,
masterkey=None, ticket=None):
self.hostname = hostname
self.ssp = ssp
self.domain = domain
self.username = username
self.password = password
self.lmhash = lmhash
self.nthash = nthash
self.sha1 = sha1
self.masterkey = masterkey
self.ticket = ticket
# adapted from/inspired by https://github.com/login-securite/lsassy/blob/9682127364f6f64ce190e8b7f03cdfa1dd457066/lsassy/parser.py (MIT License)
class LsassDumpParser(EnrichmentModule):
def __init__(self):
super().__init__("lsass_dump")
self.storage = StorageMinio()
# the workflows this module should automatically run in
self.workflows = ["default"]
def should_process(self, object_id: str) -> bool:
"""Determine if this module should run based on file type."""
file_enriched = get_file_enriched(object_id)
should_run = "mini dump crash report" in file_enriched.magic_type.lower()
logger.debug(
f"LsassDumpParser should_run: {should_run}, file_name: {file_enriched.file_name}"
)
return should_run
def _convert_bytes_to_string(self, value):
"""Convert bytes objects and datetime objects to strings for JSON serialization"""
if isinstance(value, bytes):
return value.decode('utf-8', errors='replace')
elif isinstance(value, datetime):
return str(value)
elif hasattr(value, 'strftime'): # Handle other datetime-like objects
return str(value)
elif isinstance(value, dict):
return {k: self._convert_bytes_to_string(v) for k, v in value.items()}
elif isinstance(value, list):
return [self._convert_bytes_to_string(item) for item in value]
else:
return value
def _parse_lsass_dump(self, dump_file_path: str, target_hostname: str = "unknown") -> tuple[list, list, list, list]:
"""
Parse LSASS dump file using pypykatz
:param dump_file_path: Path to the dump file
:param target_hostname: Target hostname for credential tracking
:return: Tuple of (logon_sessions, credentials, tickets, masterkeys)
"""
logon_sessions = []
credentials = []
tickets = []
masterkeys = []
try:
pypy_parse = pypykatz.parse_minidump_file(dump_file_path)
except Exception as e:
logger.error(f"An error occurred while parsing lsass dump: {e}", exc_info=True)
return None, None, None, None
ssps = [
"msv_creds",
"wdigest_creds",
"ssp_creds",
"livessp_creds",
"kerberos_creds",
"credman_creds",
"tspkg_creds",
"dpapi_creds",
]
for luid in pypy_parse.logon_sessions:
session = pypy_parse.logon_sessions[luid]
# Extract session metadata
session_data = {
'authentication_id': getattr(session, 'authentication_id', luid),
'session_id': getattr(session, 'session_id', None),
'username': getattr(session, 'username', None),
'domainname': getattr(session, 'domainname', None),
'logon_server': getattr(session, 'logon_server', None),
'logon_time': getattr(session, 'logon_time', None),
'sid': getattr(session, 'sid', None),
'luid': luid,
'credentials_by_ssp': {}
}
# Convert logon_time to string if it exists
if session_data['logon_time']:
session_data['logon_time'] = str(session_data['logon_time'])
if session_data['sid']:
session_data['sid'] = str(session_data['sid'])
# Process each SSP type for session data AND create original credentials
for ssp in ssps:
ssp_creds = []
creds = getattr(session, ssp, [])
for cred in creds:
cred_data = {}
# Common fields
if hasattr(cred, 'username'):
cred_data['username'] = cred.username
if hasattr(cred, 'domainname'):
cred_data['domainname'] = cred.domainname
if hasattr(cred, 'password'):
cred_data['password'] = cred.password
if hasattr(cred, 'credtype'):
cred_data['credtype'] = cred.credtype
if hasattr(cred, 'luid'):
cred_data['luid'] = cred.luid
# Extract credential info for original credential objects (for ALL SSP types)
domain = getattr(cred, "domainname", None)
username = getattr(cred, "username", None)
password = getattr(cred, "password", None)
LMHash = getattr(cred, "LMHash", None)
NThash = getattr(cred, "NThash", None)
SHA1 = getattr(cred, "SHAHash", None)
if LMHash is not None:
LMHash = LMHash.hex() if hasattr(LMHash, 'hex') else str(LMHash)
if NThash is not None:
NThash = NThash.hex() if hasattr(NThash, 'hex') else str(NThash)
if SHA1 is not None:
SHA1 = SHA1.hex() if hasattr(SHA1, 'hex') else str(SHA1)
# Create credential object for all SSP types that have valid credentials
if username and (
password
or (NThash and NThash != "00000000000000000000000000000000")
or (LMHash and LMHash != "00000000000000000000000000000000")
):
credentials.append(
Credential(
hostname=target_hostname,
ssp=ssp,
domain=domain,
username=username,
password=password,
lmhash=LMHash,
nthash=NThash,
sha1=SHA1,
)
)
# MSV specific fields for session data
if ssp == "msv_creds":
if hasattr(cred, 'LMHash') and cred.LMHash:
cred_data['LMHash'] = cred.LMHash.hex() if hasattr(cred.LMHash, 'hex') else str(cred.LMHash)
if hasattr(cred, 'NThash') and cred.NThash:
cred_data['NThash'] = cred.NThash.hex() if hasattr(cred.NThash, 'hex') else str(cred.NThash)
if hasattr(cred, 'SHAHash') and cred.SHAHash:
cred_data['SHAHash'] = cred.SHAHash.hex() if hasattr(cred.SHAHash, 'hex') else str(cred.SHAHash)
if hasattr(cred, 'DPAPI') and cred.DPAPI:
cred_data['DPAPI'] = cred.DPAPI.hex() if hasattr(cred.DPAPI, 'hex') else str(cred.DPAPI)
# Kerberos specific fields
elif ssp == "kerberos_creds":
ticket_list = []
if hasattr(cred, 'tickets'):
for ticket in cred.tickets:
tickets.append(ticket)
# Add ticket info to the session data
ticket_info = {
'service_name': getattr(ticket, 'ServiceName', [None])[0] if hasattr(ticket, 'ServiceName') and ticket.ServiceName else None,
'client_name': getattr(ticket, 'EClientName', [None])[0] if hasattr(ticket, 'EClientName') and ticket.EClientName else None,
'domain_name': getattr(ticket, 'DomainName', None),
'end_time': str(getattr(ticket, 'EndTime', None)) if hasattr(ticket, 'EndTime') else None
}
ticket_list.append(ticket_info)
cred_data['tickets'] = ticket_list
else:
cred_data['tickets'] = []
if hasattr(cred, 'aes128') and cred.aes128:
cred_data['aes128'] = cred.aes128.hex() if hasattr(cred.aes128, 'hex') else str(cred.aes128)
if hasattr(cred, 'aes256') and cred.aes256:
cred_data['aes256'] = cred.aes256.hex() if hasattr(cred.aes256, 'hex') else str(cred.aes256)
# DPAPI specific fields
elif ssp == "dpapi_creds":
if hasattr(cred, 'key_guid'):
cred_data['key_guid'] = str(cred.key_guid)
if hasattr(cred, 'masterkey') and cred.masterkey:
cred_data['masterkey'] = cred.masterkey.hex() if hasattr(cred.masterkey, 'hex') else str(cred.masterkey)
if hasattr(cred, 'sha1_masterkey') and cred.sha1_masterkey:
sha1_hex = cred.sha1_masterkey.hex() if hasattr(cred.sha1_masterkey, 'hex') else str(cred.sha1_masterkey)
cred_data['sha1_masterkey'] = sha1_hex
# Add to masterkeys list
m = "{%s}:%s" % (cred.key_guid, sha1_hex)
if m not in masterkeys:
masterkeys.append(m)
credentials.append(
Credential(
hostname=target_hostname,
ssp="dpapi",
domain="",
username="",
masterkey=m,
)
)
# WDIGEST specific fields
elif ssp == "wdigest_creds":
if hasattr(cred, 'password_raw'):
# Convert bytes to string for JSON serialization
if isinstance(cred.password_raw, bytes):
cred_data['password_raw'] = cred.password_raw.decode('utf-8', errors='replace')
else:
cred_data['password_raw'] = str(cred.password_raw) if cred.password_raw is not None else ""
if cred_data: # Only add if we have some data
# Convert any bytes objects to strings for JSON serialization
cred_data = self._convert_bytes_to_string(cred_data)
ssp_creds.append(cred_data)
if ssp_creds: # Only add SSP if it has credentials
session_data['credentials_by_ssp'][ssp] = ssp_creds
# Clean session data of any remaining bytes objects
session_data = self._convert_bytes_to_string(session_data)
logon_sessions.append(session_data)
# Process orphaned credentials
for cred in pypy_parse.orphaned_creds:
if cred.credtype == "kerberos":
for ticket in cred.tickets:
tickets.append(ticket)
# Process tickets for TGT detection
for ticket in tickets:
if ticket.ServiceName is not None and ticket.ServiceName[0] == "krbtgt":
if ticket.EClientName is not None and ticket.DomainName is not None:
if (
ticket.TargetDomainName is not None
and ticket.TargetDomainName != ticket.DomainName
):
target_domain = ticket.TargetDomainName
else:
target_domain = ticket.DomainName
# Keep only valid tickets
if ticket.EndTime > datetime.now(ticket.EndTime.tzinfo):
credentials.append(
Credential(
hostname=target_hostname,
ssp="kerberos",
domain=ticket.DomainName,
username=ticket.EClientName[0],
ticket={
"file": list(ticket.kirbi_data)[0].split(".kirbi")[0]
+ "_"
+ ticket.EndTime.strftime("%Y%m%d%H%M%S")
+ ".kirbi",
"domain": target_domain,
"endtime": str(ticket.EndTime), # Convert datetime to string
},
)
)
return logon_sessions, credentials, tickets, masterkeys
def _create_finding_summary(self, logon_sessions: list, credentials: list, tickets: list, masterkeys: list) -> str:
"""Creates a markdown summary for the LSASS dump findings."""
summary = "# LSASS Dump Analysis Results\n\n"
# Summary statistics
summary += f"**Total Logon Sessions**: {len(logon_sessions)}\n"
summary += f"**Total Credentials Found**: {len(credentials)}\n"
summary += f"**Total Tickets Found**: {len(tickets)}\n"
summary += f"**Total DPAPI Masterkeys**: {len(masterkeys)}\n\n"
# Process each logon session
for i, session in enumerate(logon_sessions, 1):
summary += f"## Logon Session {i}\n\n"
# Session metadata
summary += f"* **Authentication ID**: `{session.get('authentication_id', 'N/A')}`\n"
summary += f"* **Session ID**: `{session.get('session_id', 'N/A')}`\n"
summary += f"* **Username**: `{session.get('username', 'N/A')}`\n"
summary += f"* **Domain**: `{session.get('domainname', 'N/A')}`\n"
summary += f"* **Logon Server**: `{session.get('logon_server', 'N/A')}`\n"
summary += f"* **Logon Time**: `{session.get('logon_time', 'N/A')}`\n"
summary += f"* **SID**: `{session.get('sid', 'N/A')}`\n"
summary += f"* **LUID**: `{session.get('luid', 'N/A')}`\n\n"
# Credentials by SSP
creds_by_ssp = session.get('credentials_by_ssp', {})
if creds_by_ssp:
for ssp, creds in creds_by_ssp.items():
if creds:
summary += f"### {ssp.upper().replace('_', ' ')}\n\n"
for j, cred in enumerate(creds, 1):
summary += f"**Credential {j}:**\n"
for key, value in cred.items():
if value is not None and value != "":
if key in ['NThash', 'LMHash', 'SHAHash', 'DPAPI', 'aes128', 'aes256', 'masterkey', 'sha1_masterkey']:
summary += f"* **{key}**: `{value}`\n"
elif key == 'tickets' and isinstance(value, list) and value:
summary += f"* **Tickets**: {len(value)} found\n"
for i, ticket in enumerate(value, 1):
summary += f" * **Ticket {i}**: Service=`{ticket.get('service_name', 'N/A')}`, Client=`{ticket.get('client_name', 'N/A')}`, Domain=`{ticket.get('domain_name', 'N/A')}`, EndTime=`{ticket.get('end_time', 'N/A')}`\n"
else:
summary += f"* **{key.title()}**: `{value}`\n"
summary += "\n"
else:
summary += "*No credentials found for this session.*\n\n"
summary += "---\n\n"
return summary
def process(self, object_id: str) -> EnrichmentResult | None:
"""Process LSASS dump file and extract credentials."""
try:
file_enriched = get_file_enriched(object_id)
enrichment_result = EnrichmentResult(
module_name=self.name,
dependencies=self.dependencies
)
# Download the file to a temporary location
with self.storage.download(file_enriched.object_id) as temp_file:
# Parse the LSASS dump
logon_sessions, credentials, tickets, masterkeys = self._parse_lsass_dump(
temp_file.name,
file_enriched.file_name
)
if logon_sessions is None:
logger.error("Failed to parse LSASS dump file")
return None
if logon_sessions or credentials or tickets or masterkeys:
# Create finding summary
summary_markdown = self._create_finding_summary(logon_sessions, credentials, tickets, masterkeys)
# Prepare credentials data for serialization (convert objects to dicts)
credentials_data = []
for cred in credentials:
cred_dict = {
'hostname': cred.hostname,
'ssp': cred.ssp,
'domain': cred.domain,
'username': cred.username,
'password': cred.password,
'lmhash': cred.lmhash,
'nthash': cred.nthash,
'sha1': cred.sha1,
'masterkey': cred.masterkey,
'ticket': cred.ticket
}
credentials_data.append(cred_dict)
# Create display data
display_data = FileObject(
type="finding_summary",
metadata={
"summary": summary_markdown
}
)
# Create finding
finding = Finding(
category=FindingCategory.CREDENTIAL,
finding_name="lsass_credentials_detected",
origin_type=FindingOrigin.ENRICHMENT_MODULE,
origin_name=self.name,
object_id=file_enriched.object_id,
severity=9, # High severity for credential extraction
raw_data={
"logon_sessions": logon_sessions,
"credentials": credentials_data,
"ticket_count": len(tickets),
"masterkey_count": len(masterkeys)
},
data=[display_data]
)
# Add finding to enrichment result
enrichment_result.findings = [finding]
enrichment_result.results = {
"logon_sessions": logon_sessions,
"credentials": credentials_data,
"ticket_count": len(tickets),
"masterkey_count": len(masterkeys)
}
# Create a displayable version of the results
with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8') as tmp_display_file:
yaml_output = []
yaml_output.append("LSASS Dump Analysis Results")
yaml_output.append("===========================\n")
yaml_output.append(f"Total Logon Sessions: {len(logon_sessions)}")
yaml_output.append(f"Total Credentials: {len(credentials)}")
yaml_output.append(f"Total Tickets: {len(tickets)}")
yaml_output.append(f"Total Masterkeys: {len(masterkeys)}\n")
for i, session in enumerate(logon_sessions, 1):
yaml_output.append(f"Logon Session {i}:")
yaml_output.append(f" Authentication ID: {session.get('authentication_id', 'N/A')}")
yaml_output.append(f" Username: {session.get('username', 'N/A')}")
yaml_output.append(f" Domain: {session.get('domainname', 'N/A')}")
yaml_output.append(f" Logon Server: {session.get('logon_server', 'N/A')}")
yaml_output.append(f" Logon Time: {session.get('logon_time', 'N/A')}")
yaml_output.append(f" SID: {session.get('sid', 'N/A')}")
yaml_output.append(f" LUID: {session.get('luid', 'N/A')}")
creds_by_ssp = session.get('credentials_by_ssp', {})
if creds_by_ssp:
for ssp, creds in creds_by_ssp.items():
yaml_output.append(f" {ssp.upper()}:")
for j, cred in enumerate(creds, 1):
yaml_output.append(f" Credential {j}:")
for key, value in cred.items():
if value is not None and value != "":
if key == 'tickets' and isinstance(value, list) and value:
yaml_output.append(f" {key}: {len(value)} tickets found")
for k, ticket in enumerate(value, 1):
yaml_output.append(f" Ticket {k}: Service={ticket.get('service_name', 'N/A')}, Client={ticket.get('client_name', 'N/A')}, Domain={ticket.get('domain_name', 'N/A')}, EndTime={ticket.get('end_time', 'N/A')}")
else:
yaml_output.append(f" {key}: {value}")
yaml_output.append("") # Add empty line between sessions
display = textwrap.indent(
"\n".join(yaml_output),
" "
)
tmp_display_file.write(display)
tmp_display_file.flush()
object_id = self.storage.upload_file(tmp_display_file.name)
displayable_parsed = Transform(
type="displayable_parsed",
object_id=f"{object_id}",
metadata={
"file_name": f"{file_enriched.file_name}_lsass_analysis.txt",
"display_type_in_dashboard": "monaco",
"default_display": True
},
)
enrichment_result.transforms = [displayable_parsed]
return enrichment_result
except Exception as e:
logger.exception(e, message="Error processing LSASS dump file")
return None
def create_enrichment_module() -> EnrichmentModule:
return LsassDumpParser()
+269 -43
View File
@@ -1,5 +1,22 @@
# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand.
[[package]]
name = "aesedb"
version = "0.1.6"
description = "NTDS parser toolkit"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "aesedb-0.1.6-py3-none-any.whl", hash = "sha256:9dad54792b7d792715fd95379516b27e3a31de318199ba7cff51e5d0c8739228"},
]
[package.dependencies]
aiowinreg = ">=0.0.7"
colorama = "*"
tqdm = "*"
unicrypto = ">=0.0.9"
[[package]]
name = "aiohappyeyeballs"
version = "2.6.1"
@@ -135,6 +152,46 @@ files = [
[package.dependencies]
frozenlist = ">=1.1.0"
[[package]]
name = "aiosmb"
version = "0.4.11"
description = "Asynchronous SMB protocol implementation"
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "aiosmb-0.4.11-py3-none-any.whl", hash = "sha256:a3b84893cded7aa1ebf048c0f5267024f2c030e5d918e4d8d8b86f8974a4011a"},
{file = "aiosmb-0.4.11.tar.gz", hash = "sha256:6d66f51ed2354f76f206613eac0d63f37cfd9ed44be9f8a06594d410244273d7"},
]
[package.dependencies]
asn1crypto = "*"
asyauth = ">=0.0.16"
asysocks = ">=0.2.9"
colorama = "*"
cryptography = "*"
prompt-toolkit = ">=3.0.2"
six = "*"
tqdm = "*"
unicrypto = ">=0.0.10"
wcwidth = "*"
winacl = ">=0.1.8"
[[package]]
name = "aiowinreg"
version = "0.0.12"
description = "Windows registry file reader"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "aiowinreg-0.0.12-py3-none-any.whl", hash = "sha256:a67be904045d8ecb4798fa691dd7688b20a6e47a524d093528f7e77d9eaf00e9"},
]
[package.dependencies]
prompt-toolkit = ">=3.0.2"
winacl = ">=0.1.7"
[[package]]
name = "annotated-types"
version = "0.7.0"
@@ -237,6 +294,36 @@ files = [
[package.extras]
tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
[[package]]
name = "asn1crypto"
version = "1.5.1"
description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"},
{file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"},
]
[[package]]
name = "asyauth"
version = "0.0.21"
description = "Unified authentication library"
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "asyauth-0.0.21-py3-none-any.whl", hash = "sha256:1098ced8f4dfda74db535bc961e7667714154a440761821e26c8b637c95a2775"},
{file = "asyauth-0.0.21.tar.gz", hash = "sha256:34cc10c5f8628ff2e25b5116dc98efc5ca45532f163ccd3f9147a3e02dd810eb"},
]
[package.dependencies]
asn1crypto = ">=1.3.0"
asysocks = ">=0.2.11"
minikerberos = ">=0.4.4"
unicrypto = ">=0.0.10"
[[package]]
name = "asyncpg"
version = "0.30.0"
@@ -301,6 +388,23 @@ docs = ["Sphinx (>=8.1.3,<8.2.0)", "sphinx-rtd-theme (>=1.2.2)"]
gssauth = ["gssapi", "sspilib"]
test = ["distro (>=1.9.0,<1.10.0)", "flake8 (>=6.1,<7.0)", "flake8-pyi (>=24.1.0,<24.2.0)", "gssapi", "k5test", "mypy (>=1.8.0,<1.9.0)", "sspilib", "uvloop (>=0.15.3)"]
[[package]]
name = "asysocks"
version = "0.2.13"
description = ""
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "asysocks-0.2.13-py3-none-any.whl", hash = "sha256:e32f478eac58566162d3e5af02ed6b6625317d9ddf83af22109bd13a24ef721a"},
{file = "asysocks-0.2.13.tar.gz", hash = "sha256:44185b2c471e63b7293173967eef3b0f5e60ed5cc1b7650a30a9569e49ff25f8"},
]
[package.dependencies]
asn1crypto = "*"
cryptography = "*"
h11 = ">=0.14.0"
[[package]]
name = "attrs"
version = "25.3.0"
@@ -852,10 +956,6 @@ files = [
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"},
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"},
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"},
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c"},
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1"},
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2"},
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec"},
{file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"},
{file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"},
{file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"},
@@ -868,14 +968,8 @@ files = [
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"},
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"},
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"},
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f"},
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757"},
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0"},
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b"},
{file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"},
{file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"},
{file = "Brotli-1.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28"},
{file = "Brotli-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f"},
{file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"},
{file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"},
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"},
@@ -886,24 +980,8 @@ files = [
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"},
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"},
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"},
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9"},
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb"},
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111"},
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839"},
{file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"},
{file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"},
{file = "Brotli-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5"},
{file = "Brotli-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8"},
{file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f"},
{file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648"},
{file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0"},
{file = "Brotli-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089"},
{file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368"},
{file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c"},
{file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284"},
{file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7"},
{file = "Brotli-1.1.0-cp313-cp313-win32.whl", hash = "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0"},
{file = "Brotli-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b"},
{file = "Brotli-1.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1"},
{file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d"},
{file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b"},
@@ -913,10 +991,6 @@ files = [
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2"},
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354"},
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2"},
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:aea440a510e14e818e67bfc4027880e2fb500c2ccb20ab21c7a7c8b5b4703d75"},
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:6974f52a02321b36847cd19d1b8e381bf39939c21efd6ee2fc13a28b0d99348c"},
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:a7e53012d2853a07a4a79c00643832161a910674a893d296c9f1259859a289d2"},
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:d7702622a8b40c49bffb46e1e3ba2e81268d5c04a34f460978c6b5517a34dd52"},
{file = "Brotli-1.1.0-cp36-cp36m-win32.whl", hash = "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460"},
{file = "Brotli-1.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579"},
{file = "Brotli-1.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c"},
@@ -928,10 +1002,6 @@ files = [
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74"},
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b"},
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438"},
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:cb1dac1770878ade83f2ccdf7d25e494f05c9165f5246b46a621cc849341dc01"},
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:3ee8a80d67a4334482d9712b8e83ca6b1d9bc7e351931252ebef5d8f7335a547"},
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:5e55da2c8724191e5b557f8e18943b1b4839b8efc3ef60d65985bcf6f587dd38"},
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:d342778ef319e1026af243ed0a07c97acf3bad33b9f29e7ae6a1f68fd083e90c"},
{file = "Brotli-1.1.0-cp37-cp37m-win32.whl", hash = "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95"},
{file = "Brotli-1.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68"},
{file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3"},
@@ -944,10 +1014,6 @@ files = [
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a"},
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088"},
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596"},
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d2b35ca2c7f81d173d2fadc2f4f31e88cc5f7a39ae5b6db5513cf3383b0e0ec7"},
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:af6fa6817889314555aede9a919612b23739395ce767fe7fcbea9a80bf140fe5"},
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:2feb1d960f760a575dbc5ab3b1c00504b24caaf6986e2dc2b01c09c87866a943"},
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4410f84b33374409552ac9b6903507cdb31cd30d2501fc5ca13d18f73548444a"},
{file = "Brotli-1.1.0-cp38-cp38-win32.whl", hash = "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b"},
{file = "Brotli-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0"},
{file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a"},
@@ -960,10 +1026,6 @@ files = [
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c"},
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d"},
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59"},
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0737ddb3068957cf1b054899b0883830bb1fec522ec76b1098f9b6e0f02d9419"},
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4f3607b129417e111e30637af1b56f24f7a49e64763253bbc275c75fa887d4b2"},
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6c6e0c425f22c1c719c42670d561ad682f7bfeeef918edea971a79ac5252437f"},
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:494994f807ba0b92092a163a0a283961369a65f6cbe01e8891132b7a320e61eb"},
{file = "Brotli-1.1.0-cp39-cp39-win32.whl", hash = "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64"},
{file = "Brotli-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467"},
{file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"},
@@ -2575,6 +2637,38 @@ files = [
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
]
[[package]]
name = "minidump"
version = "0.0.24"
description = "Python library to parse Windows minidump file format"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "minidump-0.0.24-py3-none-any.whl", hash = "sha256:9c016e35c8fe37c82a01b0a266f5416a0b0138934d92affb436ac2e72372bec6"},
{file = "minidump-0.0.24.tar.gz", hash = "sha256:f7ae09b944f3b17ccf5cecc66f9ff5a7a45b053474a13aeb012f4c9204470437"},
]
[[package]]
name = "minikerberos"
version = "0.4.6"
description = "Kerberos manipulation library in pure Python"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "minikerberos-0.4.6-py3-none-any.whl", hash = "sha256:9bb7160e0ccbf742746f9777c54311187113ce813d2cc75d470e37602a908a12"},
{file = "minikerberos-0.4.6.tar.gz", hash = "sha256:56fd389e06197043b7d89eee713e9a5f2bb546020db6a064e1921d740f957290"},
]
[package.dependencies]
asn1crypto = ">=1.5.1"
asysocks = ">=0.2.8"
oscrypto = ">=1.3.0"
six = "*"
tqdm = "*"
unicrypto = ">=0.0.10"
[[package]]
name = "minio"
version = "7.2.15"
@@ -2594,6 +2688,29 @@ pycryptodome = "*"
typing-extensions = "*"
urllib3 = "*"
[[package]]
name = "msldap"
version = "0.5.15"
description = "Python library to play with MS LDAP"
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "msldap-0.5.15-py3-none-any.whl", hash = "sha256:ee4224cf3964c386a52424a4b6d763a866b4d7ae6d5597a0af58611588668531"},
{file = "msldap-0.5.15.tar.gz", hash = "sha256:b8024a2c0559158ec407cb6317201ecc83627248baaeecee5dfd4419ca773e3d"},
]
[package.dependencies]
asn1crypto = ">=1.3.0"
asyauth = ">=0.0.18"
asysocks = ">=0.2.11"
prompt-toolkit = ">=3.0.2"
tabulate = "*"
tqdm = "*"
unicrypto = ">=0.0.10"
wcwidth = "*"
winacl = ">=0.1.8"
[[package]]
name = "msoffcrypto-tool"
version = "5.4.2"
@@ -3070,6 +3187,21 @@ files = [
{file = "opentelemetry_util_http-0.51b0.tar.gz", hash = "sha256:05edd19ca1cc3be3968b1e502fd94816901a365adbeaab6b6ddb974384d3a0b9"},
]
[[package]]
name = "oscrypto"
version = "1.3.0"
description = "TLS (SSL) sockets, key generation, encryption, decryption, signing, verification and KDFs using the OS crypto libraries. Does not require a compiler, and relies on the OS for patching. Works on Windows, OS X and Linux/BSD."
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "oscrypto-1.3.0-py2.py3-none-any.whl", hash = "sha256:2b2f1d2d42ec152ca90ccb5682f3e051fb55986e1b170ebde472b133713e7085"},
{file = "oscrypto-1.3.0.tar.gz", hash = "sha256:6f5fef59cb5b3708321db7cca56aed8ad7e662853351e7991fcf60ec606d47a4"},
]
[package.dependencies]
asn1crypto = ">=1.5.1"
[[package]]
name = "packaging"
version = "25.0"
@@ -3220,6 +3352,21 @@ files = [
[package.extras]
tests = ["coverage", "pycodestyle", "pydocstyle", "pyflakes"]
[[package]]
name = "prompt-toolkit"
version = "3.0.51"
description = "Library for building powerful interactive command lines in Python"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07"},
{file = "prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed"},
]
[package.dependencies]
wcwidth = "*"
[[package]]
name = "propcache"
version = "0.3.2"
@@ -3980,6 +4127,29 @@ docs = ["sphinx", "sphinx_rtd_theme"]
fuzzer = ["atheris", "hypothesis"]
test = ["coverage[toml] (>=5.2)", "hypothesis", "pytest (>=6.0)", "pytest-benchmark", "pytest-cov", "pytest-timeout"]
[[package]]
name = "pypykatz"
version = "0.6.11"
description = "Python implementation of Mimikatz"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "pypykatz-0.6.11-py3-none-any.whl", hash = "sha256:212e577e4333c6ce326118cc62bd1cc4fe515c05f97e260664616d758b754f3a"},
{file = "pypykatz-0.6.11.tar.gz", hash = "sha256:c8dc3fa3443dec76fc48d9803d7ebf29f4f5fd8ad04682592765d0870f704518"},
]
[package.dependencies]
aesedb = ">=0.1.4,<=0.2.0"
aiosmb = ">=0.4.8,<=0.5.0"
aiowinreg = ">=0.0.11,<=0.1.0"
minidump = ">=0.0.21,<=0.1.0"
minikerberos = ">=0.4.1,<=0.5.0"
msldap = ">=0.5.7,<=0.6.0"
tqdm = "*"
unicrypto = ">=0.0.10,<=0.1.0"
winacl = ">=0.1.9,<=0.2.0"
[[package]]
name = "pyreadline3"
version = "3.5.4"
@@ -4732,6 +4902,21 @@ files = [
{file = "structlog-25.4.0.tar.gz", hash = "sha256:186cd1b0a8ae762e29417095664adf1d6a31702160a46dacb7796ea82f7409e4"},
]
[[package]]
name = "tabulate"
version = "0.9.0"
description = "Pretty-print tabular data"
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"},
{file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"},
]
[package.extras]
widechars = ["wcwidth"]
[[package]]
name = "texttable"
version = "1.7.0"
@@ -4910,6 +5095,20 @@ files = [
{file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"},
]
[[package]]
name = "unicrypto"
version = "0.0.10"
description = "Unified interface for cryptographic libraries"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "unicrypto-0.0.10-py3-none-any.whl", hash = "sha256:77322c68cb6a7ef8ee762dcb0a824a491429f8939793e8a9d64f615baaf595b9"},
]
[package.dependencies]
pycryptodomex = "*"
[[package]]
name = "urllib3"
version = "2.4.0"
@@ -4947,6 +5146,18 @@ h11 = ">=0.8"
[package.extras]
standard = ["colorama (>=0.4)", "httptools (>=0.6.3)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
[[package]]
name = "wcwidth"
version = "0.2.13"
description = "Measures the displayed width of unicode strings in a terminal"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
{file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
]
[[package]]
name = "werkzeug"
version = "3.1.3"
@@ -4993,6 +5204,21 @@ files = [
[package.extras]
dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
[[package]]
name = "winacl"
version = "0.1.9"
description = "ACL/ACE/Security Descriptor manipulation library in pure Python"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "winacl-0.1.9-py3-none-any.whl", hash = "sha256:31ba781a35f3b1bd3c2ece994816c0a5fe113c73018689ab6118010ac0d15099"},
{file = "winacl-0.1.9.tar.gz", hash = "sha256:af70c2ec30178bf9e3c8a1c48c25e8781235fe2c1b321adb46e2f2ae1f8d4aab"},
]
[package.dependencies]
cryptography = ">=38.0.1"
[[package]]
name = "wrapt"
version = "1.17.2"
@@ -5256,4 +5482,4 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.1"
python-versions = "^3.12"
content-hash = "53080891854c995202f164a59212643fe1b748a7fa8da3dfe64f29b013dd1e04"
content-hash = "3ebf19a118a8cfdf86f87b676e064b22892c92f010cb3ff36a9e2df706c0bda6"
+1
View File
@@ -38,6 +38,7 @@ pyarrow = "^19.0.1"
impacket = "^0.12.0"
msoffcrypto-tool = "^5.4.2"
oletools = "^0.60.2"
pypykatz = "^0.6.11"
[tool.poetry.group.dev.dependencies]