cleanup wmiexec_event code

main
Marshall Hallenbeck 2023-09-20 12:06:44 -04:00
parent b788f09af8
commit bdf0fe27e8
1 changed files with 49 additions and 48 deletions

View File

@ -22,7 +22,7 @@
# Get result from reading wmi object ActiveScriptEventConsumer.Name="{command_ResultInstance}" # Get result from reading wmi object ActiveScriptEventConsumer.Name="{command_ResultInstance}"
# #
# Stage 4: # Stage 4:
# Remove everythings in wmi object # Remove everything in wmi object
import time import time
import uuid import uuid
@ -33,9 +33,9 @@ from io import StringIO
from nxc.helpers.powershell import get_ps_script from nxc.helpers.powershell import get_ps_script
from impacket.dcerpc.v5.dtypes import NULL from impacket.dcerpc.v5.dtypes import NULL
from impacket.dcerpc.v5.dcomrt import DCOMConnection from impacket.dcerpc.v5.dcomrt import DCOMConnection
from impacket.dcerpc.v5.dcom.wmi import WBEMSTATUS
from impacket.dcerpc.v5.dcom.wmi import CLSID_WbemLevel1Login, IID_IWbemLevel1Login, IWbemLevel1Login, WBEMSTATUS from impacket.dcerpc.v5.dcom.wmi import CLSID_WbemLevel1Login, IID_IWbemLevel1Login, IWbemLevel1Login, WBEMSTATUS
class WMIEXEC_EVENT: class WMIEXEC_EVENT:
def __init__(self, host, username, password, domain, lmhash, nthash, doKerberos, kdcHost, aesKey, logger, exec_timeout, codec): def __init__(self, host, username, password, domain, lmhash, nthash, doKerberos, kdcHost, aesKey, logger, exec_timeout, codec):
self.__host = host self.__host = host
@ -63,7 +63,8 @@ class WMIEXEC_EVENT:
iWbemLevel1Login.RemRelease() iWbemLevel1Login.RemRelease()
def execute(self, command, output=False): def execute(self, command, output=False):
if "'" in command: command = command.replace("'",r'"') if "'" in command:
command = command.replace("'",r'"')
self.__retOutput = output self.__retOutput = output
self.execute_handler(command) self.execute_handler(command)
@ -84,14 +85,14 @@ class WMIEXEC_EVENT:
self.execute_remote(command) self.execute_remote(command)
# Get command results # Get command results
self.logger.info("Waiting {}s for command completely executed.".format(self.__exec_timeout)) self.logger.info(f"Waiting {self.__exec_timeout}s for command completely executed.")
time.sleep(self.__exec_timeout) time.sleep(self.__exec_timeout)
if self.__retOutput: if self.__retOutput:
self.get_CommandResult() self.get_command_result()
# Clean up # Clean up
self.remove_Instance() self.remove_instance()
def process_vbs(self, command): def process_vbs(self, command):
schedule_taskname = str(uuid.uuid4()) schedule_taskname = str(uuid.uuid4())
@ -117,7 +118,7 @@ class WMIEXEC_EVENT:
vbs = vbs.replace("REPLACE_ME_TEMP_TASKNAME", schedule_taskname) vbs = vbs.replace("REPLACE_ME_TEMP_TASKNAME", schedule_taskname)
return vbs return vbs
def checkError(self, banner, call_status): def check_error(self, banner, call_status):
if call_status != 0: if call_status != 0:
try: try:
error_name = WBEMSTATUS.enumItems(call_status).name error_name = WBEMSTATUS.enumItems(call_status).name
@ -130,81 +131,81 @@ class WMIEXEC_EVENT:
def execute_vbs(self, vbs_content): def execute_vbs(self, vbs_content):
# Copy from wmipersist.py # Copy from wmipersist.py
# Install ActiveScriptEventConsumer # Install ActiveScriptEventConsumer
activeScript, _ = self.__iWbemServices.GetObject('ActiveScriptEventConsumer') active_script, _ = self.__iWbemServices.GetObject('ActiveScriptEventConsumer')
activeScript = activeScript.SpawnInstance() active_script = active_script.SpawnInstance()
activeScript.Name = self.__instanceID active_script.Name = self.__instanceID
activeScript.ScriptingEngine = 'VBScript' active_script.ScriptingEngine = 'VBScript'
activeScript.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] active_script.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0]
activeScript.ScriptText = vbs_content active_script.ScriptText = vbs_content
# Don't output impacket default verbose # Don't output impacket default verbose
current=sys.stdout current=sys.stdout
sys.stdout = StringIO() sys.stdout = StringIO()
resp = self.__iWbemServices.PutInstance(activeScript.marshalMe()) resp = self.__iWbemServices.PutInstance(active_script.marshalMe())
sys.stdout = current sys.stdout = current
self.checkError(f'Adding ActiveScriptEventConsumer.Name="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff) self.check_error(f'Adding ActiveScriptEventConsumer.Name="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff)
# Timer means the amount of milliseconds after the script will be triggered, hard coding to 1 second it in this case. # Timer means the amount of milliseconds after the script will be triggered, hard coding to 1 second it in this case.
wmiTimer, _ = self.__iWbemServices.GetObject('__IntervalTimerInstruction') wmi_timer, _ = self.__iWbemServices.GetObject('__IntervalTimerInstruction')
wmiTimer = wmiTimer.SpawnInstance() wmi_timer = wmi_timer.SpawnInstance()
wmiTimer.TimerId = self.__instanceID wmi_timer.TimerId = self.__instanceID
wmiTimer.IntervalBetweenEvents = 1000 wmi_timer.IntervalBetweenEvents = 1000
# wmiTimer.SkipIfPassed = False # wmiTimer.SkipIfPassed = False
# Don't output verbose # Don't output verbose
current = sys.stdout current = sys.stdout
sys.stdout = StringIO() sys.stdout = StringIO()
resp = self.__iWbemServices.PutInstance(wmiTimer.marshalMe()) resp = self.__iWbemServices.PutInstance(wmi_timer.marshalMe())
sys.stdout = current sys.stdout = current
self.checkError(f'Adding IntervalTimerInstruction.TimerId="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff) self.check_error(f'Adding IntervalTimerInstruction.TimerId="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff)
# EventFilter # EventFilter
eventFilter,_ = self.__iWbemServices.GetObject('__EventFilter') event_filter, _ = self.__iWbemServices.GetObject('__EventFilter')
eventFilter = eventFilter.SpawnInstance() event_filter = event_filter.SpawnInstance()
eventFilter.Name = self.__instanceID event_filter.Name = self.__instanceID
eventFilter.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] event_filter.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0]
eventFilter.Query = f'select * from __TimerEvent where TimerID = "{self.__instanceID}" ' event_filter.Query = f'select * from __TimerEvent where TimerID = "{self.__instanceID}" '
eventFilter.QueryLanguage = 'WQL' event_filter.QueryLanguage = 'WQL'
eventFilter.EventNamespace = r'root\subscription' event_filter.EventNamespace = r'root\subscription'
# Don't output verbose # Don't output verbose
current=sys.stdout current=sys.stdout
sys.stdout = StringIO() sys.stdout = StringIO()
resp = self.__iWbemServices.PutInstance(eventFilter.marshalMe()) resp = self.__iWbemServices.PutInstance(event_filter.marshalMe())
sys.stdout = current sys.stdout = current
self.checkError(f'Adding EventFilter.Name={self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff) self.check_error(f'Adding EventFilter.Name={self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff)
# Binding EventFilter & EventConsumer # Binding EventFilter & EventConsumer
filterBinding, _ = self.__iWbemServices.GetObject('__FilterToConsumerBinding') filter_binding, _ = self.__iWbemServices.GetObject('__FilterToConsumerBinding')
filterBinding = filterBinding.SpawnInstance() filter_binding = filter_binding.SpawnInstance()
filterBinding.Filter = f'__EventFilter.Name="{self.__instanceID}"' filter_binding.Filter = f'__EventFilter.Name="{self.__instanceID}"'
filterBinding.Consumer = f'ActiveScriptEventConsumer.Name="{self.__instanceID}"' filter_binding.Consumer = f'ActiveScriptEventConsumer.Name="{self.__instanceID}"'
filterBinding.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] filter_binding.CreatorSID = [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0]
# Don't output verbose # Don't output verbose
current=sys.stdout current=sys.stdout
sys.stdout = StringIO() sys.stdout = StringIO()
resp = self.__iWbemServices.PutInstance(filterBinding.marshalMe()) resp = self.__iWbemServices.PutInstance(filter_binding.marshalMe())
sys.stdout = current sys.stdout = current
self.checkError(fr'Adding FilterToConsumerBinding.Consumer="ActiveScriptEventConsumer.Name=\"{self.__instanceID}\"", Filter="__EventFilter.Name=\"{self.__instanceID}\""', resp.GetCallStatus(0) & 0xffffffff) self.check_error(fr'Adding FilterToConsumerBinding.Consumer="ActiveScriptEventConsumer.Name=\"{self.__instanceID}\"", Filter="__EventFilter.Name=\"{self.__instanceID}\""', resp.GetCallStatus(0) & 0xffffffff)
def get_CommandResult(self): def get_command_result(self):
try: try:
command_ResultObject, _ = self.__iWbemServices.GetObject(f'ActiveScriptEventConsumer.Name="{self.__instanceID_StoreResult}"') command_result_object, _ = self.__iWbemServices.GetObject(f'ActiveScriptEventConsumer.Name="{self.__instanceID_StoreResult}"')
record = dict(command_ResultObject.getProperties()) record = dict(command_result_object.getProperties())
self.__outputBuffer = base64.b64decode(record['ScriptText']['value']).decode(self.__codec, errors='replace') self.__outputBuffer = base64.b64decode(record['ScriptText']['value']).decode(self.__codec, errors='replace')
except Exception: except Exception:
self.logger.fail("WMIEXEC-EVENT: Could not retrieve output file, it may have been detected by AV. Please try increasing the timeout with the '--exec-timeout' option. If it is still failing, try the 'smb' protocol or another exec method") self.logger.fail("WMIEXEC-EVENT: Could not retrieve output file, it may have been detected by AV. Please try increasing the timeout with the '--exec-timeout' option. If it is still failing, try the 'smb' protocol or another exec method")
def remove_Instance(self): def remove_instance(self):
if self.__retOutput: if self.__retOutput:
resp = self.__iWbemServices.DeleteInstance(f'ActiveScriptEventConsumer.Name="{self.__instanceID_StoreResult}"') resp = self.__iWbemServices.DeleteInstance(f'ActiveScriptEventConsumer.Name="{self.__instanceID_StoreResult}"')
self.checkError(f'Removing ActiveScriptEventConsumer.Name="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff) self.check_error(f'Removing ActiveScriptEventConsumer.Name="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff)
resp = self.__iWbemServices.DeleteInstance(f'ActiveScriptEventConsumer.Name="{self.__instanceID}"') resp = self.__iWbemServices.DeleteInstance(f'ActiveScriptEventConsumer.Name="{self.__instanceID}"')
self.checkError(f'Removing ActiveScriptEventConsumer.Name="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff) self.check_error(f'Removing ActiveScriptEventConsumer.Name="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff)
resp = self.__iWbemServices.DeleteInstance(f'__IntervalTimerInstruction.TimerId="{self.__instanceID}"') resp = self.__iWbemServices.DeleteInstance(f'__IntervalTimerInstruction.TimerId="{self.__instanceID}"')
self.checkError(f'Removing IntervalTimerInstruction.TimerId="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff) self.check_error(f'Removing IntervalTimerInstruction.TimerId="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff)
resp = self.__iWbemServices.DeleteInstance(f'__EventFilter.Name="{self.__instanceID}"') resp = self.__iWbemServices.DeleteInstance(f'__EventFilter.Name="{self.__instanceID}"')
self.checkError(f'Removing EventFilter.Name="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff) self.check_error(f'Removing EventFilter.Name="{self.__instanceID}"', resp.GetCallStatus(0) & 0xffffffff)
resp = self.__iWbemServices.DeleteInstance(fr'__FilterToConsumerBinding.Consumer="ActiveScriptEventConsumer.Name=\"{self.__instanceID}\"",Filter="__EventFilter.Name=\"{self.__instanceID}\""') resp = self.__iWbemServices.DeleteInstance(fr'__FilterToConsumerBinding.Consumer="ActiveScriptEventConsumer.Name=\"{self.__instanceID}\"",Filter="__EventFilter.Name=\"{self.__instanceID}\""')
self.checkError(fr'Removing FilterToConsumerBinding.Consumer="ActiveScriptEventConsumer.Name=\"{self.__instanceID}\"", Filter="__EventFilter.Name=\"{self.__instanceID}\""', resp.GetCallStatus(0) & 0xffffffff) self.check_error(fr'Removing FilterToConsumerBinding.Consumer="ActiveScriptEventConsumer.Name=\"{self.__instanceID}\"", Filter="__EventFilter.Name=\"{self.__instanceID}\""', resp.GetCallStatus(0) & 0xffffffff)