Skip to content

Commit b0bb706

Browse files
Fixed Major Issue
Re-hauled event_log.py, now made it better and more useful, as well as fixed issues with dependencies Also updated Logicytics.py to remove deprecated code Updated exception logging to discourage it, making only one script now using it Signed-off-by: Shahm Najeeb <[email protected]>
1 parent bbc6f7f commit b0bb706

File tree

6 files changed

+56
-49
lines changed

6 files changed

+56
-49
lines changed

CODE/Logicytics.py

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,6 @@ def handle_special_actions():
124124
log.info("Opening developer menu...")
125125
special_execute("_dev.py")
126126

127-
# Deprecated, remove in v3.3.0
128-
if ACTION == "extra":
129-
print("\033[91mDeprecationWarning: The `extra` feature has been removed! 🚫\n"
130-
"Why? It didn't match our code quality standards.\n"
131-
"What to use instead? Check out our new features with --help\033[0m")
132-
input("Press Enter to exit...")
133-
exit(0)
134-
135127
if ACTION == "update":
136128
log.info("Updating...")
137129
message, log_type = Health.update()
@@ -162,14 +154,6 @@ def handle_special_actions():
162154
input("Press Enter to exit...")
163155
exit(0)
164156

165-
# Deprecated, remove in v3.3.0
166-
if ACTION == "unzip_extra":
167-
print("\033[91mDeprecationWarning: The `unzip_extra` feature has been removed! 🚫\n"
168-
"Why? It didn't match our code quality standards.\n"
169-
"What to use instead? Check out our new features with --help\033[0m")
170-
input("Press Enter to exit...")
171-
exit(0)
172-
173157

