cleanup wmiexec_event code
parent
b788f09af8
commit
bdf0fe27e8
|
@ -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)
|
Loading…
Reference in New Issue