Untitled
unknown
plain_text
3 years ago
6.0 kB
10
Indexable
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)Editor is loading...