174158
def check_privileges():
175159
"""
@@ -204,6 +188,7 @@ def generate_execution_list() -> list | list[str] | list[str | Any]:
204188
execution_list.remove("dir_list.py")
205189
execution_list.remove("tree.ps1")
206190
execution_list.remove("vulnscan.py")
191+
execution_list.remove("event_log.py")
207192

208193
if ACTION == "minimal":
209194
execution_list = [
@@ -237,6 +222,7 @@ def generate_execution_list() -> list | list[str] | list[str | Any]:
237222
execution_list.append("sensitive_data_miner.py")
238223
execution_list.append("dir_list.py")
239224
execution_list.append("tree.ps1")
225+
execution_list.append("event_log.py")
240226
log.warning("This flag will use threading!")
241227

242228
if ACTION == "vulnscan_ai":

CODE/_dev.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def dev_checks() -> None:
127127
print("\nGreat Job! Please tick the box in the GitHub PR request for completing steps in --dev")
128128
except Exception as e:
129129
# Log any exceptions that occur during the process
130-
log_dev.exception(str(e))
130+
log_dev.error(f"An error occurred: {e}")
131131

132132

133133
if __name__ == "__main__":

CODE/event_log.py

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import os
2+
import shutil
3+
import threading
24
from os import mkdir
35

4-
import win32evtlog # TODO - Remove this dependency, find a alternative
6+
import wmi # Import the wmi library
57

68
from logicytics import Log, DEBUG
79

@@ -12,49 +14,64 @@
1214

1315

1416
@log.function
15-
def parse_event_logs(log_type: str, output_file: str, server: str = 'localhost'):
17+
def parse_event_logs(log_type: str, output_file: str):
1618
"""
17-
Parses Windows event logs of a specified type and writes them to an output file.
19+
Parses Windows event logs of a specified type and writes them to an output file using WMI.
1820
1921
Args:
2022
log_type (str): The type of event log to parse (e.g., 'Security', 'Application').
2123
output_file (str): The file path where the parsed event logs will be written.
22-
server (str): The name of the server to connect to. Default is 'localhost'.
2324
2425
Raises:
2526
Exception: If there is an error opening or reading the event log, or writing to the output file.
2627
"""
28+
log.info(f"Parsing {log_type} events (Windows Events) and writing to {output_file}, this may take a while...")
2729
try:
28-
hand = win32evtlog.OpenEventLog(server, log_type)
29-
flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
30-
total = win32evtlog.GetNumberOfEventLogRecords(hand)
30+
# Initialize WMI connection
31+
c = wmi.WMI()
3132

33+
# Query based on log_type ('Security', 'Application', or 'System')
34+
query = f"SELECT * FROM Win32_NTLogEvent WHERE Logfile = '{log_type}'"
35+
log.debug(f"Executing WMI query: {query}")
36+
37+
# Open the output file for writing
3238
with open(output_file, 'w') as f:
33-
f.write(f"Total records: {total}\n\n")
34-
events = win32evtlog.ReadEventLog(hand, flags, 0)
35-
while events:
36-
for event in events:
37-
event_data = {
38-
'Event Category': event.EventCategory,
39-
'Time Generated': event.TimeGenerated.Format(),
40-
'Source Name': event.SourceName,
41-
'Event ID': event.EventID,
42-
'Event Type': event.EventType,
43-
'Event Data': event.StringInserts
44-
}
45-
f.write(str(event_data) + '\n\n')
46-
events = win32evtlog.ReadEventLog(hand, flags, 0)
47-
48-
win32evtlog.CloseEventLog(hand)
39+
events = c.query(query)
40+
f.write(f"Total records: {len(events)}\n\n")
41+
log.debug(f"Number of events retrieved: {len(events)}")
42+
for event in events:
43+
event_data = {
44+
'Event Category': event.Category,
45+
'Time Generated': event.TimeGenerated,
46+
'Source Name': event.SourceName,
47+
'Event ID': event.EventCode,
48+
'Event Type': event.Type,
49+
'Event Data': event.InsertionStrings
50+
}
51+
f.write(str(event_data) + '\n\n')
52+
4953
log.info(f"{log_type} events (Windows Events) have been written to {output_file}")
54+
except Exception as err:
55+
log.error(f"Fatal issue: {err}")
56+
57+
58+
if __name__ == "__main__":
59+
try:
60+
if os.path.exists('event_logs'):
61+
shutil.rmtree('event_logs')
62+
mkdir('event_logs')
5063
except Exception as e:
5164
log.error(f"Fatal issue: {e}")
65+
exit(1)
5266

67+
threads = []
68+
threads_items = [('Security', 'event_logs/Security_events.txt'),
69+
('Application', 'event_logs/App_events.txt'),
70+
('System', 'event_logs/System_events.txt')]
5371

54-
if __name__ == "__main__":
55-
if os.path.exists('event_logs'):
56-
os.rmdir('event_logs')
57-
mkdir('event_logs')
58-
parse_event_logs('Security', 'event_logs/Security_events.txt')
59-
parse_event_logs('Application', 'event_logs/App_events.txt')
60-
parse_event_logs('System', 'event_logs/System_events.txt')
72+
for log_type_main, output_file_main in threads_items:
73+
thread = threading.Thread(target=parse_event_logs, args=(log_type_main, output_file_main))
74+
threads.append(thread)
75+
thread.start()
76+
for thread in threads:
77+
thread.join()

CODE/log_miner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def backup_windows_logs():
3535
stdout, stderr = process.communicate(input=cmd)
3636

3737
if process.returncode != 0:
38-
log.exception(f"Failed to backup logs: {stderr.strip()}", ChildProcessError)
38+
log.error(f"Failed to backup logs: {stderr.strip()}")
3939

4040
log.info(f"Windows logs backed up to {backup_file}")
4141
except Exception as e:

CODE/logicytics/Logger.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ def exception(self, message, exception_type: Type = Exception):
233233
"""
234234
Logs an exception message.
235235
236+
This is not recommended for use in production code, as it raises the exception after logging it.
237+
Use Log().error() instead.
238+
236239
:param message: The exception message to be logged.
237240
:param exception_type: The type of exception to raise.
238241
"""

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ safetensors~=0.4.5
1919
prettytable~=3.12.0
2020
pandas~=2.2.2
2121
scapy~=2.5.0
22-
sentence-transformers~=3.3.1
22+
sentence-transformers~=3.3.1
23+
WMI~=1.5.1

0 commit comments

Comments
 (0)