atomicshop 2.16.43__py3-none-any.whl → 2.16.44__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/file_io/docxs.py +1 -1
- atomicshop/websocket_parse.py +244 -5
- atomicshop/wrappers/factw/install/install_after_restart.py +78 -5
- {atomicshop-2.16.43.dist-info → atomicshop-2.16.44.dist-info}/METADATA +1 -1
- {atomicshop-2.16.43.dist-info → atomicshop-2.16.44.dist-info}/RECORD +9 -9
- {atomicshop-2.16.43.dist-info → atomicshop-2.16.44.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.16.43.dist-info → atomicshop-2.16.44.dist-info}/WHEEL +0 -0
- {atomicshop-2.16.43.dist-info → atomicshop-2.16.44.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/file_io/docxs.py
CHANGED
|
@@ -75,7 +75,7 @@ def search_for_hyperlink_in_files(directory_path: str, hyperlink: str, relative_
|
|
|
75
75
|
|
|
76
76
|
# Get all the docx files in the specified directory.
|
|
77
77
|
files = filesystem.get_paths_from_directory(
|
|
78
|
-
directory_path, get_file=True, file_name_check_pattern="
|
|
78
|
+
directory_path, get_file=True, file_name_check_pattern="*.docx",
|
|
79
79
|
add_relative_directory=True, relative_file_name_as_directory=True)
|
|
80
80
|
|
|
81
81
|
found_in_files: list = list()
|
atomicshop/websocket_parse.py
CHANGED
|
@@ -1,18 +1,256 @@
|
|
|
1
|
-
from typing import Union
|
|
1
|
+
from typing import Union, Generator
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
4
|
from websockets.server import ServerProtocol
|
|
5
5
|
from websockets.client import ClientProtocol
|
|
6
|
-
from websockets.extensions.permessage_deflate import ServerPerMessageDeflateFactory, ClientPerMessageDeflateFactory
|
|
6
|
+
from websockets.extensions.permessage_deflate import PerMessageDeflate, ServerPerMessageDeflateFactory, ClientPerMessageDeflateFactory
|
|
7
7
|
from websockets.http11 import Request, Response
|
|
8
|
-
from websockets.frames import Frame, Opcode
|
|
8
|
+
from websockets.frames import Frame, Opcode
|
|
9
9
|
from websockets.uri import parse_uri
|
|
10
10
|
from websockets.exceptions import InvalidHeaderValue
|
|
11
11
|
from websockets.protocol import OPEN
|
|
12
|
+
from websockets.streams import StreamReader
|
|
13
|
+
from websockets.exceptions import ProtocolError, PayloadTooBig
|
|
12
14
|
|
|
13
15
|
|
|
14
|
-
class
|
|
16
|
+
class WebsocketParseWrongOpcode(Exception):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def create_byte_http_response(
|
|
21
|
+
byte_http_request: Union[bytes, bytearray],
|
|
22
|
+
enable_logging: bool = False
|
|
23
|
+
) -> bytes:
|
|
24
|
+
"""
|
|
25
|
+
Create a byte HTTP response from a byte HTTP request.
|
|
26
|
+
|
|
27
|
+
Parameters:
|
|
28
|
+
- byte_http_request (bytes, bytearray): The byte HTTP request.
|
|
29
|
+
- enable_logging (bool): Whether to enable logging.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
- bytes: The byte HTTP response.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
# Set up extensions
|
|
36
|
+
permessage_deflate_factory = ServerPerMessageDeflateFactory()
|
|
37
|
+
|
|
38
|
+
# Create the protocol instance
|
|
39
|
+
protocol = ServerProtocol(
|
|
40
|
+
extensions=[permessage_deflate_factory],
|
|
41
|
+
)
|
|
42
|
+
# At this state the protocol.state is State.CONNECTING
|
|
43
|
+
|
|
44
|
+
if enable_logging:
|
|
45
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
46
|
+
protocol.logger.setLevel(logging.DEBUG)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
protocol.receive_data(byte_http_request)
|
|
50
|
+
events = protocol.events_received()
|
|
51
|
+
event = events[0]
|
|
52
|
+
if isinstance(event, Request):
|
|
53
|
+
# Accept the handshake.
|
|
54
|
+
# After the response is sent, it means the handshake was successful, the protocol.state is State.OPEN
|
|
55
|
+
# Only after this state we can parse frames.
|
|
56
|
+
response = protocol.accept(event)
|
|
57
|
+
return response.serialize()
|
|
58
|
+
else:
|
|
59
|
+
raise ValueError("The event is not a Request object.")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def parse_frame_bytes(data_bytes: bytes):
|
|
63
|
+
# Define the read_exact function
|
|
64
|
+
def read_exact(n: int) -> Generator[None, None, bytes]:
|
|
65
|
+
return reader.read_exact(n)
|
|
66
|
+
|
|
67
|
+
# Helper function to run generator-based coroutines
|
|
68
|
+
def run_coroutine(coroutine):
|
|
69
|
+
try:
|
|
70
|
+
while True:
|
|
71
|
+
next(coroutine)
|
|
72
|
+
except StopIteration as e:
|
|
73
|
+
return e.value
|
|
74
|
+
except Exception as e:
|
|
75
|
+
raise e # Re-raise exceptions to be handled by the caller
|
|
76
|
+
|
|
77
|
+
# Function to parse frames
|
|
78
|
+
def parse_frame(mask: bool):
|
|
79
|
+
try:
|
|
80
|
+
# Use Frame.parse to parse the frame
|
|
81
|
+
frame_parser = Frame.parse(
|
|
82
|
+
read_exact,
|
|
83
|
+
mask=mask, # Client frames are masked
|
|
84
|
+
max_size=None,
|
|
85
|
+
extensions=[permessage_deflate], # Include the extension unconditionally
|
|
86
|
+
)
|
|
87
|
+
current_frame = run_coroutine(frame_parser)
|
|
88
|
+
except EOFError as e:
|
|
89
|
+
# Not enough data to parse a complete frame
|
|
90
|
+
raise e
|
|
91
|
+
except (ProtocolError, PayloadTooBig) as e:
|
|
92
|
+
print("Error parsing frame:", e)
|
|
93
|
+
raise e
|
|
94
|
+
except Exception as e:
|
|
95
|
+
print("Error parsing frame:", e)
|
|
96
|
+
raise e
|
|
97
|
+
return current_frame
|
|
98
|
+
|
|
99
|
+
def process_frame(current_frame):
|
|
100
|
+
if current_frame.opcode == Opcode.TEXT:
|
|
101
|
+
message = current_frame.data.decode('utf-8', errors='replace')
|
|
102
|
+
return message
|
|
103
|
+
elif current_frame.opcode == Opcode.BINARY:
|
|
104
|
+
return current_frame.data
|
|
105
|
+
elif current_frame.opcode == Opcode.CLOSE:
|
|
106
|
+
print("Received close frame")
|
|
107
|
+
elif current_frame.opcode == Opcode.PING:
|
|
108
|
+
print("Received ping")
|
|
109
|
+
elif current_frame.opcode == Opcode.PONG:
|
|
110
|
+
print("Received pong")
|
|
111
|
+
else:
|
|
112
|
+
raise WebsocketParseWrongOpcode("Received unknown frame with opcode:", current_frame.opcode)
|
|
113
|
+
|
|
114
|
+
# Create the StreamReader instance
|
|
115
|
+
reader = StreamReader()
|
|
116
|
+
|
|
117
|
+
# Instantiate the permessage-deflate extension
|
|
118
|
+
permessage_deflate = PerMessageDeflate(
|
|
119
|
+
remote_no_context_takeover=False,
|
|
120
|
+
local_no_context_takeover=False,
|
|
121
|
+
remote_max_window_bits=15,
|
|
122
|
+
local_max_window_bits=15,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
masked = is_frame_masked(data_bytes)
|
|
126
|
+
|
|
127
|
+
# Feed the data into the reader
|
|
128
|
+
reader.feed_data(data_bytes)
|
|
129
|
+
|
|
130
|
+
# Parse and process frames
|
|
131
|
+
frame = parse_frame(masked)
|
|
132
|
+
result = process_frame(frame)
|
|
133
|
+
return result
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def create_websocket_frame(
|
|
137
|
+
data: Union[str, bytes, bytearray],
|
|
138
|
+
deflate: bool = False,
|
|
139
|
+
mask: bool = False,
|
|
140
|
+
opcode: int = None
|
|
141
|
+
) -> bytes:
|
|
142
|
+
"""
|
|
143
|
+
Create a WebSocket frame with the given data, optionally applying
|
|
144
|
+
permessage-deflate compression and masking.
|
|
145
|
+
|
|
146
|
+
Parameters:
|
|
147
|
+
- data (str, bytes, bytearray): The payload data.
|
|
148
|
+
If str, it will be encoded to bytes using UTF-8.
|
|
149
|
+
- deflate (bool): Whether to apply permessage-deflate compression.
|
|
150
|
+
- mask (bool): Whether to apply masking to the frame.
|
|
151
|
+
- opcode (int): The opcode of the frame. If not provided, it will be
|
|
152
|
+
determined based on the type of data.
|
|
153
|
+
Example:
|
|
154
|
+
from websockets.frames import Opcode
|
|
155
|
+
Opcode.TEXT, Opcode.BINARY, Opcode.CLOSE, Opcode.PING, Opcode.PONG.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
- bytes: The serialized WebSocket frame ready to be sent.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
# Determine the opcode if not provided
|
|
162
|
+
if opcode is None:
|
|
163
|
+
if isinstance(data, str):
|
|
164
|
+
opcode = Opcode.TEXT
|
|
165
|
+
elif isinstance(data, (bytes, bytearray)):
|
|
166
|
+
opcode = Opcode.BINARY
|
|
167
|
+
else:
|
|
168
|
+
raise TypeError("Data must be of type str, bytes, or bytearray.")
|
|
169
|
+
else:
|
|
170
|
+
if not isinstance(opcode, int):
|
|
171
|
+
raise TypeError("Opcode must be an integer.")
|
|
172
|
+
if not isinstance(data, (str, bytes, bytearray)):
|
|
173
|
+
raise TypeError("Data must be of type str, bytes, or bytearray.")
|
|
174
|
+
|
|
175
|
+
# Encode string data if necessary
|
|
176
|
+
if isinstance(data, str):
|
|
177
|
+
payload = data.encode('utf-8')
|
|
178
|
+
else:
|
|
179
|
+
payload = bytes(data)
|
|
180
|
+
|
|
181
|
+
# Create the Frame instance
|
|
182
|
+
frame = Frame(opcode=opcode, data=payload)
|
|
183
|
+
|
|
184
|
+
# Set up extensions if deflate is True
|
|
185
|
+
extensions = []
|
|
186
|
+
if deflate:
|
|
187
|
+
permessage_deflate = PerMessageDeflate(
|
|
188
|
+
remote_no_context_takeover=False,
|
|
189
|
+
local_no_context_takeover=False,
|
|
190
|
+
remote_max_window_bits=15,
|
|
191
|
+
local_max_window_bits=15,
|
|
192
|
+
)
|
|
193
|
+
extensions.append(permessage_deflate)
|
|
194
|
+
|
|
195
|
+
# Serialize the frame with the specified options
|
|
196
|
+
try:
|
|
197
|
+
frame_bytes = frame.serialize(
|
|
198
|
+
mask=mask,
|
|
199
|
+
extensions=extensions,
|
|
200
|
+
)
|
|
201
|
+
except Exception as e:
|
|
202
|
+
raise RuntimeError(f"Error serializing frame: {e}")
|
|
203
|
+
|
|
204
|
+
return frame_bytes
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def is_frame_masked(frame_bytes):
|
|
208
|
+
"""
|
|
209
|
+
Determine whether a WebSocket frame is masked.
|
|
210
|
+
|
|
211
|
+
Parameters:
|
|
212
|
+
- frame_bytes (bytes): The raw bytes of the WebSocket frame.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
- bool: True if the frame is masked, False otherwise.
|
|
216
|
+
"""
|
|
217
|
+
if len(frame_bytes) < 2:
|
|
218
|
+
raise ValueError("Frame is too short to determine masking.")
|
|
219
|
+
|
|
220
|
+
# The second byte of the frame header contains the MASK bit
|
|
221
|
+
second_byte = frame_bytes[1]
|
|
222
|
+
|
|
223
|
+
# The MASK bit is the most significant bit (MSB) of the second byte
|
|
224
|
+
mask_bit = (second_byte & 0x80) != 0 # 0x80 is 1000 0000 in binary
|
|
225
|
+
|
|
226
|
+
return mask_bit
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def is_frame_deflated(frame_bytes):
|
|
230
|
+
"""
|
|
231
|
+
Determine whether a WebSocket frame is deflated (compressed).
|
|
232
|
+
|
|
233
|
+
Parameters:
|
|
234
|
+
- frame_bytes (bytes): The raw bytes of the WebSocket frame.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
- bool: True if the frame is deflated (compressed), False otherwise.
|
|
238
|
+
"""
|
|
239
|
+
if len(frame_bytes) < 1:
|
|
240
|
+
raise ValueError("Frame is too short to determine deflation status.")
|
|
241
|
+
|
|
242
|
+
# The first byte of the frame header contains the RSV1 bit
|
|
243
|
+
first_byte = frame_bytes[0]
|
|
244
|
+
|
|
245
|
+
# The RSV1 bit is the second most significant bit (bit 6)
|
|
246
|
+
rsv1 = (first_byte & 0x40) != 0 # 0x40 is 0100 0000 in binary
|
|
247
|
+
|
|
248
|
+
return rsv1
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class _WebsocketRequestParse:
|
|
15
252
|
"""
|
|
253
|
+
THIS IS ONLY FOR THE REFERENCE IT IS NOT CURRENTLY USED OR SHOULD BE USED.
|
|
16
254
|
Parse the websocket request and return the data
|
|
17
255
|
"""
|
|
18
256
|
def __init__(
|
|
@@ -85,8 +323,9 @@ class WebsocketRequestParse:
|
|
|
85
323
|
"""
|
|
86
324
|
|
|
87
325
|
|
|
88
|
-
class
|
|
326
|
+
class _WebsocketResponseParse:
|
|
89
327
|
"""
|
|
328
|
+
THIS IS ONLY FOR THE REFERENCE IT IS NOT CURRENTLY USED OR SHOULD BE USED.
|
|
90
329
|
Parse the websocket response and return the data
|
|
91
330
|
"""
|
|
92
331
|
def __init__(
|
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
from typing import Union, Literal
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
|
-
from .... import process,
|
|
4
|
+
from .... import process, print_api
|
|
5
5
|
from .. import config_install
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
PLUGIN_LIST: list = [
|
|
9
|
+
'qemu_exec',
|
|
10
|
+
'binwalk',
|
|
11
|
+
'users_and_passwords',
|
|
12
|
+
'kernel_config',
|
|
13
|
+
'cve_lookup',
|
|
14
|
+
'crypto_hints',
|
|
15
|
+
'input_vectors',
|
|
16
|
+
'cwe_checker',
|
|
17
|
+
'linter',
|
|
18
|
+
'ip_and_uri_finder',
|
|
19
|
+
'device_tree',
|
|
20
|
+
'file_system_metadata',
|
|
21
|
+
'ipc',
|
|
22
|
+
'software_components',
|
|
23
|
+
'architecture_detection',
|
|
24
|
+
'known_vulnerabilities'
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
INSTALLING_STRINGS: list = ['Installing', 'plugin']
|
|
29
|
+
FINISHED_INSTALLING_STRINGS: list = ['Finished installing', 'plugin']
|
|
30
|
+
LOG_FINISHED_STRING: str = 'installation complete'
|
|
31
|
+
|
|
32
|
+
|
|
8
33
|
def install_after_restart(
|
|
9
34
|
installation_directory: str,
|
|
10
35
|
install_type: Union[
|
|
@@ -12,8 +37,12 @@ def install_after_restart(
|
|
|
12
37
|
Literal['backend', 'frontend', 'db']] = None,
|
|
13
38
|
log_level: Union[
|
|
14
39
|
None,
|
|
15
|
-
Literal['DEBUG', 'INFO', 'WARNING', 'ERROR']] = None
|
|
16
|
-
|
|
40
|
+
Literal['DEBUG', 'INFO', 'WARNING', 'ERROR']] = None,
|
|
41
|
+
log_file: Union[
|
|
42
|
+
None,
|
|
43
|
+
str] = None,
|
|
44
|
+
analyze_log: bool = False
|
|
45
|
+
) -> int:
|
|
17
46
|
"""
|
|
18
47
|
This function will continue the installation the FACT_core after the restart of the computer.
|
|
19
48
|
|
|
@@ -28,7 +57,10 @@ def install_after_restart(
|
|
|
28
57
|
:param log_level: string, the log level to use for the installation.
|
|
29
58
|
The same as using the '--log-level' parameter in the 'install.py' script.
|
|
30
59
|
The default is 'INFO' in the 'install.py' script.
|
|
31
|
-
:
|
|
60
|
+
:param log_file: string, the log file to use for the installation.
|
|
61
|
+
The same as using the '--log-file' parameter in the 'install.py' script.
|
|
62
|
+
:param analyze_log: bool, if True, the log file will be analyzed for plugin installation errors.
|
|
63
|
+
:return: int, 0 if the installation was successful, otherwise 1.
|
|
32
64
|
"""
|
|
33
65
|
|
|
34
66
|
install_command: str = 'python3 "' + str(Path(installation_directory, config_install.INSTALL_FILE_PATH)) + '"'
|
|
@@ -37,10 +69,51 @@ def install_after_restart(
|
|
|
37
69
|
install_command = install_command + ' --' + install_type
|
|
38
70
|
|
|
39
71
|
if log_level:
|
|
40
|
-
install_command = install_command + ' --
|
|
72
|
+
install_command = install_command + ' --log_level ' + log_level
|
|
73
|
+
|
|
74
|
+
if log_file:
|
|
75
|
+
install_command = install_command + ' --log_file "' + log_file + '"'
|
|
41
76
|
|
|
42
77
|
# Install the FACT_core repo.
|
|
43
78
|
process.execute_with_live_output(cmd=install_command, verbose=True)
|
|
79
|
+
|
|
80
|
+
# Analyze the log file for errors.
|
|
81
|
+
if analyze_log and (install_type == 'backend' or install_type is None):
|
|
82
|
+
if not log_file:
|
|
83
|
+
log_file = str(Path.cwd() / config_install.INSTALL_LOG_FILE_NAME)
|
|
84
|
+
|
|
85
|
+
return analyze_log_file(log_file=log_file)
|
|
86
|
+
|
|
44
87
|
# Remove the FACT_core installation log.
|
|
45
88
|
# working_directory_path: str = filesystem.get_working_directory()
|
|
46
89
|
# filesystem.remove_file(str(Path(working_directory_path, config_install.INSTALL_LOG_FILE_NAME)))
|
|
90
|
+
|
|
91
|
+
return 0
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def analyze_log_file(log_file: str):
|
|
95
|
+
"""
|
|
96
|
+
This function will analyze the log file for plugin installation errors.
|
|
97
|
+
:param log_file:
|
|
98
|
+
:return:
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
with open(log_file, 'r') as file:
|
|
102
|
+
log_content: str = file.read()
|
|
103
|
+
|
|
104
|
+
for plugin in PLUGIN_LIST:
|
|
105
|
+
if f'{FINISHED_INSTALLING_STRINGS[0]} {plugin} {FINISHED_INSTALLING_STRINGS[1]}' not in log_content:
|
|
106
|
+
message = (f'Error: [{plugin}] installation failed.\n'
|
|
107
|
+
f'Check the log file: {log_file}\n'
|
|
108
|
+
f'Exiting...')
|
|
109
|
+
print_api.print_api(message, color='red')
|
|
110
|
+
return 1
|
|
111
|
+
|
|
112
|
+
if LOG_FINISHED_STRING not in log_content:
|
|
113
|
+
message = (f'Error: Installation failed.\n'
|
|
114
|
+
f'Check the log file: {log_file}\n'
|
|
115
|
+
f'Exiting...')
|
|
116
|
+
print_api.print_api(message, color='red')
|
|
117
|
+
return 1
|
|
118
|
+
|
|
119
|
+
return 0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=cTkolJcyCusHq9bBDXgphXYHAv5YCLiWysUXbZegGZc,124
|
|
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
|
|
@@ -45,7 +45,7 @@ atomicshop/urls.py,sha256=aJ0NGS9qqaKeqjkkWBs80jaBBg6MYBiPuLIyPGxscVc,1557
|
|
|
45
45
|
atomicshop/uuids.py,sha256=JSQdm3ZTJiwPQ1gYe6kU0TKS_7suwVrHc8JZDGYlydM,2214
|
|
46
46
|
atomicshop/virtualization.py,sha256=LPP4vjE0Vr10R6DA4lqhfX_WaNdDGRAZUW0Am6VeGco,494
|
|
47
47
|
atomicshop/web.py,sha256=GLdTXgMxg1_0UQaXC4bOvARVyuFg7SPIeJdsCHV8rNE,11662
|
|
48
|
-
atomicshop/websocket_parse.py,sha256=
|
|
48
|
+
atomicshop/websocket_parse.py,sha256=PygRqEFnqEcPx3PNRtJoZcKN-mXvT_zighzTJR_B-Tc,14934
|
|
49
49
|
atomicshop/a_installs/ubuntu/docker_rootless.py,sha256=9IPNtGZYjfy1_n6ZRt7gWz9KZgR6XCgevjqq02xk-o0,281
|
|
50
50
|
atomicshop/a_installs/ubuntu/docker_sudo.py,sha256=JzayxeyKDtiuT4Icp2L2LyFRbx4wvpyN_bHLfZ-yX5E,281
|
|
51
51
|
atomicshop/a_installs/ubuntu/elastic_search_and_kibana.py,sha256=yRB-l1zBxdiN6av-FwNkhcBlaeu4zrDPjQ0uPGgpK2I,244
|
|
@@ -117,7 +117,7 @@ atomicshop/etws/traces/trace_dns.py,sha256=WvOZm7KNdP4r6ofkZhUGi9WjtYlkV3mUp_yxi
|
|
|
117
117
|
atomicshop/etws/traces/trace_sysmon_process_creation.py,sha256=OM-bkK38uYMwWLZKNOTDa0Xdk3sO6sqsxoMUIiPvm5g,4656
|
|
118
118
|
atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
119
119
|
atomicshop/file_io/csvs.py,sha256=jBdm3_z5cMyvxLxJnGcybUAptHAbyL0r0tlLqY0sdTQ,9327
|
|
120
|
-
atomicshop/file_io/docxs.py,sha256=
|
|
120
|
+
atomicshop/file_io/docxs.py,sha256=3ctQ9JiGx8K8EYeKWiuraLtqhilW1qk1cZX9lHv0usk,5753
|
|
121
121
|
atomicshop/file_io/file_io.py,sha256=5Kl0P6vF4GQVdwew1lzHLb-db9qiMvDjTgccbi5P-zk,7167
|
|
122
122
|
atomicshop/file_io/jsons.py,sha256=q9ZU8slBKnHLrtn3TnbK1qxrRpj5ZvCm6AlsFzoANjo,5303
|
|
123
123
|
atomicshop/file_io/tomls.py,sha256=ol8EvQPf9sryTmZUf1v55BYSUQ6ml7HVVBHpNKbsIlA,9768
|
|
@@ -229,7 +229,7 @@ atomicshop/wrappers/factw/fact_extractor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
|
|
|
229
229
|
atomicshop/wrappers/factw/fact_extractor/docker_image.py,sha256=2FyYjnw8gxFNwISQ83OwH-iGivkFi6EAluyCZ0loHEQ,2501
|
|
230
230
|
atomicshop/wrappers/factw/fact_extractor/get_extractor.py,sha256=2mfOAftHIlCcGt1s7MWdq7DsDCuI6wX3MtvcEZ4SK-0,756
|
|
231
231
|
atomicshop/wrappers/factw/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
232
|
-
atomicshop/wrappers/factw/install/install_after_restart.py,sha256=
|
|
232
|
+
atomicshop/wrappers/factw/install/install_after_restart.py,sha256=cr8E9BAEdpJXJ1VdyXr85byU0PvE3tPV0uPALQOmiKg,4318
|
|
233
233
|
atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py,sha256=GFsO9MTH0czKoxkiPJtjalilUwsmFLBCcx9Znv37S4M,5945
|
|
234
234
|
atomicshop/wrappers/factw/postgresql/__init__.py,sha256=xMBn2d3Exo23IPP2F_9-SXmOlhFbwWDgS9KwozSTjA0,162
|
|
235
235
|
atomicshop/wrappers/factw/postgresql/analysis.py,sha256=2Rxzy2jyq3zEKIo53z8VkjuslKE_i5mq2ZpmJAvyd6U,716
|
|
@@ -315,8 +315,8 @@ atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0L
|
|
|
315
315
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=w1AH-zf4mBuT4euf28UKij9ihM-b1BRU9Qfby0QDdqI,2957
|
|
316
316
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
317
317
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=ChnVG8ZecKJ-DMF8nUHRiifWJq2M4slEwKat6FBfPfE,8685
|
|
318
|
-
atomicshop-2.16.
|
|
319
|
-
atomicshop-2.16.
|
|
320
|
-
atomicshop-2.16.
|
|
321
|
-
atomicshop-2.16.
|
|
322
|
-
atomicshop-2.16.
|
|
318
|
+
atomicshop-2.16.44.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
319
|
+
atomicshop-2.16.44.dist-info/METADATA,sha256=yeA-HD5CtX5FhTCrJG9ylhYHECkHvJL_ai4gaOnilY4,10500
|
|
320
|
+
atomicshop-2.16.44.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
321
|
+
atomicshop-2.16.44.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
322
|
+
atomicshop-2.16.44.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|