def readFromEvtx(path_evtx, root, baseline): global num_alerts server = "localhost" # Reading from a file if path_evtx: try: h_log = win32evtlog.OpenBackupEventLog(server, path_evtx) except Exception, e: log.error(str(e)) exit(1)
def do_action(self): server = None events_list = [] # Reading from a file if self.filepath: try: h_log = win32evtlog.OpenBackupEventLog(server, self.filepath) except Exception, e: log.error(str(e)) self.console_print(e.args[2]) exit(1)
def readevents(path): logHandle = win32evtlog.OpenBackupEventLog( None, path) # None=NULL means local host flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ total = win32evtlog.GetNumberOfEventLogRecords(logHandle) LOGGER.info("Total number of records for {} is: {}".format(path, total)) # if "security" in path.lower(): # logType = "Security" # elif "application" in path.lower(): # logType = "Application" # elif "system" in path.lower(): # logType = "System" # else: # LOGGER.error("Unknown log type - put something in path") # sys.exit(-1) event_dict = None while True: events = win32evtlog.ReadEventLog(logHandle, flags, 0) if events: for event in events: event_dict = {} event_dict['TimeGenerated'] = time.strftime( "%#c", time.localtime(int(event.TimeGenerated))) event_dict['SourceName'] = event.SourceName event_dict['Id'] = event.EventID event_dict['EventType'] = event.EventType event_dict['ComputerName'] = event.ComputerName if event.StringInserts: event_dict['data'] = "|".join(event.StringInserts) description = expandString(event) event_dict['Description'] = description if description: event_dict.update(description_to_fields(description)) first_line = description.split("\r\n")[0] event_dict['Short Description'] = first_line yield event_dict else: break
def scan_one_audit_log(path_event_log, backup_flag=True): flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ list_id = [4656, 4663, 4660, 4659] try: if backup_flag: handle = win32evtlog.OpenBackupEventLog(None, path_event_log) else: handle = win32evtlog.OpenEventLog(None, "Security") num_records = win32evtlog.GetNumberOfEventLogRecords(handle) total = 0 pending_delete = {} alert_dict = {} events = 1 # Object while events: events = win32evtlog.ReadEventLog(handle, flags, 0) for event in events: event_category = event.EventCategory # ID of event event_id = winerror.HRESULT_CODE(event.EventID) # Category: File System if event_category == 12800 and filter_id(event_id, list_id): # Time generated event event_time = event.TimeGenerated.strftime( '%Y-%m-%d %H:%M:%S') event_computer = str(event.ComputerName) event_user = event.StringInserts[1] event_object = event.StringInserts[6] alert_dict['time'] = event_time alert_dict['user'] = event_user alert_dict['domain'] = event_computer alert_dict['resource'] = event_object # A handle was requested. if event_id == 4656 and has_key(event_object, pending_delete): # The file was not deleted -> created/modified pending_delete[event_object]['alive'] = True # Event 4663 = object access. elif event_id == 4663: event_access_mask = event.StringInserts[9] # 0x10000 = Delete, but this can mean different things - delete, overwrite, rename, move. if event_access_mask == '0x10000' and not is_contain_str( "RECYCLE.BIN", event_object): # Ignore metadata files in the recycle bin. if has_key(event_object, pending_delete): # Is it already in the list? If so, kick it out and replace it. # The most recent handle is used to track a moved file. del pending_delete[event_object] # Record the filename, username, handle ID, and time. pending_delete[event_object] = {} pending_delete[event_object]['user'] = event_user pending_delete[event_object][ 'handle_id'] = event.StringInserts[7] pending_delete[event_object][ 'time_created'] = event_time pending_delete[event_object]['alive'] = False pending_delete[event_object]['confirmed'] = False # 0x2 = is a classic "object was modified" signal. if event_access_mask == '0x2' and not is_contain_str( "RECYCLE.BIN", event_object): # Generate report alert_dict['action'] = ADD_FILE_ACTION_MSG alert_dict['note'] = '0x2' print( "Time: %s, User: %s, Domain: %s, Action: %s, Resource: %s, AccessMask: %s." % (event_time, event_user, event_computer, ADD_FILE_ACTION_MSG, event_object, "0x2")) insert_alert_monitor(alert_dict) # The file was not actually deleted, so remove it from this array. try: del pending_delete[event_object] except (Exception, ValueError): continue # A 4663 event with 0x80 (Read Attributes) is logged # with the same handle ID when files/folders are moved or renamed. if event_access_mask == '0x80': for key in pending_delete.keys(): # If the Handle & User match...and the object wasn't deleted... # figure out whether it was moved or renamed. if pending_delete[key]['handle_id'] == event.StringInserts[7] \ and pending_delete[key]['user'] == event_user \ and event_object != key \ and not pending_delete[key]['confirmed']: # Files moved to a different folder (same filename, different folder) if get_file_name(event_object ) == get_file_name(key): alert_dict[ 'action'] = MOVE_FILE_ACTION_MSG alert_dict['note'] = '0x2' print( "Time: %s, User: %s, Domain: %s, Action: %s, Resource: %s, AccessMask: %s." % (event_time, event_user, event_computer, MOVE_FILE_ACTION_MSG, event_object, "0x2")) insert_alert_monitor(alert_dict) del pending_delete[key] # Files moved into the recycle bin elif is_contain_str( 'RECYCLE.BIN', event_object): alert_dict[ 'action'] = RECYCLE_FILE_ACTION_MSG alert_dict['note'] = '0x2' print( "Time: %s, User: %s, Domain: %s, Action: %s, Resource: %s, AccessMask: %s." % (event_time, event_user, event_computer, RECYCLE_FILE_ACTION_MSG, event_object, "0x2")) insert_alert_monitor(alert_dict) del pending_delete[key] # Files moved out of the recycle bin elif is_contain_str('RECYCLE.BIN', key): alert_dict[ 'action'] = RESTORE_FILE_ACTION_MSG alert_dict['note'] = '0x2' print( "Time: %s, User: %s, Domain: %s, Action: %s, Resource: %s, AccessMask: %s." % (event_time, event_user, event_computer, RESTORE_FILE_ACTION_MSG, event_object, "0x2")) insert_alert_monitor(alert_dict) del pending_delete[key] # Created / renamed files elif get_folder_name( event_object) == get_folder_name( key): if get_file_name(key) == "New Folder": alert_dict[ 'action'] = ADD_FILE_ACTION_MSG alert_dict['note'] = '' print( "Time: %s, User: %s, Domain: %s, Action: %s, Resource: %s, AccessMask: %s." % (event_time, event_user, event_computer, ADD_FILE_ACTION_MSG, event_object, "")) else: alert_dict[ 'action'] = RENAME_FILE_ACTION_MSG alert_dict['note'] = '' print( "Time: %s, User: %s, Domain: %s, Action: %s, Resource: %s, AccessMask: %s." % (event_time, event_user, event_computer, RENAME_FILE_ACTION_MSG, key, "")) insert_alert_monitor(alert_dict) del pending_delete[key] break # If none of those conditions match, at least note that the file still exists (if applicable). if has_key(event_object, pending_delete): pending_delete[event_object]['alive'] = True # Event 4659 = a handle was requested with intent to delete elif event_id == 4659: alert_dict['action'] = DELETE_FILE_ACTION_MSG alert_dict['note'] = '' print( "Time: %s, User: %s, Domain: %s, Action: %s, Resource: %s, AccessMask: %s." % (event_time, event_user, event_computer, DELETE_FILE_ACTION_MSG, event_object, "")) insert_alert_monitor(alert_dict) # This delete confirmation doesn't happen when objects are moved/renamed; # it does when files are created/deleted/recycled. elif event_id == 4660: for key in pending_delete.keys(): # print(event.StringInserts[5], pending_delete[key]['handle_id']) if pending_delete[key]['handle_id'] == event.StringInserts[5] \ and pending_delete[key]['user'] == event_user: pending_delete[key]['confirmed'] = True # msg = win32evtlogutil.SafeFormatMessage(event, log_type) total = total + len(events) win32evtlog.CloseEventLog(handle) msg = "Done read event_log. Scan: " + str(total) + "/" + str( num_records) + "." return SUCCESS_CODE, msg except Exception as e: print(e, 123) return ERROR_CODE, "Cannot read windows event_log."
def readevents(path): logHandle = None try: logHandle = win32evtlog.OpenBackupEventLog( None, path) # None=NULL means local host flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ total = win32evtlog.GetNumberOfEventLogRecords(logHandle) LOGGER.info("Total number of records for {} is: {}".format( path, total)) # if "security" in path.lower(): # logType = "Security" # elif "application" in path.lower(): # logType = "Application" # elif "system" in path.lower(): # logType = "System" # else: # LOGGER.error("Unknown log type - put something in path") # sys.exit(-1) event_dict = None local_tz = tzlocal.get_localzone() while True: events = win32evtlog.ReadEventLog(logHandle, flags, 0) if events: for event in events: event_dict = {} # print(event.TimeGenerated) # from IPython import embed # embed() # event_dict['TimeGenerated'] = event.TimeGenerated.strftime("%#c") dt = local_tz.localize(event.TimeGenerated).astimezone( pytz.utc) event_dict['TimeGenerated'] = dt.isoformat() event_dict['SourceName'] = event.SourceName # See https://social.msdn.microsoft.com/Forums/sqlserver/en-US/67e49b0b-a9b8-4263-9233-079776f4cbbc/systemdiagnosticseventlogentry-is-showing-wrong-eventid-in-the-eventlogentrymessage-string-?forum=vbgeneral # EventID might be Instance ID and so we 0xFFFF it to bring back to EventID event_dict['Id'] = event.EventID & 0xFFFF event_dict['EventType'] = event.EventType event_dict['ComputerName'] = event.ComputerName if event.StringInserts: event_dict['data'] = "|".join(event.StringInserts) description = expandString(event) event_dict['Description'] = description if description: event_dict.update(description_to_fields(description)) first_line = description.split("\r\n")[0] event_dict['Short Description'] = first_line yield event_dict else: break except pywintypes.error as e: LOGGER.error(str(e)) if e.winerror == 1722: LOGGER.error("Check that Windows Event Log service is running") finally: # if logHandle is not None: # win32api.CloseHandle(logHandle) pass return
def searchInEvtx(path_evtx, filter, attribute): server = "localhost" filter = eval(filter) # Reading from a file if path_evtx: h_log = win32evtlog.OpenBackupEventLog(server, path_evtx) # Reading from evetnlog else: source_type = "Microsoft-Windows-Sysmon/Operational" h_log = win32evtlog.OpenEventLog(server, source_type) total_events = win32evtlog.GetNumberOfEventLogRecords(h_log) log.info("Searching in total events: %d" % total_events) flags = win32evtlog.EVENTLOG_FORWARDS_READ|\ win32evtlog.EVENTLOG_SEQUENTIAL_READ num_events = 0 while num_events < total_events: events = win32evtlog.ReadEventLog(h_log, flags, 0) num_events += len(events) print 'Progress: %d/%d \r' % (num_events, total_events), if events: for event in events: req_parsed = {} if event.EventID in EVENTLOG_EVENTID: req_parsed = parseEventlogIDx(SYSMON_SCHEMA, event, server) try: match = True for filter_attribute in filter: #special case for filter attribute idEvent becouse # it's an int not string if filter_attribute == 'idEvent': if filter[filter_attribute] != \ req_parsed[filter_attribute]: match = False break else: if filter[filter_attribute].lower() not in \ req_parsed[filter_attribute].lower(): match = False break if match: if attribute: try: print req_parsed[attribute] except: log.error('Filter attribute not found') else: pprint.pprint(req_parsed) print "\n" except Exception, e: pass