clean and fix imports

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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