atomicshop 2.14.1__py3-none-any.whl → 2.14.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of atomicshop might be problematic. Click here for more details.
- atomicshop/__init__.py +1 -1
- atomicshop/etws/trace.py +5 -21
- atomicshop/etws/traces/trace_dns.py +17 -14
- atomicshop/etws/traces/trace_sysmon_process_creation.py +34 -22
- atomicshop/get_process_list.py +133 -0
- atomicshop/monitor/change_monitor.py +1 -0
- atomicshop/monitor/checks/dns.py +2 -1
- atomicshop/process.py +3 -3
- atomicshop/process_poller/__init__.py +0 -0
- atomicshop/process_poller/pollers/__init__.py +0 -0
- atomicshop/process_poller/pollers/psutil_pywin32wmi_dll.py +95 -0
- atomicshop/process_poller/process_pool.py +208 -0
- atomicshop/process_poller/simple_process_pool.py +112 -0
- atomicshop/process_poller/tracer_base.py +45 -0
- atomicshop/process_poller/tracers/__init__.py +0 -0
- atomicshop/process_poller/tracers/event_log.py +46 -0
- atomicshop/process_poller/tracers/sysmon_etw.py +68 -0
- atomicshop/wrappers/pywin32w/win_event_log/subscribe.py +106 -43
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/{subscribe_to_process_create.py → process_create.py} +18 -4
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +103 -0
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/schannel_logging.py +97 -0
- {atomicshop-2.14.1.dist-info → atomicshop-2.14.3.dist-info}/METADATA +1 -1
- {atomicshop-2.14.1.dist-info → atomicshop-2.14.3.dist-info}/RECORD +27 -16
- atomicshop/process_poller.py +0 -346
- /atomicshop/{process_name_cmd.py → get_process_name_cmd_dll.py} +0 -0
- {atomicshop-2.14.1.dist-info → atomicshop-2.14.3.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.14.1.dist-info → atomicshop-2.14.3.dist-info}/WHEEL +0 -0
- {atomicshop-2.14.1.dist-info → atomicshop-2.14.3.dist-info}/top_level.txt +0 -0
|
@@ -4,6 +4,7 @@ import time
|
|
|
4
4
|
import threading
|
|
5
5
|
import queue
|
|
6
6
|
from typing import Union
|
|
7
|
+
import binascii
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class EventLogSubscriber:
|
|
@@ -20,15 +21,29 @@ class EventLogSubscriber:
|
|
|
20
21
|
event = event_log_subscriber.emit()
|
|
21
22
|
print(event)
|
|
22
23
|
"""
|
|
23
|
-
def __init__(self, log_channel: str, event_id: int):
|
|
24
|
+
def __init__(self, log_channel: str, event_id: int = None, provider: str = None):
|
|
24
25
|
"""
|
|
25
26
|
:param log_channel: The name of the event log channel to subscribe to. Examples:
|
|
26
27
|
Security, System, Application, etc.
|
|
27
28
|
:param event_id: The ID of the event to subscribe to.
|
|
28
29
|
Example: 4688 for process creation events in "Security" channel.
|
|
30
|
+
You can only subscribe by event ID or provider, not both.
|
|
31
|
+
:param provider: The name of the provider to subscribe to.
|
|
32
|
+
You can only subscribe by event ID or provider, not both.
|
|
29
33
|
"""
|
|
34
|
+
|
|
35
|
+
if event_id is None and provider is None:
|
|
36
|
+
raise ValueError("You must specify either an event ID or provider name to subscribe to.")
|
|
37
|
+
elif event_id and provider:
|
|
38
|
+
raise ValueError("You can only subscribe by event ID or provider, not both.")
|
|
39
|
+
|
|
30
40
|
self.log_channel: str = log_channel
|
|
31
|
-
self.
|
|
41
|
+
self.provider: str = provider
|
|
42
|
+
|
|
43
|
+
if event_id:
|
|
44
|
+
self.event_id: str = str(event_id)
|
|
45
|
+
else:
|
|
46
|
+
self.event_id = event_id
|
|
32
47
|
|
|
33
48
|
self._event_queue = queue.Queue()
|
|
34
49
|
self._subscription_thread = None
|
|
@@ -36,7 +51,7 @@ class EventLogSubscriber:
|
|
|
36
51
|
def start(self):
|
|
37
52
|
"""Start the subscription process."""
|
|
38
53
|
self._subscription_thread = threading.Thread(
|
|
39
|
-
target=start_subscription, args=(self.log_channel, self.event_id, self.
|
|
54
|
+
target=start_subscription, args=(self.log_channel, self._event_queue, self.event_id, self.provider)
|
|
40
55
|
)
|
|
41
56
|
self._subscription_thread.daemon = True
|
|
42
57
|
self._subscription_thread.start()
|
|
@@ -64,51 +79,83 @@ class EventLogSubscriber:
|
|
|
64
79
|
def _parse_event_xml(event_xml):
|
|
65
80
|
root = Et.fromstring(event_xml)
|
|
66
81
|
data = {}
|
|
82
|
+
|
|
83
|
+
# Helper function to strip namespace
|
|
84
|
+
def strip_namespace(tag):
|
|
85
|
+
return tag.split('}')[-1] # Remove namespace
|
|
86
|
+
|
|
87
|
+
# Iterate over all elements
|
|
67
88
|
for elem in root.iter():
|
|
68
|
-
|
|
69
|
-
|
|
89
|
+
# Extract elements with text content
|
|
90
|
+
if elem.text and elem.text.strip():
|
|
91
|
+
tag = elem.tag.split('}')[-1] # Remove namespace
|
|
92
|
+
data[tag] = elem.text.strip()
|
|
93
|
+
|
|
94
|
+
# Extract elements with attributes
|
|
95
|
+
for attr_name, attr_value in elem.attrib.items():
|
|
96
|
+
tag = elem.tag.split('}')[-1] # Remove namespace
|
|
97
|
+
data[f"{tag}_{attr_name}"] = attr_value
|
|
98
|
+
|
|
99
|
+
# Handle Binary data
|
|
100
|
+
if elem.tag.split('}')[-1] == 'Binary':
|
|
101
|
+
try:
|
|
102
|
+
data['BinaryReadable'] = binascii.unhexlify(elem.text.strip())
|
|
103
|
+
except (TypeError, binascii.Error) as e:
|
|
104
|
+
print(f"Error decoding binary data: {e}")
|
|
105
|
+
data['BinaryReadable'] = elem.text.strip()
|
|
106
|
+
|
|
107
|
+
# Extract system-specific data
|
|
108
|
+
system_data = root.find(".//{http://schemas.microsoft.com/win/2004/08/events/event}System")
|
|
109
|
+
if system_data is not None:
|
|
110
|
+
for system_elem in system_data:
|
|
111
|
+
tag = strip_namespace(system_elem.tag)
|
|
112
|
+
if system_elem.attrib:
|
|
113
|
+
for attr_name, attr_value in system_elem.attrib.items():
|
|
114
|
+
data[f"{tag}_{attr_name}"] = attr_value
|
|
115
|
+
if system_elem.text and system_elem.text.strip():
|
|
116
|
+
data[tag] = system_elem.text.strip()
|
|
117
|
+
|
|
118
|
+
# Extract event-specific data
|
|
119
|
+
event_data = root.find(".//{http://schemas.microsoft.com/win/2004/08/events/event}EventData")
|
|
120
|
+
if event_data is not None:
|
|
121
|
+
for data_elem in event_data:
|
|
122
|
+
if strip_namespace(data_elem.tag) == 'Data' and 'Name' in data_elem.attrib:
|
|
123
|
+
data[data_elem.attrib['Name']] = data_elem.text.strip()
|
|
124
|
+
|
|
125
|
+
# Extract user data if available
|
|
126
|
+
user_data = root.find(".//{http://schemas.microsoft.com/win/2004/08/events/event}UserData")
|
|
127
|
+
if user_data is not None:
|
|
128
|
+
for user_elem in user_data:
|
|
129
|
+
tag = strip_namespace(user_elem.tag)
|
|
130
|
+
if user_elem.attrib:
|
|
131
|
+
for attr_name, attr_value in user_elem.attrib.items():
|
|
132
|
+
data[f"{tag}_{attr_name}"] = attr_value
|
|
133
|
+
if user_elem.text and user_elem.text.strip():
|
|
134
|
+
data[tag] = user_elem.text.strip()
|
|
135
|
+
|
|
136
|
+
# Extract rendering info (additional details like the message)
|
|
137
|
+
rendering_info = root.find(".//{http://schemas.microsoft.com/win/2004/08/events/event}RenderingInfo")
|
|
138
|
+
if rendering_info is not None:
|
|
139
|
+
for info_elem in rendering_info:
|
|
140
|
+
tag = strip_namespace(info_elem.tag)
|
|
141
|
+
if info_elem.text and info_elem.text.strip():
|
|
142
|
+
data[f"RenderingInfo_{tag}"] = info_elem.text.strip()
|
|
143
|
+
|
|
70
144
|
return data
|
|
71
145
|
|
|
72
146
|
|
|
73
147
|
def _handle_event(event, event_queue):
|
|
148
|
+
# Render event as XML
|
|
74
149
|
event_xml = win32evtlog.EvtRender(event, win32evtlog.EvtRenderEventXml)
|
|
150
|
+
data = None
|
|
75
151
|
try:
|
|
76
152
|
data = _parse_event_xml(event_xml)
|
|
77
153
|
except Et.ParseError as e:
|
|
78
154
|
print(f"Error parsing event XML: {e}")
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
event_dict: dict = {
|
|
82
|
-
'user_sid': data.get("SubjectUserSid", "Unknown"),
|
|
83
|
-
'user_name': data.get("SubjectUserName", "Unknown"),
|
|
84
|
-
'domain': data.get("SubjectDomainName", "Unknown"),
|
|
85
|
-
'pid_hex': data.get("NewProcessId", "0"),
|
|
86
|
-
'process_name': data.get("NewProcessName", "Unknown"),
|
|
87
|
-
'command_line': data.get("CommandLine", None),
|
|
88
|
-
'parent_pid_hex': data.get("ProcessId", "0"),
|
|
89
|
-
'parent_process_name': data.get("ParentProcessName", "Unknown")
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
try:
|
|
93
|
-
process_id = int(event_dict['pid_hex'], 16)
|
|
94
|
-
except ValueError:
|
|
95
|
-
process_id = "Unknown"
|
|
155
|
+
except Exception as e:
|
|
156
|
+
print(f"Error getting rendered message: {e}")
|
|
96
157
|
|
|
97
|
-
|
|
98
|
-
parent_pid = int(event_dict['parent_pid_hex'], 16)
|
|
99
|
-
except ValueError:
|
|
100
|
-
parent_pid = "Unknown"
|
|
101
|
-
|
|
102
|
-
event_dict['pid'] = process_id
|
|
103
|
-
event_dict['parent_pid'] = parent_pid
|
|
104
|
-
|
|
105
|
-
# if user_sid != "Unknown":
|
|
106
|
-
# try:
|
|
107
|
-
# user_name, domain, type = win32security.LookupAccountSid(None, user_sid)
|
|
108
|
-
# except Exception as e:
|
|
109
|
-
# print(f"Error looking up account SID: {e}")
|
|
110
|
-
|
|
111
|
-
event_queue.put(event_dict)
|
|
158
|
+
event_queue.put(data)
|
|
112
159
|
|
|
113
160
|
|
|
114
161
|
def _event_callback(action, context, event):
|
|
@@ -117,31 +164,47 @@ def _event_callback(action, context, event):
|
|
|
117
164
|
_handle_event(event, event_queue)
|
|
118
165
|
|
|
119
166
|
|
|
120
|
-
def start_subscription(
|
|
167
|
+
def start_subscription(
|
|
168
|
+
log_channel: str,
|
|
169
|
+
event_queue,
|
|
170
|
+
event_id: str = None,
|
|
171
|
+
provider: str = None
|
|
172
|
+
):
|
|
121
173
|
"""
|
|
122
174
|
Start listening for events in the specified log channel with the given event ID.
|
|
123
175
|
|
|
124
176
|
:param log_channel: The name of the event log channel to subscribe to. Examples:
|
|
125
177
|
Security, System, Application, etc.
|
|
178
|
+
:param event_queue: A queue to store the received events
|
|
126
179
|
:param event_id: The ID of the event to subscribe to.
|
|
127
180
|
Example: 4688 for process creation events in "Security" channel.
|
|
128
|
-
|
|
181
|
+
You can only subscribe by event ID or provider, not both.
|
|
182
|
+
:param provider: The name of the provider to subscribe to.
|
|
183
|
+
You can only subscribe by event ID or provider, not both.
|
|
129
184
|
"""
|
|
185
|
+
|
|
186
|
+
if event_id is None and provider is None:
|
|
187
|
+
raise ValueError("You must specify either an event ID or provider name to subscribe to.")
|
|
188
|
+
elif event_id and provider:
|
|
189
|
+
raise ValueError("You can only subscribe by event ID or provider, not both.")
|
|
190
|
+
|
|
130
191
|
# This selects the System node within each event.
|
|
131
192
|
# The System node contains metadata about the event, such as the event ID, provider name, timestamp, and more.
|
|
132
|
-
|
|
193
|
+
xpath_query = None
|
|
194
|
+
if provider:
|
|
195
|
+
xpath_query = f"*[System/Provider[@Name='{provider}']]"
|
|
196
|
+
elif event_id:
|
|
197
|
+
xpath_query = f"*[System/EventID={event_id}]"
|
|
133
198
|
|
|
134
199
|
subscription = win32evtlog.EvtSubscribe(
|
|
135
200
|
log_channel,
|
|
136
201
|
win32evtlog.EvtSubscribeToFutureEvents,
|
|
137
202
|
SignalEvent=None,
|
|
138
|
-
Query=
|
|
203
|
+
Query=xpath_query,
|
|
139
204
|
Callback=_event_callback,
|
|
140
205
|
Context={'event_queue': event_queue}
|
|
141
206
|
)
|
|
142
207
|
|
|
143
|
-
print("Listening for new process creation events...")
|
|
144
|
-
|
|
145
208
|
try:
|
|
146
209
|
while True:
|
|
147
210
|
time.sleep(1)
|
|
@@ -7,6 +7,8 @@ from .....print_api import print_api
|
|
|
7
7
|
|
|
8
8
|
AUDITING_REG_PATH: str = r"Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit"
|
|
9
9
|
PROCESS_CREATION_INCLUDE_CMDLINE_VALUE: str = "ProcessCreationIncludeCmdLine_Enabled"
|
|
10
|
+
LOG_CHANNEL: str = 'Security'
|
|
11
|
+
EVENT_ID: int = 4688
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class ProcessCreateSubscriber(subscribe.EventLogSubscriber):
|
|
@@ -14,9 +16,9 @@ class ProcessCreateSubscriber(subscribe.EventLogSubscriber):
|
|
|
14
16
|
Class for subscribing to Windows Event Log events related to process creation.
|
|
15
17
|
|
|
16
18
|
Usage:
|
|
17
|
-
from atomicshop.wrappers.pywin32w.win_event_log.subscribes import
|
|
19
|
+
from atomicshop.wrappers.pywin32w.win_event_log.subscribes import process_create
|
|
18
20
|
|
|
19
|
-
process_create_subscriber =
|
|
21
|
+
process_create_subscriber = process_create.ProcessCreateSubscriber()
|
|
20
22
|
process_create_subscriber.start()
|
|
21
23
|
|
|
22
24
|
while True:
|
|
@@ -24,7 +26,7 @@ class ProcessCreateSubscriber(subscribe.EventLogSubscriber):
|
|
|
24
26
|
print(event)
|
|
25
27
|
"""
|
|
26
28
|
def __init__(self):
|
|
27
|
-
super().__init__(
|
|
29
|
+
super().__init__(log_channel=LOG_CHANNEL, event_id=EVENT_ID)
|
|
28
30
|
|
|
29
31
|
def start(self):
|
|
30
32
|
"""Start the subscription process."""
|
|
@@ -45,7 +47,19 @@ class ProcessCreateSubscriber(subscribe.EventLogSubscriber):
|
|
|
45
47
|
If None, the function will block until an event is available.
|
|
46
48
|
:return: A dictionary containing the event data.
|
|
47
49
|
"""
|
|
48
|
-
|
|
50
|
+
|
|
51
|
+
data = super().emit(timeout=timeout)
|
|
52
|
+
|
|
53
|
+
data['NewProcessIdInt'] = int(data['NewProcessId'], 16)
|
|
54
|
+
data['ParentProcessIdInt'] = int(data['ProcessId'], 16)
|
|
55
|
+
|
|
56
|
+
# if user_sid != "Unknown":
|
|
57
|
+
# try:
|
|
58
|
+
# user_name, domain, type = win32security.LookupAccountSid(None, user_sid)
|
|
59
|
+
# except Exception as e:
|
|
60
|
+
# print(f"Error looking up account SID: {e}")
|
|
61
|
+
|
|
62
|
+
return data
|
|
49
63
|
|
|
50
64
|
|
|
51
65
|
def enable_audit_process_creation(print_kwargs: dict = None):
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
|
|
3
|
+
from .. import subscribe
|
|
4
|
+
from .....print_api import print_api
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
LOG_CHANNEL: str = 'Security'
|
|
8
|
+
EVENT_ID: int = 4689
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProcessTerminateSubscriber(subscribe.EventLogSubscriber):
|
|
12
|
+
"""
|
|
13
|
+
Class for subscribing to Windows Event Log events related to process termination.
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
from atomicshop.wrappers.pywin32w.win_event_log.subscribes import process_terminate
|
|
17
|
+
|
|
18
|
+
process_terminate_subscriber = process_terminate.ProcessTerminateSubscriber()
|
|
19
|
+
process_terminate_subscriber.start()
|
|
20
|
+
|
|
21
|
+
while True:
|
|
22
|
+
event = process_terminate_subscriber.emit()
|
|
23
|
+
print(event)
|
|
24
|
+
"""
|
|
25
|
+
def __init__(self):
|
|
26
|
+
super().__init__(log_channel=LOG_CHANNEL, event_id=EVENT_ID)
|
|
27
|
+
|
|
28
|
+
def start(self):
|
|
29
|
+
"""Start the subscription process."""
|
|
30
|
+
enable_audit_process_termination()
|
|
31
|
+
|
|
32
|
+
super().start()
|
|
33
|
+
|
|
34
|
+
def stop(self):
|
|
35
|
+
"""Stop the subscription process."""
|
|
36
|
+
super().stop()
|
|
37
|
+
|
|
38
|
+
def emit(self, timeout: float = None) -> dict:
|
|
39
|
+
"""
|
|
40
|
+
Get the next event from the event queue.
|
|
41
|
+
|
|
42
|
+
:param timeout: The maximum time (in seconds) to wait for an event.
|
|
43
|
+
If None, the function will block until an event is available.
|
|
44
|
+
:return: A dictionary containing the event data.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
data = super().emit(timeout=timeout)
|
|
48
|
+
|
|
49
|
+
data['ProcessIdInt'] = int(data['ProcessId'], 16)
|
|
50
|
+
|
|
51
|
+
return data
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def enable_audit_process_termination(print_kwargs: dict = None):
|
|
55
|
+
"""
|
|
56
|
+
Enable the 'Audit Process Termination' policy.
|
|
57
|
+
|
|
58
|
+
:param print_kwargs: Optional keyword arguments for the print function.
|
|
59
|
+
"""
|
|
60
|
+
if is_audit_process_termination_enabled():
|
|
61
|
+
print_api("Audit Process Termination is already enabled.", color='yellow', **(print_kwargs or {}))
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
audit_policy_command = [
|
|
65
|
+
"auditpol", "/set", "/subcategory:Process Termination", "/success:enable", "/failure:enable"
|
|
66
|
+
]
|
|
67
|
+
try:
|
|
68
|
+
subprocess.run(audit_policy_command, check=True)
|
|
69
|
+
print_api("Successfully enabled 'Audit Process Termination'.", color='green', **(print_kwargs or {}))
|
|
70
|
+
except subprocess.CalledProcessError as e:
|
|
71
|
+
print_api(f"Failed to enable 'Audit Process Termination': {e}", error_type=True, color='red', **(print_kwargs or {}))
|
|
72
|
+
raise e
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def is_audit_process_termination_enabled(print_kwargs: dict = None) -> bool:
|
|
76
|
+
"""
|
|
77
|
+
Check if the 'Audit Process Termination' policy is enabled.
|
|
78
|
+
|
|
79
|
+
:param print_kwargs: Optional keyword arguments for the print function.
|
|
80
|
+
"""
|
|
81
|
+
# Command to check the "Audit Process Creation" policy
|
|
82
|
+
audit_policy_check_command = [
|
|
83
|
+
"auditpol", "/get", "/subcategory:Process Termination"
|
|
84
|
+
]
|
|
85
|
+
try:
|
|
86
|
+
result = subprocess.run(audit_policy_check_command, check=True, capture_output=True, text=True)
|
|
87
|
+
output = result.stdout
|
|
88
|
+
# print_api(output) # Print the output for inspection
|
|
89
|
+
|
|
90
|
+
if "Process Termination" in output and "Success and Failure" in output:
|
|
91
|
+
# print_api(
|
|
92
|
+
# "'Audit Process Termination' is enabled for both success and failure.",
|
|
93
|
+
# color='green', **(print_kwargs or {}))
|
|
94
|
+
return True
|
|
95
|
+
else:
|
|
96
|
+
# print_api(output, **(print_kwargs or {}))
|
|
97
|
+
# print_api(
|
|
98
|
+
# "'Audit Process Termination' is not fully enabled. Check the output above for details.",
|
|
99
|
+
# color='yellow', **(print_kwargs or {}))
|
|
100
|
+
return False
|
|
101
|
+
except subprocess.CalledProcessError as e:
|
|
102
|
+
print_api(f"Failed to check 'Audit Process Termination': {e}", color='red', error_type=True, **(print_kwargs or {}))
|
|
103
|
+
return False
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import winreg
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from .. import subscribe
|
|
5
|
+
from .....print_api import print_api
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
SCHANNEL_LOGGING_REG_PATH: str = r'SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL'
|
|
9
|
+
SCHANNEL_EVENT_LOGGING_KEY: str = 'EventLogging'
|
|
10
|
+
LOG_CHANNEL: str = 'System'
|
|
11
|
+
PROVIDER: str = 'Schannel'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SchannelLoggingSubscriber(subscribe.EventLogSubscriber):
|
|
15
|
+
"""
|
|
16
|
+
Class for subscribing to Windows Event Log events related to process creation.
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
from atomicshop.wrappers.pywin32w.win_event_log.subscribes import schannel_logging
|
|
20
|
+
|
|
21
|
+
process_create_subscriber = schannel_logging.SchannelLoggingSubscriber()
|
|
22
|
+
process_create_subscriber.start()
|
|
23
|
+
|
|
24
|
+
while True:
|
|
25
|
+
event = process_create_subscriber.emit()
|
|
26
|
+
print(event)
|
|
27
|
+
"""
|
|
28
|
+
def __init__(self):
|
|
29
|
+
super().__init__(log_channel=LOG_CHANNEL, provider=PROVIDER)
|
|
30
|
+
|
|
31
|
+
def start(self):
|
|
32
|
+
"""Start the subscription process."""
|
|
33
|
+
enable_schannel_logging()
|
|
34
|
+
|
|
35
|
+
super().start()
|
|
36
|
+
|
|
37
|
+
def stop(self):
|
|
38
|
+
"""Stop the subscription process."""
|
|
39
|
+
super().stop()
|
|
40
|
+
|
|
41
|
+
def emit(self, timeout: float = None) -> dict:
|
|
42
|
+
"""
|
|
43
|
+
Get the next event from the event queue.
|
|
44
|
+
|
|
45
|
+
:param timeout: The maximum time (in seconds) to wait for an event.
|
|
46
|
+
If None, the function will block until an event is available.
|
|
47
|
+
:return: A dictionary containing the event data.
|
|
48
|
+
"""
|
|
49
|
+
return super().emit(timeout=timeout)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def enable_schannel_logging(logging_value: int = 1, print_kwargs: dict = None):
|
|
53
|
+
"""
|
|
54
|
+
Value Description
|
|
55
|
+
0x0000 Do not log
|
|
56
|
+
0x0001 Log error messages
|
|
57
|
+
0x0002 Log warnings
|
|
58
|
+
0x0003 Log warnings and error messages
|
|
59
|
+
0x0004 Log informational and success events
|
|
60
|
+
0x0005 Log informational, success events and error messages
|
|
61
|
+
0x0006 Log informational, success events and warnings
|
|
62
|
+
0x0007 Log informational, success events, warnings, and error messages (all log levels)
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
if is_schannel_logging_enabled(logging_value):
|
|
66
|
+
print_api(
|
|
67
|
+
"Schannel event logging is already enabled.", color='yellow',
|
|
68
|
+
**(print_kwargs or {}))
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, SCHANNEL_LOGGING_REG_PATH, 0, winreg.KEY_ALL_ACCESS) as key:
|
|
73
|
+
winreg.SetValueEx(key, SCHANNEL_EVENT_LOGGING_KEY, 0, winreg.REG_DWORD, logging_value)
|
|
74
|
+
|
|
75
|
+
print_api(
|
|
76
|
+
"Successfully enabled Schannel logging.",
|
|
77
|
+
color='green', **(print_kwargs or {}))
|
|
78
|
+
print_api(
|
|
79
|
+
"Please restart the computer for the changes to take effect.",
|
|
80
|
+
color='yellow', **(print_kwargs or {}))
|
|
81
|
+
sys.exit()
|
|
82
|
+
except WindowsError as e:
|
|
83
|
+
print_api(
|
|
84
|
+
f"Failed to enable Schannel event logging: {e}", error_type=True,
|
|
85
|
+
color='red', **(print_kwargs or {}))
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def is_schannel_logging_enabled(logging_value: int) -> bool:
|
|
89
|
+
try:
|
|
90
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, SCHANNEL_LOGGING_REG_PATH, 0, winreg.KEY_READ) as key:
|
|
91
|
+
value, regtype = winreg.QueryValueEx(key, SCHANNEL_EVENT_LOGGING_KEY)
|
|
92
|
+
return value == logging_value
|
|
93
|
+
except FileNotFoundError:
|
|
94
|
+
return False
|
|
95
|
+
except WindowsError as e:
|
|
96
|
+
print(f"Failed to read the Schannel event logging setting: {e}")
|
|
97
|
+
return False
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=oGFh-WMJw07HDbokeQe5ZNDZSUzB3jHxbH8krJL842c,123
|
|
2
2
|
atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
|
|
3
3
|
atomicshop/_create_pdf_demo.py,sha256=Yi-PGZuMg0RKvQmLqVeLIZYadqEZwUm-4A9JxBl_vYA,3713
|
|
4
4
|
atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
|
|
@@ -16,6 +16,8 @@ atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
|
|
|
16
16
|
atomicshop/file_types.py,sha256=-0jzQMRlmU1AP9DARjk-HJm1tVE22E6ngP2mRblyEjY,763
|
|
17
17
|
atomicshop/filesystem.py,sha256=202ue2LkjI1KdaxvB_RHV-2eIczy2-caZGLO4PSePik,53887
|
|
18
18
|
atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
|
|
19
|
+
atomicshop/get_process_list.py,sha256=hi1NOG-i8S6EcyQ6LTfP4pdxqRfjEijz9SZ5nEbcM9Q,6076
|
|
20
|
+
atomicshop/get_process_name_cmd_dll.py,sha256=CtaSp3mgxxJKCCVW8BLx6BJNx4giCklU_T7USiCEwfc,5162
|
|
19
21
|
atomicshop/hashing.py,sha256=Le8qGFyt3_wX-zGTeQShz7L2HL_b6nVv9PnawjglyHo,3474
|
|
20
22
|
atomicshop/http_parse.py,sha256=nrf2rZcprLqtW8HVrV7TCZ1iTBcWRRy-mXIlAOzcaJs,9703
|
|
21
23
|
atomicshop/inspect_wrapper.py,sha256=sGRVQhrJovNygHTydqJj0hxES-aB2Eg9KbIk3G31apw,11429
|
|
@@ -25,9 +27,7 @@ atomicshop/on_exit.py,sha256=Wf1iy2e0b0Zu7oRxrct3VkLdQ_x9B32-z_JerKTt9Z0,5493
|
|
|
25
27
|
atomicshop/pbtkmultifile_argparse.py,sha256=aEk8nhvoQVu-xyfZosK3ma17CwIgOjzO1erXXdjwtS4,4574
|
|
26
28
|
atomicshop/permissions.py,sha256=P6tiUKV-Gw-c3ePEVsst9bqWaHJbB4ZlJB4xbDYVpEs,4436
|
|
27
29
|
atomicshop/print_api.py,sha256=DhbCQd0MWZZ5GYEk4oTu1opRFC-b31g1VWZgTGewG2Y,11568
|
|
28
|
-
atomicshop/process.py,sha256=
|
|
29
|
-
atomicshop/process_name_cmd.py,sha256=CtaSp3mgxxJKCCVW8BLx6BJNx4giCklU_T7USiCEwfc,5162
|
|
30
|
-
atomicshop/process_poller.py,sha256=B91ugFIo84IMFXbWJeW8P7TsIkzYxMXBVWuvYqRXS-c,16107
|
|
30
|
+
atomicshop/process.py,sha256=U2gyRl0bw2138y-rOMABMVptRvAL81ZfX1JyfxJI_Oo,15973
|
|
31
31
|
atomicshop/python_file_patcher.py,sha256=kd3rBWvTcosLEk-7TycNdfKW9fZbe161iVwmH4niUo0,5515
|
|
32
32
|
atomicshop/python_functions.py,sha256=zJg4ogUwECxrDD7xdDN5JikIUctITM5lsyabr_ZNsRw,4435
|
|
33
33
|
atomicshop/question_answer_engine.py,sha256=DuOn7QEgKKfqZu2cR8mVeFIfFgayfBHiW-jY2VPq_Fo,841
|
|
@@ -106,10 +106,10 @@ atomicshop/etws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
106
106
|
atomicshop/etws/const.py,sha256=v3x_IdCYeSKbCGywiZFOZln80ldpwKW5nuMDuUe51Jg,1257
|
|
107
107
|
atomicshop/etws/providers.py,sha256=fVmWi-uGdtnsQTDpu_ty6dzx0GMhGokiST73LNBEJ38,129
|
|
108
108
|
atomicshop/etws/sessions.py,sha256=k3miewU278xn829cqDbsuH_bmZHPQE9-Zn-hINbxUSE,1330
|
|
109
|
-
atomicshop/etws/trace.py,sha256=
|
|
109
|
+
atomicshop/etws/trace.py,sha256=KddD6_pXWhB1nr_ZsPTX1W3zayAdy5v0UxDsTcrme_w,7286
|
|
110
110
|
atomicshop/etws/traces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
111
|
-
atomicshop/etws/traces/trace_dns.py,sha256
|
|
112
|
-
atomicshop/etws/traces/trace_sysmon_process_creation.py,sha256=
|
|
111
|
+
atomicshop/etws/traces/trace_dns.py,sha256=rWQ8bv8eMHBRRkA8oxO9caYqj0h4Emw4aZXmoI3Q6fg,6292
|
|
112
|
+
atomicshop/etws/traces/trace_sysmon_process_creation.py,sha256=OM-bkK38uYMwWLZKNOTDa0Xdk3sO6sqsxoMUIiPvm5g,4656
|
|
113
113
|
atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
114
114
|
atomicshop/file_io/csvs.py,sha256=y8cJtnlN-NNxNupzJgSeGq9aQ4wNxYLFPX9vNNlUiIc,5830
|
|
115
115
|
atomicshop/file_io/docxs.py,sha256=6tcYFGp0vRsHR47VwcRqwhdt2DQOwrAUYhrwN996n9U,5117
|
|
@@ -139,13 +139,22 @@ atomicshop/mitm/engines/__reference_general/parser___reference_general.py,sha256
|
|
|
139
139
|
atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha256=KENDVf9OwXD9gwSh4B1XxACCe7iHYjrvnW1t6F64wdE,695
|
|
140
140
|
atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=1AM49UaFTKA0AHw-k3SV3uH3QbG-o6ux0c-GoWkKNU0,6993
|
|
141
141
|
atomicshop/monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
142
|
-
atomicshop/monitor/change_monitor.py,sha256=
|
|
142
|
+
atomicshop/monitor/change_monitor.py,sha256=K5NlVp99XIDDPnQQMdru4BDmua_DtcDIhVAzkTOvD5s,7673
|
|
143
143
|
atomicshop/monitor/checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
144
|
-
atomicshop/monitor/checks/dns.py,sha256=
|
|
144
|
+
atomicshop/monitor/checks/dns.py,sha256=GHBQ2GEPaU3hAmK6l2vM2PKTcBNzDDF9ThZixqnl9Qk,7108
|
|
145
145
|
atomicshop/monitor/checks/file.py,sha256=2tIDSlX2KZNc_9i9ji1tcOqupbFTIOj7cKXLyBEDWMk,3263
|
|
146
146
|
atomicshop/monitor/checks/network.py,sha256=CGZWl4WlQrxayZeVF9JspJXwYA-zWx8ECWTVGSlXc98,3825
|
|
147
147
|
atomicshop/monitor/checks/process_running.py,sha256=x66wd6-l466r8sbRQaIli0yswyGt1dH2DVXkGDL6O0Q,1891
|
|
148
148
|
atomicshop/monitor/checks/url.py,sha256=1PvKt_d7wFg7rDMFpUejAQhj0mqWsmlmrNfjNAV2G4g,4123
|
|
149
|
+
atomicshop/process_poller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
150
|
+
atomicshop/process_poller/process_pool.py,sha256=1CaG6Cov-Pt_kZohfFeQFT42YBnEwNBA6ge55dxok_8,9600
|
|
151
|
+
atomicshop/process_poller/simple_process_pool.py,sha256=hJkrn-efetLjyC8CevAFcsiKwBBKS8onYbf2ygq2J18,4540
|
|
152
|
+
atomicshop/process_poller/tracer_base.py,sha256=IOiHcnmF-MccOSCErixN5mve9RifZ9cPnGVHCIRchrs,1091
|
|
153
|
+
atomicshop/process_poller/pollers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
154
|
+
atomicshop/process_poller/pollers/psutil_pywin32wmi_dll.py,sha256=XRRfOIy62iOYU8IKRcyECWiL0rqQ35DeYbPsv_SHDVM,4510
|
|
155
|
+
atomicshop/process_poller/tracers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
156
|
+
atomicshop/process_poller/tracers/event_log.py,sha256=Ob5v18VPZ__PN8TP6aJJjQZcDMwfGA2pIKwKjrl5j3k,1417
|
|
157
|
+
atomicshop/process_poller/tracers/sysmon_etw.py,sha256=zn5YGX0Uro_Om7Gp1O4r0nlP1cR7BX1nYQmELPLZc9I,2500
|
|
149
158
|
atomicshop/ssh_scripts/process_from_ipv4.py,sha256=uDBKZ2Ds20614JW1xMLr4IPB-z1LzIwy6QH5-SJ4j0s,1681
|
|
150
159
|
atomicshop/ssh_scripts/process_from_port.py,sha256=uDTkVh4zc3HOTTGv1Et3IxM3PonDJCPuFRL6rnZDQZ4,1389
|
|
151
160
|
atomicshop/startup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -251,9 +260,11 @@ atomicshop/wrappers/pywin32w/console.py,sha256=LstHajPLgXp9qQxFNR44QfH10nOnNp3bC
|
|
|
251
260
|
atomicshop/wrappers/pywin32w/winshell.py,sha256=i2bKiMldPU7_azsD5xGQDdMwjaM7suKJd3k0Szmcs6c,723
|
|
252
261
|
atomicshop/wrappers/pywin32w/wmi_win32process.py,sha256=qMzXtJ5hBZ5ydAyqpDbSx0nO2RJQL95HdmV5SzNKMhk,6826
|
|
253
262
|
atomicshop/wrappers/pywin32w/win_event_log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
254
|
-
atomicshop/wrappers/pywin32w/win_event_log/subscribe.py,sha256=
|
|
263
|
+
atomicshop/wrappers/pywin32w/win_event_log/subscribe.py,sha256=FYo2X0Xm3lb3GIdIt_8usoj7JPSDWj0iwsIJ4OwZLQM,8156
|
|
255
264
|
atomicshop/wrappers/pywin32w/win_event_log/subscribes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
256
|
-
atomicshop/wrappers/pywin32w/win_event_log/subscribes/
|
|
265
|
+
atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py,sha256=1PrPiDiuiVfzfzN5BUuxMfUoCgGW7RGgH6HVrjpTnQc,6064
|
|
266
|
+
atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py,sha256=0k09fiAwKDJO404bjxUWSSSLOiNANl-VTJDD_YLq-I8,3763
|
|
267
|
+
atomicshop/wrappers/pywin32w/win_event_log/subscribes/schannel_logging.py,sha256=8nxIcNcbeEuvoBwhujgh7-oIpL9A6J-gg1NM8hOGAVA,3442
|
|
257
268
|
atomicshop/wrappers/socketw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
258
269
|
atomicshop/wrappers/socketw/accepter.py,sha256=HQC1EyZmyUtVEfFbaBkHCE-VZp6RWyd9mEqAkgsE1fk,1749
|
|
259
270
|
atomicshop/wrappers/socketw/base.py,sha256=1vvg8EhRGvnxdrRAm1VJSLCXkm2SZDHRjdpTuhkH3Mg,1844
|
|
@@ -270,8 +281,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
|
|
|
270
281
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
|
|
271
282
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
|
|
272
283
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
|
|
273
|
-
atomicshop-2.14.
|
|
274
|
-
atomicshop-2.14.
|
|
275
|
-
atomicshop-2.14.
|
|
276
|
-
atomicshop-2.14.
|
|
277
|
-
atomicshop-2.14.
|
|
284
|
+
atomicshop-2.14.3.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
285
|
+
atomicshop-2.14.3.dist-info/METADATA,sha256=JhF66mFvmwPdaPxY9XiSY3ZjfBDikdaCzCF2PRNO0Ac,10478
|
|
286
|
+
atomicshop-2.14.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
287
|
+
atomicshop-2.14.3.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
288
|
+
atomicshop-2.14.3.dist-info/RECORD,,
|