def test_etw_multi_providers_bitmask(self): """ Tests the etw capture class using multiple providers :return: None """ # Instantiate an ETW object capture = etw.ETW( {'Microsoft-Windows-PowerShell': GUID("{A0C1853B-5C40-4B15-8766-3CF1C58F985A}")}, any_keywords=['Runspace'], all_keywords=['Pipeline']) assert(capture.guids['Microsoft-Windows-PowerShell'][1] == 0x0000000000000001) assert(capture.guids['Microsoft-Windows-PowerShell'][2] == 0x0000000000000002) # add provider capture.add_provider( {'Microsoft-Windows-WMI-Activity': GUID("{1418EF04-B0B4-4623-BF7E-D74AB47BBDAA}")}, any_keywords=['Microsoft-Windows-WMI-Activity/Trace'], all_keywords=['Microsoft-Windows-WMI-Activity/Operational']) assert(capture.guids['Microsoft-Windows-WMI-Activity'][1] == 0x8000000000000000) assert(capture.guids['Microsoft-Windows-WMI-Activity'][2] == 0x4000000000000000) return
def test_etw_multi_providers_bitmask(self): """ Tests the etw capture class using multiple providers :return: None """ # Instantiate an ProviderInfo object provider = ProviderInfo('Microsoft-Windows-Kernel-Process', GUID("{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}"), any_keywords=['WINEVENT_KEYWORD_PROCESS'], all_keywords=['WINEVENT_KEYWORD_THREAD']) assert (provider.any_bitmask == 0x0000000000000010) assert (provider.all_bitmask == 0x0000000000000020) # add provider provider = ProviderInfo('Microsoft-Windows-WinINet', GUID("{43D1A55C-76D6-4F7E-995C-64C711E5CAFE}"), any_keywords=['WININET_KEYWORD_HANDLES'], all_keywords=['WININET_KEYWORD_HTTP']) assert (provider.any_bitmask == 0x0000000000000001) assert (provider.all_bitmask == 0x0000000000000002) return
def test_etw_capture_multi_providers(self): """ Tests the etw capture class using multiple providers :return: None """ if self.skip_tests: self.skipTest('PowerShell version must be greater than 2') # Instantiate an ETW object capture = etw.ETW({'Microsoft-Windows-PowerShell': GUID("{A0C1853B-5C40-4B15-8766-3CF1C58F985A}")}) # add provider capture.add_provider({'Microsoft-Windows-WMI-Activity': GUID("{1418EF04-B0B4-4623-BF7E-D74AB47BBDAA}")}) capture.start(lambda event_tufo: self.event_tufo_list.append(event_tufo), None) # start powershell args = ['powershell'] p = sp.Popen(args, stdout=sp.DEVNULL, stderr=sp.DEVNULL) time.sleep(5) p.kill() # do wmi query w = wmi.WMI() w.init() w.connect('root\\cimv2') enum = w.do_query('SELECT * FROM Win32_Process') enum.vtbl.Release(enum.this) w.fini() # Stop the ETW instance capture.stop() # check for powershell capture event = self.find_event('POWERSHELL CONSOLE STARTUP') self.assertTrue(event) event = self.trim_fields(event) # This event should have 1 field self.assertEqual(len(event), 1) # check capture events = self.find_all_events('MICROSOFT-WINDOWS-WMI-ACTIVITY') found = False for event in events: try: if 'SELECT * FROM Win32_Process' in str(event['Operation']): found = True break except: pass self.assertTrue(found) self.event_tufo = [] return
def __init__(self, ring_buf_size=1024, max_str_len=1024, min_buffers=0, max_buffers=0, level=et.TRACE_LEVEL_INFORMATION, any_keywords=None, all_keywords=None, filters=None, event_callback=None, logfile=None, no_conout=False): """ Initializes an instance of RDPETW. The default parameters represent a very typical use case and should not be overridden unless the user knows what they are doing. :param ring_buf_size: The size of the ring buffer used for capturing events. :param max_str_len: The maximum length of the strings the proceed the structure. Unless you know what you are doing, do not modify this value. :param min_buffers: The minimum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param max_buffers: The maximum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param level: Logging level :param any_keywords: List of keywords to match :param all_keywords: List of keywords that all must match :param filters: List of filters to apply to capture. :param event_callback: Callback for processing events :param logfile: Path to logfile. :param no_conout: If true does not output live capture to console. """ self.logfile = logfile self.no_conout = no_conout if event_callback: self.event_callback = event_callback else: self.event_callback = self.on_event providers = [ ProviderInfo( 'Microsoft-Windows-TerminalServices-RemoteConnectionManager', GUID("{C76BAA63-AE81-421C-B425-340B4B24157F}"), level, any_keywords, all_keywords), ProviderInfo( 'Microsoft-Windows-TerminalServices-LocalSessionManager', GUID("{5D896912-022D-40AA-A3A8-4FA5515C76D7}"), level, any_keywords, all_keywords) ] super().__init__(ring_buf_size=ring_buf_size, max_str_len=max_str_len, min_buffers=min_buffers, max_buffers=max_buffers, event_callback=self.event_callback, task_name_filters=filters, providers=providers)
def __init__(self, ring_buf_size=1024, max_str_len=1024, min_buffers=0, max_buffers=0, level=et.TRACE_LEVEL_INFORMATION, any_keywords=None, all_keywords=None, filters=None, event_callback=None, logfile=None, no_conout=False): """ Initializes an instance of INETETW. The default parameters represent a very typical use case and should not be overridden unless the user knows what they are doing. :param ring_buf_size: The size of the ring buffer used for capturing events. :param max_str_len: The maximum length of the strings the proceed the structure. Unless you know what you are doing, do not modify this value. :param min_buffers: The minimum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param max_buffers: The maximum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param level: Logging level :param any_keywords: List of keywords to match :param all_keywords: List of keywords that all must match :param filters: List of filters to apply to capture. :param event_callback: Callback for processing events :param logfile: Path to logfile. :param no_conout: If true does not output live capture to console. """ self.logfile = logfile self.no_conout = no_conout if event_callback: self.event_callback = event_callback else: self.event_callback = self.on_event providers = [ ProviderInfo('Microsoft-Windows-WinINet', GUID("{43D1A55C-76D6-4F7E-995C-64C711E5CAFE}"), level, any_keywords, all_keywords), ProviderInfo('Microsoft-Windows-WinINet-Capture', GUID("{A70FF94F-570B-4979-BA5C-E59C9FEAB61B}"), level, any_keywords, all_keywords) ] super().__init__(ring_buf_size=ring_buf_size, max_str_len=max_str_len, min_buffers=min_buffers, max_buffers=max_buffers, event_callback=self.event_callback, task_name_filters=filters, providers=providers)
def create_instance(self, clsid, type, iid): if self.initialized is False: raise ComException('COM must be initialized before calling CoCreateInstance()') ptr = ct.c_void_p(0) error = ct.windll.ole32.CoCreateInstance(ct.byref(GUID(clsid)), None, type, ct.byref(GUID(iid)), ct.byref(ptr)) if error != tdh.ERROR_SUCCESS: raise ct.WinError() return ptr
def test_etw_eq(self): """ Test container classes comparision :return: None """ params = et.ENABLE_TRACE_PARAMETERS() params.Version = 1 other_params = et.ENABLE_TRACE_PARAMETERS() other_params.Version = 1 provider = ProviderInfo('Microsoft-Windows-Kernel-Process', GUID("{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}"), any_keywords=['WINEVENT_KEYWORD_PROCESS'], params=ct.pointer(params)) other_provider = ProviderInfo( 'Microsoft-Windows-Kernel-Process', GUID("{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}"), any_keywords=['WINEVENT_KEYWORD_PROCESS'], params=ct.pointer(other_params)) self.assertEqual(provider, other_provider) other_params.Version = 2 self.assertNotEqual(provider, other_provider) event_id_list = [54] event_filter = ep.EVENT_FILTER_EVENT_ID(common.TRUE, event_id_list).get() event_filters = [ ep.EVENT_FILTER_DESCRIPTOR( ct.addressof(event_filter.contents), ct.sizeof(event_filter.contents) + ct.sizeof(wt.USHORT) * len(event_id_list), ep.EVENT_FILTER_TYPE_EVENT_ID) ] properties = ProviderParameters(0, event_filters) other_properties = ProviderParameters(0, event_filters) self.assertEqual(properties, other_properties) other_properties.get().contents.Version = 1 self.assertNotEqual(properties, other_properties) params = TraceProperties(1024, 1024, 0, 10) other_params = TraceProperties(1024, 1024, 0, 10) self.assertEqual(params, other_params) other_params.get().contents.BufferSize = 1025 self.assertNotEqual(params, other_params) return
def test_etw_capture_multi_providers(self): """ Tests the etw capture class using multiple providers :return: None """ # Instantiate an ETW object providers = [ ProviderInfo('Microsoft-Windows-WinINet', GUID("{43D1A55C-76D6-4F7E-995C-64C711E5CAFE}")), ProviderInfo('Microsoft-Windows-Kernel-Process', GUID("{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}")) ] capture = ETW(providers=providers, event_callback=lambda event_tufo: self.event_tufo_list. append(event_tufo)) capture.start() # start ping args = ['ping.exe'] p = sp.Popen(args, stdout=sp.DEVNULL, stderr=sp.DEVNULL) time.sleep(5) p.kill() self.makeRequest() # Stop the ETW instance capture.stop() # check for process start event = self.find_event('PROCESSSTART') self.assertTrue(event) event = self.trim_fields(event) # This event should have 6 fields self.assertEqual(len(event), 6) event = self.find_event('WININET_READDATA') self.assertTrue(event) event = self.trim_fields(event) # This event should have 3 fields self.assertEqual(len(event), 3) self.event_tufo = [] return
def test_etw_nt_logger(self): """ Tests to ensure nt kernel logger capture works properly :return: None """ capture = ETW( session_name='NT Kernel Logger', providers=[ ProviderInfo('Windows Kernel Trace', GUID("{9E814AAD-3204-11D2-9A82-006008A86939}"), any_keywords=['process']) ], event_callback=lambda event_tufo: self.event_tufo_list.append( event_tufo)) capture.start() # start ping.exe args = ['ping.exe'] p = sp.Popen(args, stdout=sp.DEVNULL, stderr=sp.DEVNULL) time.sleep(2) p.kill() capture.stop() event = self.find_event('PROCESS') self.assertTrue(event) event = self.trim_fields(event) # This event should have 10 fields self.assertEqual(len(event), 10) self.event_tufo = [] return
def test_etw_capture(self): """ Tests the etw capture :return: None """ # Instantiate an ETW object capture = ETW(providers=[ ProviderInfo('Microsoft-Windows-WinINet', GUID("{43D1A55C-76D6-4F7E-995C-64C711E5CAFE}")) ], event_callback=lambda event_tufo: self.event_tufo_list. append(event_tufo)) capture.start() self.makeRequest() # Ensure that we have a chance for all the events to come back time.sleep(5) # Stop the ETW instance capture.stop() event = self.find_event('WININET_READDATA') self.assertTrue(event) event = self.trim_fields(event) # This event should have 3 fields self.assertEqual(len(event), 3) self.event_tufo = [] return
def __init__(self, ring_buf_size=1024, max_str_len=1024, min_buffers=0, max_buffers=0, level=et.TRACE_LEVEL_INFORMATION, any_keywords=None, all_keywords=None): """ Initializes an instance of PROCETW. The default parameters represent a very typical use case and should not be overridden unless the user knows what they are doing. :param ring_buf_size: The size of the ring buffer used for capturing events. :param max_str_len: The maximum length of the strings the proceed the structure. Unless you know what you are doing, do not modify this value. :param min_buffers: The minimum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param max_buffers: The maximum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param level: Logging level :param any_keywords: List of keywords to match :param all_keywords: List of keywords that all must match """ guid = { 'Microsoft-Windows-Kernel-Process': GUID("{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}") } super().__init__(guid, ring_buf_size, max_str_len, min_buffers, max_buffers, level, any_keywords, all_keywords)
def test_etw_capture(self): """ Tests the etw capture :return: None """ if self.skip_tests: self.skipTest('PowerShell version must be greater than 2') # Instantiate an ETW object capture = etw.ETW({'Microsoft-Windows-PowerShell': GUID("{A0C1853B-5C40-4B15-8766-3CF1C58F985A}")}) capture.start(lambda event_tufo: self.event_tufo_list.append(event_tufo), None) # start powershell args = ['powershell'] p = sp.Popen(args, stdout=sp.DEVNULL, stderr=sp.DEVNULL) time.sleep(5) p.kill() # Stop the ETW instance capture.stop() event = self.find_event('POWERSHELL CONSOLE STARTUP') self.assertTrue(event) event = self.trim_fields(event) # This event should have 1 field self.assertEqual(len(event), 1) self.event_tufo = [] return
def test_etw_callback_wait(self): """ Tests the etw capture wait time :return: None """ # Instantiate an ETW object capture = ETW(providers=[ ProviderInfo('Microsoft-Windows-Kernel-Process', GUID("{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}")) ], event_callback=lambda event_tufo: self.event_tufo_list. append(event_tufo), callback_wait_time=0.0025) capture.start() # start ping args = ['ping.exe'] p = sp.Popen(args, stdout=sp.DEVNULL, stderr=sp.DEVNULL) time.sleep(5) p.kill() # Stop the ETW instance capture.stop() # check for process start event = self.find_event('PROCESSSTART') self.assertTrue(event) event = self.trim_fields(event) # This event should have 6 fields self.assertEqual(len(event), 6) self.event_tufo = [] return
def test_etw_get_keywords_bitmask(self): """ Tests to ensure the correct bitmask is found for the provider (Windows Kernel Trace) :return: None """ assert(etw.get_keywords_bitmask( GUID('{9E814AAD-3204-11D2-9A82-006008A86939}'), ['process']) == 0x0000000000000001) return
def __init__( self, ring_buf_size=1024, max_str_len=1024, min_buffers=0, max_buffers=0, level=et.TRACE_LEVEL_INFORMATION, any_keywords=None, all_keywords=None): """ Initializes an instance of INETETW. The default parameters represent a very typical use case and should not be overridden unless the user knows what they are doing. :param ring_buf_size: The size of the ring buffer used for capturing events. :param max_str_len: The maximum length of the strings the proceed the structure. Unless you know what you are doing, do not modify this value. :param min_buffers: The minimum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param max_buffers: The maximum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param level: Logging level :param any_keywords: List of keywords to match :param all_keywords: List of keywords that all must match """ guid = {'Microsoft-Windows-WinINet': GUID("{43D1A55C-76D6-4F7E-995C-64C711E5CAFE}")} super().__init__( guid, ring_buf_size, max_str_len, min_buffers, max_buffers, level, any_keywords, all_keywords) self.add_provider( {'Microsoft-Windows-WinINet-Capture': GUID("{A70FF94F-570B-4979-BA5C-E59C9FEAB61B}")}, any_keywords, all_keywords)
def __init__(self, ring_buf_size=1024, max_str_len=1024, min_buffers=0, max_buffers=0, level=et.TRACE_LEVEL_INFORMATION, any_keywords=None, all_keywords=None): """ Initializes an instance of RDPETW. The default parameters represent a very typical use case and should not be overridden unless the user knows what they are doing. :param ring_buf_size: The size of the ring buffer used for capturing events. :param max_str_len: The maximum length of the strings the proceed the structure. Unless you know what you are doing, do not modify this value. :param min_buffers: The minimum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param max_buffers: The maximum number of buffers for an event tracing session. Unless you know what you are doing, do not modify this value. :param level: Logging level :param any_keywords: List of keywords to match :param all_keywords: List of keywords that all must match """ guid = { 'Microsoft-Windows-TerminalServices-RemoteConnectionManager': GUID("{C76BAA63-AE81-421C-B425-340B4B24157F}") } super().__init__(guid, ring_buf_size, max_str_len, min_buffers, max_buffers, level, any_keywords, all_keywords) self.add_provider( { 'Microsoft-Windows-TerminalServices-LocalSessionManager': GUID("{5D896912-022D-40AA-A3A8-4FA5515C76D7}") }, any_keywords, all_keywords)
WBEM_FLAG_NO_ERROR_OBJECT = 0x40 WBEM_FLAG_RETURN_ERROR_OBJECT = 0 WBEM_FLAG_SEND_STATUS = 0x80 WBEM_FLAG_DONT_SEND_STATUS = 0 WBEM_FLAG_ENSURE_LOCATABLE = 0x100 WBEM_FLAG_DIRECT_READ = 0x200 WBEM_FLAG_SEND_ONLY_SELECTED = 0 WBEM_RETURN_WHEN_COMPLETE = 0 WBEM_RETURN_IMMEDIATELY = 0x10 WBEM_MASK_RESERVED_FLAGS = 0x1f000 WBEM_FLAG_USE_AMENDED_QUALIFIERS = 0x20000 WBEM_FLAG_STRONG_VALIDATION = 0x10000 HRESULT = wt.LONG CLSID_WbemLocator = GUID("{4590f811-1d3a-11d0-891f-00aa004b2e24}") IID_IWbemLocator = GUID("{dc12a687-737f-11cf-884d-00aa004b2e24}") # generic prototype Generic_Proto = ct.WINFUNCTYPE(HRESULT, wt.LPVOID) # virtual HRESULT STDMETHODCALLTYPE QueryInterface( # /* [in] */ REFIID riid, # /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) = 0; # # virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; # # virtual ULONG STDMETHODCALLTYPE Release( void) = 0; # IUnknown method prototypes IUnknown_QueryInterface_Proto = ct.WINFUNCTYPE(HRESULT, wt.LPVOID,
# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ######################################################################## import ctypes as ct import ctypes.wintypes as wt from etw.GUID import GUID # This GUID allow us to enable and disable file share auditing audit_objectaccess_share = GUID("{0cce9224-69ae-11d9-bed3-505054503030}") POLICY_AUDIT_EVENT_SUCCESS = 0x1 POLICY_AUDIT_EVENT_FAILURE = 0x2 POLICY_AUDIT_EVENT_NONE = 0x4 class AUDIT_POLICY_INFORMATION(ct.Structure): _fields_ = [('AuditSubCategoryGuid', GUID), ('AuditingInformation', wt.ULONG), ('AuditCategoryGuid', GUID)] # Function Definitions AuditSetSystemPolicy = ct.windll.advapi32.AuditSetSystemPolicy AuditSetSystemPolicy.argtypes = [ ct.POINTER(AUDIT_POLICY_INFORMATION), wt.ULONG