Untitled
unknown
plain_text
a year ago
6.0 kB
1
Indexable
Never
import win32evtlog import xml.etree.ElementTree as ET import ctypes import sys import time import paramiko import datetime import os LOG_FILE_PATH = 'C:\Windows\System32\winevt\Logs\ForwardedEvents.evtx' INDEX_FILE_PATH = 'last_timestamp.txt' MAX_RECORDS_TO_READ = 500 OUTPUT_FILE_PATH='C:\\Users\\capeuser\\Python\\cape_event_log_integration\\Code\\event_log_output.txt' OUTPUT_FILE_DIR='C:\\Users\\capeuser\\Python\\cape_event_log_integration\\Code\\' MAX_EVENT_COUNT=5000 event_count=0 REMOTE_HOST = '192.168.100.21' REMOTE_USER = 'TCSCAPEAGENT' REMOTE_PASSWORD = 'C@peM@nitor' REMOTE_PATH = '/var/log/EventLog/' current_time = time.strftime("%Y-%m-%d-%H-%M-%S") print(current_time) def is_admin(): try: return ctypes.windll.shell32.IsUserAnAdmin() except: return False def get_last_timestamp(): try: with open(INDEX_FILE_PATH, 'r') as f: last_timestamp = f.readline().strip() return last_timestamp except: return None def write_last_timestamp(timestamp): with open(INDEX_FILE_PATH, 'w') as f: f.write(str(timestamp)) if is_admin(): last_timestamp = get_last_timestamp() if last_timestamp is not None: # convert the last timestamp to a datetime object last_dt = datetime.datetime.strptime(last_timestamp, '%Y-%m-%dT%H:%M:%S.%fZ') # format the last timestamp for the query last_query_timestamp = last_dt.strftime('%Y-%m-%dT%H:%M:%S.%fZ') print(f'Resuming reading events after timestamp {last_timestamp}...') else: last_query_timestamp = None print('Starting to read events from the beginning...') # open event file query_handle = win32evtlog.EvtQuery( LOG_FILE_PATH, win32evtlog.EvtQueryFilePath, f'Event/System[TimeCreated[@SystemTime>"{last_query_timestamp}"]]' if last_query_timestamp is not None else None ) # open output file for writing with open(OUTPUT_FILE_PATH, 'a') as f: stop = False transfer_success_flag=False while not stop: # wait for new events to arrive time.sleep(5) # read 1 record(s) events = win32evtlog.EvtNext(query_handle, MAX_RECORDS_TO_READ) # if there is no record break the loop if len(events) == 0: break for event in events: xml_content = win32evtlog.EvtRender(event, win32evtlog.EvtRenderEventXml) # parse xml content xml = ET.fromstring(xml_content) # xml namespace, root element has a xmlns definition, so we have to use the namespace ns = '{http://schemas.microsoft.com/win/2004/08/events/event}' try: substatus = xml[1][9].text message = xml.find(f'.//{ns}Message').text except IndexError: #print('Substatus field not found in event.') substatus = None message = None event_id = xml.find(f'.//{ns}EventID').text computer = xml.find(f'.//{ns}Computer').text channel = xml.find(f'.//{ns}Channel').text execution = xml.find(f'.//{ns}Execution') time_created = xml.find(f'.//{ns}TimeCreated').get('SystemTime') level = xml.find(f'.//{ns}Level').text # write event data to output file event_data = f'Time: {time_created}, Computer: {computer}, Substatus: {substatus}, Event Id: {event_id},Message: {message},Level: {level},Channel: {channel}\n' f.write(event_data) event_count += 1 #print(event_count) # update last timestamp last_timestamp = xml.find(f'.//{ns}TimeCreated').get('SystemTime') write_last_index(last_timestamp) # check if event count has exceeded the limit if event_count >= MAX_EVENT_COUNT: stop = True break # check if stop flag is set if stop: break # close output file f.close() # check if output file is empty and delete it if it is if os.stat(OUTPUT_FILE_PATH).st_size == 0: os.remove(OUTPUT_FILE_PATH) print('Output file is empty and has been deleted.') else: # transfer file to remote agent import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(REMOTE_HOST, username=REMOTE_USER, password=REMOTE_PASSWORD) try: sftp = ssh.open_sftp() sftp.put(OUTPUT_FILE_PATH, REMOTE_PATH + 'Forwarded_Logs'+"-T" +str(current_time)+".log") sftp.close() print(f"File Transferred Successfully at {current_time}") transfer_success_flag= True except: print("File not Transferred") ssh.close() if transfer_success_flag: print("Renaming the File in our Local") # add a delay before renaming the file time.sleep(5) # rename the local file filename = OUTPUT_FILE_DIR+"sent_event_logs-T" + str(current_time)+".txt" print(filename) os.replace(OUTPUT_FILE_PATH, filename ) else: # Re-run the program with admin rights ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)