atomicshop 2.17.2__py3-none-any.whl → 2.18.0__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/basics/ansi_escape_codes.py +3 -1
- atomicshop/file_io/docxs.py +26 -17
- atomicshop/http_parse.py +118 -77
- atomicshop/mitm/config_static.py +1 -0
- atomicshop/mitm/connection_thread_worker.py +350 -260
- atomicshop/mitm/engines/__parent/parser___parent.py +2 -2
- atomicshop/mitm/engines/__parent/recorder___parent.py +83 -24
- atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +2 -2
- atomicshop/mitm/message.py +40 -15
- atomicshop/mitm/mitm_main.py +3 -2
- atomicshop/mitm/recs_files.py +2 -1
- atomicshop/system_resource_monitor.py +16 -3
- atomicshop/wrappers/socketw/base.py +17 -0
- atomicshop/wrappers/socketw/creator.py +32 -4
- atomicshop/wrappers/socketw/receiver.py +90 -100
- atomicshop/wrappers/socketw/sender.py +5 -8
- atomicshop/wrappers/socketw/socket_client.py +15 -4
- atomicshop/wrappers/socketw/statistics_csv.py +12 -6
- {atomicshop-2.17.2.dist-info → atomicshop-2.18.0.dist-info}/METADATA +1 -1
- {atomicshop-2.17.2.dist-info → atomicshop-2.18.0.dist-info}/RECORD +24 -24
- {atomicshop-2.17.2.dist-info → atomicshop-2.18.0.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.17.2.dist-info → atomicshop-2.18.0.dist-info}/WHEEL +0 -0
- {atomicshop-2.17.2.dist-info → atomicshop-2.18.0.dist-info}/top_level.txt +0 -0
|
@@ -21,21 +21,25 @@ def peek_first_bytes(client_socket, bytes_amount: int = 1) -> bytes:
|
|
|
21
21
|
return client_socket.recv(bytes_amount, socket.MSG_PEEK)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def is_socket_ready_for_read(
|
|
24
|
+
def is_socket_ready_for_read(socket_instance, timeout: int = 0) -> bool:
|
|
25
25
|
"""
|
|
26
26
|
Check if socket is ready for read.
|
|
27
27
|
|
|
28
|
-
:param
|
|
28
|
+
:param socket_instance: Socket object.
|
|
29
29
|
:param timeout: Timeout in seconds. The default is no timeout.
|
|
30
30
|
|
|
31
31
|
:return: True if socket is ready for read, False otherwise.
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
|
+
# Check if the socket is closed.
|
|
35
|
+
if socket_instance.fileno() == -1:
|
|
36
|
+
return False
|
|
37
|
+
|
|
34
38
|
# Use select to check if the socket is ready for reading.
|
|
35
39
|
# 'readable' returns a list of sockets that are ready for reading.
|
|
36
40
|
# Since we use only one socket, it will return a list with one element if the socket is ready for reading,
|
|
37
41
|
# or an empty list if the socket is not ready for reading.
|
|
38
|
-
readable, _, _ = select.select([
|
|
42
|
+
readable, _, _ = select.select([socket_instance], [], [], timeout)
|
|
39
43
|
return bool(readable)
|
|
40
44
|
|
|
41
45
|
|
|
@@ -69,129 +73,115 @@ class Receiver:
|
|
|
69
73
|
self.logger: logging.Logger = logger
|
|
70
74
|
|
|
71
75
|
# Function to receive only the buffer, with error handling
|
|
72
|
-
def
|
|
76
|
+
def chunk_from_buffer(self) -> tuple[bytes, str]:
|
|
77
|
+
"""
|
|
78
|
+
Receive a chunk from the socket buffer.
|
|
79
|
+
|
|
80
|
+
:return: Tuple(received chunk binary bytes data, error message string).
|
|
81
|
+
"""
|
|
73
82
|
# Defining the data variable
|
|
74
|
-
|
|
83
|
+
# noinspection PyTypeChecker
|
|
84
|
+
received_data: bytes = None
|
|
85
|
+
# noinspection PyTypeChecker
|
|
86
|
+
error_message: str = None
|
|
75
87
|
|
|
88
|
+
# All excepts will be treated as empty message, indicate that socket was closed and will be handled properly.
|
|
76
89
|
try:
|
|
77
90
|
# "recv(byte buffer size)" to read the server's response.
|
|
78
|
-
|
|
91
|
+
# A signal to close connection will be empty bytes string: b''.
|
|
92
|
+
received_data = self.ssl_socket.recv(self.buffer_size_receive)
|
|
79
93
|
except ConnectionAbortedError:
|
|
80
|
-
|
|
81
|
-
print_api(
|
|
82
|
-
# This will be treated as empty message - indicate that socket was closed and will be handled properly.
|
|
83
|
-
pass
|
|
94
|
+
error_message = "* Connection was aborted by the client. Exiting..."
|
|
95
|
+
print_api(error_message, logger=self.logger, logger_method='critical', traceback_string=True)
|
|
84
96
|
except ConnectionResetError:
|
|
85
|
-
|
|
86
|
-
print_api(
|
|
87
|
-
# This will be treated as empty message - indicate that socket was closed and will be handled properly.
|
|
88
|
-
pass
|
|
97
|
+
error_message = "* Connection was forcibly closed by the client. Exiting..."
|
|
98
|
+
print_api(error_message, logger=self.logger, logger_method='critical', traceback_string=True)
|
|
89
99
|
except ssl.SSLError:
|
|
90
|
-
|
|
91
|
-
print_api(
|
|
92
|
-
# This will be treated as empty message - indicate that socket was closed and will be handled properly.
|
|
93
|
-
pass
|
|
100
|
+
error_message = "* Encountered SSL error on packet receive. Exiting..."
|
|
101
|
+
print_api(error_message, logger=self.logger, logger_method='critical', traceback_string=True)
|
|
94
102
|
|
|
95
|
-
if
|
|
103
|
+
if received_data == b'':
|
|
96
104
|
self.logger.info("Empty message received, socket closed on the other side.")
|
|
97
105
|
|
|
98
|
-
return
|
|
106
|
+
return received_data, error_message
|
|
99
107
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
# ended and the message is longer than the receiving buffer.
|
|
104
|
-
# So we need to set the timeout for the client socket.
|
|
105
|
-
# If you set "timeout" on the listening main socket, it is not inherited to the child socket when client
|
|
106
|
-
# connected, so you need to set it for the new socket as well.
|
|
107
|
-
# Each function need to set the timeout independently
|
|
108
|
-
self.ssl_socket.settimeout(self.socket_timeout)
|
|
109
|
-
# variable that is responsible to retry over the same receive session if packet is less than buffer
|
|
110
|
-
partial_data_received: bool = False
|
|
108
|
+
def socket_receive_message_full(self) -> tuple[bytes, bool, str]:
|
|
109
|
+
"""
|
|
110
|
+
Receive the full message from the socket.
|
|
111
111
|
|
|
112
|
+
:return: Tuple(full data binary bytes, is socket closed boolean, error message string).
|
|
113
|
+
"""
|
|
112
114
|
# Define the variable that is going to aggregate the whole data received
|
|
113
|
-
|
|
114
|
-
#
|
|
115
|
-
|
|
115
|
+
full_data: bytes = bytes()
|
|
116
|
+
# noinspection PyTypeChecker
|
|
117
|
+
error_message: str = None
|
|
116
118
|
|
|
117
119
|
# Infinite loop to accept data from the client
|
|
120
|
+
# We'll skip the 'is_socket_ready_for_read' check on the first run, since we want to read the data anyway,
|
|
121
|
+
# to leave the socket in the blocking mode.
|
|
122
|
+
first_run: bool = True
|
|
118
123
|
while True:
|
|
119
|
-
#
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
#
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
124
|
+
# Check if there is data to be read from the socket.
|
|
125
|
+
is_there_data: bool = is_socket_ready_for_read(self.ssl_socket, timeout=0)
|
|
126
|
+
# noinspection PyTypeChecker
|
|
127
|
+
if is_there_data or first_run:
|
|
128
|
+
first_run = False
|
|
129
|
+
# Receive the data from the socket.
|
|
130
|
+
received_chunk, error_message = self.chunk_from_buffer()
|
|
131
|
+
received_chunk: bytes
|
|
132
|
+
error_message: str
|
|
133
|
+
|
|
134
|
+
# And if the message received is not empty then aggregate it to the main "data received" variable
|
|
135
|
+
if received_chunk != b'' and received_chunk is not None:
|
|
136
|
+
full_data += received_chunk
|
|
137
|
+
|
|
138
|
+
self.logger.info(f"Received packet bytes: [{len(received_chunk)}] | "
|
|
139
|
+
f"Total aggregated bytes: [{len(full_data)}]")
|
|
140
|
+
|
|
141
|
+
elif received_chunk == b'' or received_chunk is None:
|
|
142
|
+
# If there received_chunk is None, this means that the socket was closed,
|
|
143
|
+
# since it is a connection error.
|
|
144
|
+
# Same goes for the empty message.
|
|
145
|
+
is_socket_closed = True
|
|
136
146
|
break
|
|
137
|
-
else:
|
|
138
|
-
self.logger.info(
|
|
139
|
-
# Dividing number of seconds by 60 to get minutes
|
|
140
|
-
f"{self.socket_timeout/60} minutes timeout reached on 'socket.recv()' - no data received from "
|
|
141
|
-
f"{self.class_client_address}:{self.class_client_local_port}. Still waiting...")
|
|
142
|
-
# Pass the exception
|
|
143
|
-
pass
|
|
144
|
-
# Changing the socket timeout back to none since receiving operation has been finished.
|
|
145
|
-
self.ssl_socket.settimeout(None)
|
|
146
|
-
# Continue to the next iteration inside while
|
|
147
|
-
continue
|
|
148
|
-
|
|
149
|
-
# And if the message received is not empty then aggregate it to the main "data received" variable
|
|
150
|
-
if class_data_received:
|
|
151
|
-
class_data.extend(class_data_received)
|
|
152
|
-
|
|
153
|
-
self.logger.info(f"Received packet with {len(class_data_received)} bytes. "
|
|
154
|
-
f"Current aggregated request of total: {len(class_data)} bytes")
|
|
155
|
-
|
|
156
|
-
# If the first received session is less than the buffer size, then the full message was received
|
|
157
|
-
if len(class_data_received) < self.buffer_size_receive:
|
|
158
|
-
# Since we already received some data from the other side, the retried variable will be true
|
|
159
|
-
partial_data_received = True
|
|
160
|
-
self.logger.info(f"Receiving the buffer again...")
|
|
161
|
-
|
|
162
|
-
# In this case the socket timeout will be 2 seconds to wait for more packets.
|
|
163
|
-
# If there are no more packets, receiver will end its activity and pass the message to
|
|
164
|
-
# the rest of the components in the network chain
|
|
165
|
-
if self.socket_timeout != 0.5:
|
|
166
|
-
self.socket_timeout = 0.5
|
|
167
|
-
self.ssl_socket.settimeout(self.socket_timeout)
|
|
168
|
-
self.logger.info(f"Timeout changed to {self.socket_timeout} seconds")
|
|
169
|
-
|
|
170
|
-
# Continue to the next receive on the socket
|
|
171
|
-
continue
|
|
172
147
|
else:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
f"client in the next cycle - empty message will be received again, and current "
|
|
177
|
-
f"socket will be finally closed.")
|
|
148
|
+
# If there is no data to be read from the socket, it doesn't mean that the socket is closed.
|
|
149
|
+
is_socket_closed = False
|
|
150
|
+
received_chunk = None
|
|
178
151
|
break
|
|
179
152
|
|
|
180
|
-
|
|
153
|
+
if full_data:
|
|
154
|
+
self.logger.info(f"Received total: [{len(full_data)}] bytes")
|
|
155
|
+
|
|
156
|
+
# In case the full data is empty, and the received chunk is None, it doesn't mean that the socket is closed.
|
|
157
|
+
# But it means that there was no data to be read from the socket, because of error or timeout.
|
|
158
|
+
if full_data == b'' and received_chunk is None:
|
|
159
|
+
full_data = None
|
|
160
|
+
|
|
161
|
+
return full_data, is_socket_closed, error_message
|
|
162
|
+
|
|
163
|
+
def receive(self) -> tuple[bytes, bool, str]:
|
|
164
|
+
"""
|
|
165
|
+
Receive the message from the socket.
|
|
181
166
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
167
|
+
:return: Tuple(
|
|
168
|
+
data binary bytes,
|
|
169
|
+
is socket closed boolean,
|
|
170
|
+
error message string if there was a connection exception).
|
|
171
|
+
"""
|
|
172
|
+
# Getting client address and Local port from the socket
|
|
185
173
|
self.class_client_address = self.ssl_socket.getpeername()[0]
|
|
186
|
-
# Getting client Local port from the socket
|
|
187
174
|
self.class_client_local_port = self.ssl_socket.getpeername()[1]
|
|
188
175
|
|
|
189
176
|
# Receiving data from the socket and closing the socket if send is finished.
|
|
190
177
|
self.logger.info(f"Waiting for data from {self.class_client_address}:{self.class_client_local_port}")
|
|
191
|
-
|
|
178
|
+
socket_data_bytes, is_socket_closed, error_message = self.socket_receive_message_full()
|
|
179
|
+
socket_data_bytes: bytes
|
|
180
|
+
is_socket_closed: bool
|
|
181
|
+
error_message: str
|
|
192
182
|
|
|
193
|
-
if
|
|
183
|
+
if socket_data_bytes:
|
|
194
184
|
# Put only 100 characters to the log, since we record the message any way in full - later.
|
|
195
|
-
self.logger.info(f"Received: {
|
|
185
|
+
self.logger.info(f"Received: {socket_data_bytes[0: 100]}...")
|
|
196
186
|
|
|
197
|
-
return
|
|
187
|
+
return socket_data_bytes, is_socket_closed, error_message
|
|
@@ -13,10 +13,10 @@ class Sender:
|
|
|
13
13
|
def __init__(
|
|
14
14
|
self,
|
|
15
15
|
ssl_socket: ssl.SSLSocket,
|
|
16
|
-
class_message:
|
|
16
|
+
class_message: bytes,
|
|
17
17
|
logger: logging.Logger = None
|
|
18
18
|
):
|
|
19
|
-
self.class_message:
|
|
19
|
+
self.class_message: bytes = class_message
|
|
20
20
|
self.ssl_socket: ssl.SSLSocket = ssl_socket
|
|
21
21
|
|
|
22
22
|
if logger:
|
|
@@ -35,12 +35,11 @@ class Sender:
|
|
|
35
35
|
# The error string that will be returned by the function in case of error.
|
|
36
36
|
# If returned None then everything is fine.
|
|
37
37
|
# noinspection PyTypeChecker
|
|
38
|
-
|
|
38
|
+
error_message: str = None
|
|
39
|
+
|
|
39
40
|
# Current amount of bytes sent is 0, since we didn't start yet
|
|
40
41
|
total_sent_bytes = 0
|
|
41
42
|
|
|
42
|
-
# noinspection PyTypeChecker
|
|
43
|
-
error_message: str = None
|
|
44
43
|
try:
|
|
45
44
|
# Getting byte length of current message
|
|
46
45
|
current_message_length = len(self.class_message)
|
|
@@ -59,7 +58,6 @@ class Sender:
|
|
|
59
58
|
f"Sent {sent_bytes} bytes - connection is down... Could send only "
|
|
60
59
|
f"{total_sent_bytes} bytes out of {current_message_length}. Closing socket...")
|
|
61
60
|
self.logger.info(error_message)
|
|
62
|
-
function_result_error = error_message
|
|
63
61
|
break
|
|
64
62
|
|
|
65
63
|
# Adding amount of currently sent bytes to the total amount of bytes sent
|
|
@@ -97,6 +95,5 @@ class Sender:
|
|
|
97
95
|
|
|
98
96
|
if error_message:
|
|
99
97
|
print_api(error_message, logger=self.logger, logger_method='error')
|
|
100
|
-
function_result_error = error_message
|
|
101
98
|
|
|
102
|
-
return
|
|
99
|
+
return error_message
|
|
@@ -30,7 +30,8 @@ class SocketClient:
|
|
|
30
30
|
connection_ip=None,
|
|
31
31
|
dns_servers_list=None,
|
|
32
32
|
logger: logging.Logger = None,
|
|
33
|
-
custom_pem_client_certificate_file_path: str = None
|
|
33
|
+
custom_pem_client_certificate_file_path: str = None,
|
|
34
|
+
enable_sslkeylogfile_env_to_client_ssl_context: bool = False
|
|
34
35
|
):
|
|
35
36
|
"""
|
|
36
37
|
If you have a certificate for domain, but not for the IPv4 address, the SSL Socket context can be created for
|
|
@@ -50,6 +51,13 @@ class SocketClient:
|
|
|
50
51
|
:param logger: (Optional) Logger object. If not provided, the default logger will be used.
|
|
51
52
|
:param custom_pem_client_certificate_file_path: (Optional) If specified, the SSL Socket will be created with
|
|
52
53
|
custom client certificate. The path to the file with the certificate should be provided.
|
|
54
|
+
:param enable_sslkeylogfile_env_to_client_ssl_context: boolean, enables the SSLKEYLOGFILE environment variable
|
|
55
|
+
to the SSL context. Default is False.
|
|
56
|
+
if True, SSLKEYLOGFILE will be added to SSL context with:
|
|
57
|
+
ssl_context.keylog_filename = os.environ.get('SSLKEYLOGFILE')
|
|
58
|
+
This is useful for debugging SSL/TLS connections with WireShark.
|
|
59
|
+
Since WireShark also uses this environment variable to read the key log file and apply to the SSL/TLS
|
|
60
|
+
connections, so you can see the decrypted traffic.
|
|
53
61
|
|
|
54
62
|
If both 'connection_ip' and 'dns_servers_list' specified, ValueException with raise.
|
|
55
63
|
"""
|
|
@@ -59,6 +67,7 @@ class SocketClient:
|
|
|
59
67
|
self.connection_ip = connection_ip
|
|
60
68
|
self.dns_servers_list = dns_servers_list
|
|
61
69
|
self.custom_pem_client_certificate_file_path: str = custom_pem_client_certificate_file_path
|
|
70
|
+
self.enable_sslkeylogfile_env_to_client_ssl_context: bool = enable_sslkeylogfile_env_to_client_ssl_context
|
|
62
71
|
|
|
63
72
|
if logger:
|
|
64
73
|
# Create child logger for the provided logger with the module's name.
|
|
@@ -91,7 +100,9 @@ class SocketClient:
|
|
|
91
100
|
print_api.print_api(log_message, logger=self.logger, logger_method='info')
|
|
92
101
|
socket_object = creator.create_socket_ipv4_tcp()
|
|
93
102
|
return creator.wrap_socket_with_ssl_context_client___default_certs___ignore_verification(
|
|
94
|
-
socket_object, self.service_name, self.custom_pem_client_certificate_file_path
|
|
103
|
+
socket_object, self.service_name, self.custom_pem_client_certificate_file_path,
|
|
104
|
+
enable_sslkeylogfile_env_to_client_ssl_context=self.enable_sslkeylogfile_env_to_client_ssl_context
|
|
105
|
+
)
|
|
95
106
|
|
|
96
107
|
def service_connection(
|
|
97
108
|
self
|
|
@@ -102,8 +113,8 @@ class SocketClient:
|
|
|
102
113
|
Function to establish connection to server
|
|
103
114
|
|
|
104
115
|
:return: Tuple with socket object and error string.
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
If connection was successful, the error string will be None.
|
|
117
|
+
If connection wasn't successful, the socket object will be None.
|
|
107
118
|
"""
|
|
108
119
|
# Check if socket to service domain exists.
|
|
109
120
|
# If not
|
|
@@ -6,8 +6,8 @@ from ..loggingw import loggingw
|
|
|
6
6
|
|
|
7
7
|
LOGGER_NAME: str = 'statistics'
|
|
8
8
|
STATISTICS_HEADER: str = (
|
|
9
|
-
'request_time_sent,thread_id,tls,protocol,host,path,command,status_code,request_size_bytes,response_size_bytes,file_path,'
|
|
10
|
-
'process_cmd,error')
|
|
9
|
+
'request_time_sent,thread_id,tls,protocol,protocol2,host,path,command,status_code,request_size_bytes,response_size_bytes,file_path,'
|
|
10
|
+
'process_cmd,action,error')
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class StatisticsCSVWriter:
|
|
@@ -35,6 +35,7 @@ class StatisticsCSVWriter:
|
|
|
35
35
|
tls_type: str,
|
|
36
36
|
tls_version: str,
|
|
37
37
|
protocol: str,
|
|
38
|
+
protocol2: str,
|
|
38
39
|
path: str,
|
|
39
40
|
status_code: str,
|
|
40
41
|
command: str,
|
|
@@ -43,10 +44,11 @@ class StatisticsCSVWriter:
|
|
|
43
44
|
recorded_file_path: str = None,
|
|
44
45
|
process_cmd: str = None,
|
|
45
46
|
error: str = None,
|
|
46
|
-
|
|
47
|
+
action: str = None,
|
|
48
|
+
timestamp=None,
|
|
47
49
|
):
|
|
48
|
-
if not
|
|
49
|
-
|
|
50
|
+
if not timestamp:
|
|
51
|
+
timestamp = datetime.datetime.now()
|
|
50
52
|
|
|
51
53
|
if not tls_type and not tls_version:
|
|
52
54
|
tls_info = ''
|
|
@@ -54,10 +56,11 @@ class StatisticsCSVWriter:
|
|
|
54
56
|
tls_info = f'{tls_type}|{tls_version}'
|
|
55
57
|
|
|
56
58
|
escaped_line_string: str = csvs.escape_csv_line_to_string([
|
|
57
|
-
|
|
59
|
+
timestamp,
|
|
58
60
|
thread_id,
|
|
59
61
|
tls_info,
|
|
60
62
|
protocol,
|
|
63
|
+
protocol2,
|
|
61
64
|
host,
|
|
62
65
|
path,
|
|
63
66
|
command,
|
|
@@ -66,6 +69,7 @@ class StatisticsCSVWriter:
|
|
|
66
69
|
response_size_bytes,
|
|
67
70
|
recorded_file_path,
|
|
68
71
|
process_cmd,
|
|
72
|
+
action,
|
|
69
73
|
error
|
|
70
74
|
])
|
|
71
75
|
|
|
@@ -95,6 +99,7 @@ class StatisticsCSVWriter:
|
|
|
95
99
|
tls_type='',
|
|
96
100
|
tls_version='',
|
|
97
101
|
protocol='',
|
|
102
|
+
protocol2='',
|
|
98
103
|
path='',
|
|
99
104
|
status_code='',
|
|
100
105
|
command='',
|
|
@@ -102,5 +107,6 @@ class StatisticsCSVWriter:
|
|
|
102
107
|
response_size_bytes='',
|
|
103
108
|
recorded_file_path='',
|
|
104
109
|
process_cmd=process_name,
|
|
110
|
+
action='client_accept',
|
|
105
111
|
error=error_message
|
|
106
112
|
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=_rMDmeAEfTlnh9BqKgZC0sYcOXLQPbyCSOsQYH_2pl0,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
|
|
@@ -19,7 +19,7 @@ atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
|
|
|
19
19
|
atomicshop/get_process_list.py,sha256=8cxb7gKe9sl4R6H2yMi8J6oe-RkonTvCdKjRFqi-Fs4,6075
|
|
20
20
|
atomicshop/get_process_name_cmd_dll.py,sha256=CtaSp3mgxxJKCCVW8BLx6BJNx4giCklU_T7USiCEwfc,5162
|
|
21
21
|
atomicshop/hashing.py,sha256=Le8qGFyt3_wX-zGTeQShz7L2HL_b6nVv9PnawjglyHo,3474
|
|
22
|
-
atomicshop/http_parse.py,sha256=
|
|
22
|
+
atomicshop/http_parse.py,sha256=1Tna9YbOM0rE3t6i_M-klBlwd1KNSA9skA_BqKGXDFc,11861
|
|
23
23
|
atomicshop/inspect_wrapper.py,sha256=sGRVQhrJovNygHTydqJj0hxES-aB2Eg9KbIk3G31apw,11429
|
|
24
24
|
atomicshop/ip_addresses.py,sha256=Hvi4TumEFoTEpKWaq5WNF-YzcRzt24IxmNgv-Mgax1s,1190
|
|
25
25
|
atomicshop/keyboard_press.py,sha256=1W5kRtOB75fulVx-uF2yarBhW0_IzdI1k73AnvXstk0,452
|
|
@@ -37,7 +37,7 @@ atomicshop/sound.py,sha256=tHiQQbFBk7EYN3pAfGNcxfF9oNsoYnZgu9z9iq8hxQE,24352
|
|
|
37
37
|
atomicshop/speech_recognize.py,sha256=55-dIjgkpF93mvJnJuxSFuft5H5eRvGNlUj9BeIOZxk,5903
|
|
38
38
|
atomicshop/ssh_remote.py,sha256=Mxixqs2-xGy1bhbcP0LKqjxKTNPz1Gmzz8PzO8aLB4c,17345
|
|
39
39
|
atomicshop/sys_functions.py,sha256=MTBxRve5bh58SPvhX3gMiGqHlSBuI_rdNN1NnnBBWqI,906
|
|
40
|
-
atomicshop/system_resource_monitor.py,sha256=
|
|
40
|
+
atomicshop/system_resource_monitor.py,sha256=yHdBU4mAVqoVS0Nn_SM_H42i4PgsgXDaXaMxfnL5CgA,14588
|
|
41
41
|
atomicshop/system_resources.py,sha256=iKUvVSaXR47inmr3cTYsgNfclT38dRia2oupnlhIpK4,9290
|
|
42
42
|
atomicshop/tempfiles.py,sha256=uq1ve2WlWehZ3NOTXJnpBBMt6HyCdBufqedF0HyzA6k,2517
|
|
43
43
|
atomicshop/timer.py,sha256=7Zw1KRV0acHCRATMnanyX2MLBb63Hc-6us3rCZ9dNlY,2345
|
|
@@ -83,7 +83,7 @@ atomicshop/archiver/sevenzs.py,sha256=5i_C50-deC1Cz_GQdMGofV2jeMPbbGWAvih-QnA72c
|
|
|
83
83
|
atomicshop/archiver/shutils.py,sha256=BomnK7zT-nQXA1z0i2R2aTv8eu88wPx7tf2HtOdbmEc,1280
|
|
84
84
|
atomicshop/archiver/zips.py,sha256=0Z_1MWs7YRiCBVpyaG8llnzRguHSO4R51KDMN3FJZt8,16984
|
|
85
85
|
atomicshop/basics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
86
|
-
atomicshop/basics/ansi_escape_codes.py,sha256=
|
|
86
|
+
atomicshop/basics/ansi_escape_codes.py,sha256=uGVRW01v2O052701sOfAdCaM_GLF_cu_jrssuYiPbzA,3216
|
|
87
87
|
atomicshop/basics/argparse_template.py,sha256=horwgSf3MX1ZgRnYxtmmQuz9OU_vKrKggF65gmjlmfg,5836
|
|
88
88
|
atomicshop/basics/booleans.py,sha256=V36NaMf8AffhCom_ovQeOZlYcdtGyIcQwWKki6h7O0M,1745
|
|
89
89
|
atomicshop/basics/bytes_arrays.py,sha256=tU7KF0UAFSErGNcan4Uz1GJxeIYVRuUu9sHVZHgyNnw,6542
|
|
@@ -118,33 +118,33 @@ atomicshop/etws/traces/trace_dns.py,sha256=WvOZm7KNdP4r6ofkZhUGi9WjtYlkV3mUp_yxi
|
|
|
118
118
|
atomicshop/etws/traces/trace_sysmon_process_creation.py,sha256=OM-bkK38uYMwWLZKNOTDa0Xdk3sO6sqsxoMUIiPvm5g,4656
|
|
119
119
|
atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
120
120
|
atomicshop/file_io/csvs.py,sha256=jBdm3_z5cMyvxLxJnGcybUAptHAbyL0r0tlLqY0sdTQ,9327
|
|
121
|
-
atomicshop/file_io/docxs.py,sha256=
|
|
121
|
+
atomicshop/file_io/docxs.py,sha256=Nyt3hSpzwqUKZEP5p5efqNpjFs9XqkK40Kp7BbbPo7E,6245
|
|
122
122
|
atomicshop/file_io/file_io.py,sha256=5Kl0P6vF4GQVdwew1lzHLb-db9qiMvDjTgccbi5P-zk,7167
|
|
123
123
|
atomicshop/file_io/jsons.py,sha256=q9ZU8slBKnHLrtn3TnbK1qxrRpj5ZvCm6AlsFzoANjo,5303
|
|
124
124
|
atomicshop/file_io/tomls.py,sha256=ol8EvQPf9sryTmZUf1v55BYSUQ6ml7HVVBHpNKbsIlA,9768
|
|
125
125
|
atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
|
|
126
126
|
atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,2104
|
|
127
127
|
atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
128
|
-
atomicshop/mitm/config_static.py,sha256=
|
|
128
|
+
atomicshop/mitm/config_static.py,sha256=r6M4FJVBr9jGIXmjcOk2KBHvCPelWcbZCQrRh3-G26k,7871
|
|
129
129
|
atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
|
|
130
|
-
atomicshop/mitm/connection_thread_worker.py,sha256=
|
|
130
|
+
atomicshop/mitm/connection_thread_worker.py,sha256=78QurvuN4a-_Z9q8Fydny5CkMlfz1jIF_XAaB4BiiIA,24227
|
|
131
131
|
atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
|
|
132
132
|
atomicshop/mitm/initialize_engines.py,sha256=NWz0yBErSrYBn0xWkJDBcHStBJ-kcsv9VtorcSP9x5M,8258
|
|
133
|
-
atomicshop/mitm/message.py,sha256=
|
|
134
|
-
atomicshop/mitm/mitm_main.py,sha256=
|
|
135
|
-
atomicshop/mitm/recs_files.py,sha256=
|
|
133
|
+
atomicshop/mitm/message.py,sha256=lseej719nJeCKt2eGxyJCH8cYYEXBUm_RwkunBhloKE,2918
|
|
134
|
+
atomicshop/mitm/mitm_main.py,sha256=AxmqUiDHgfzqmIF8v2GZxlEKth6_AMaYcqAxziWMG0U,23430
|
|
135
|
+
atomicshop/mitm/recs_files.py,sha256=ZAAD0twun-FtmbSniXe3XQhIlawvANNB_HxwbHj7kwI,3151
|
|
136
136
|
atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
|
|
137
137
|
atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
|
|
138
138
|
atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
139
139
|
atomicshop/mitm/engines/create_module_template.py,sha256=TAzsA4eLD2wYr7auuL4Nf_71iXqn-BOBXlSkNVrnYD4,5336
|
|
140
140
|
atomicshop/mitm/engines/create_module_template_example.py,sha256=X5xhvbV6-g9jU_bQVhf_crZmaH50LRWz3bS-faQ18ds,489
|
|
141
141
|
atomicshop/mitm/engines/__parent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
142
|
-
atomicshop/mitm/engines/__parent/parser___parent.py,sha256=
|
|
143
|
-
atomicshop/mitm/engines/__parent/recorder___parent.py,sha256=
|
|
142
|
+
atomicshop/mitm/engines/__parent/parser___parent.py,sha256=HHaCXhScl3OlPjz6eUxsDpJaZyk6BNuDMc9xCkeo2Ws,661
|
|
143
|
+
atomicshop/mitm/engines/__parent/recorder___parent.py,sha256=exfElkgOU57hupV6opRCeYPHw91GIkIZL6UY3f2OClM,5635
|
|
144
144
|
atomicshop/mitm/engines/__parent/responder___parent.py,sha256=7WQeR3UmMnN74bDwn-0nz2OfhXJ3-ClXpNGUFZ7wJUE,12004
|
|
145
145
|
atomicshop/mitm/engines/__reference_general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
146
146
|
atomicshop/mitm/engines/__reference_general/parser___reference_general.py,sha256=57MEPZMAjTO6xBDZ-yt6lgGJyqRrP0Do5Gk_cgCiPns,2998
|
|
147
|
-
atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha256=
|
|
147
|
+
atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha256=El2_YHLoHUCiKfkAmGlXxtFpmSjsUFdsb8I1MvSAFaM,653
|
|
148
148
|
atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=IUyQYMPeEhIARfALWiKPFeXagSQD6lRzAxUdi4ZIT88,7010
|
|
149
149
|
atomicshop/mitm/statistic_analyzer_helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
150
150
|
atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py,sha256=pk6L1t1ea1kvlBoR9QEJptOmaX-mumhwLsP2GCKukbk,5920
|
|
@@ -303,24 +303,24 @@ atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py,sha256=9H9MdS__GDBMm8H-
|
|
|
303
303
|
atomicshop/wrappers/pywin32w/wmis/win32process.py,sha256=qMzXtJ5hBZ5ydAyqpDbSx0nO2RJQL95HdmV5SzNKMhk,6826
|
|
304
304
|
atomicshop/wrappers/socketw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
305
305
|
atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-AtqXZevvaYigE,1732
|
|
306
|
-
atomicshop/wrappers/socketw/base.py,sha256=
|
|
306
|
+
atomicshop/wrappers/socketw/base.py,sha256=zYwFxiEzTcItFi1RZQCMxMTLBvECVUiKwivPYKcu44g,2713
|
|
307
307
|
atomicshop/wrappers/socketw/certificator.py,sha256=mtWPJ_ew3OSwt0-1W4jaoco1VIY4NRCrMv3mDUxb_Cc,12418
|
|
308
|
-
atomicshop/wrappers/socketw/creator.py,sha256=
|
|
308
|
+
atomicshop/wrappers/socketw/creator.py,sha256=zMWLsOF07vX-xQZR720LeHQVndUT8q-ytdCrKF5tt9I,12835
|
|
309
309
|
atomicshop/wrappers/socketw/dns_server.py,sha256=RklzINNuoMQn4PGGQEI5hiAldprbVwwvikY6u9X-jTY,49067
|
|
310
310
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=B-X5SHLSUIWToihH2MKnOB1F4A81_X0DpLLfnYKYbEc,7067
|
|
311
311
|
atomicshop/wrappers/socketw/get_process.py,sha256=aJC-_qFUv3NgWCSUzDI72E4z8_-VTZE9NVZ0CwUoNlM,5698
|
|
312
|
-
atomicshop/wrappers/socketw/receiver.py,sha256
|
|
313
|
-
atomicshop/wrappers/socketw/sender.py,sha256=
|
|
312
|
+
atomicshop/wrappers/socketw/receiver.py,sha256=LRQO-RIY0ZRjSMGVHLVJAXFTVO1zvjgIKSefEngPFfc,8186
|
|
313
|
+
atomicshop/wrappers/socketw/sender.py,sha256=aX_K8l_rHjd5AWb8bi5mt8-YTkMYVRDB6DnPqK_XDUE,4754
|
|
314
314
|
atomicshop/wrappers/socketw/sni.py,sha256=Nc8WMZZR21o5GXILQLVWbf7OzNPXAfE8trJY153e9Qk,17591
|
|
315
|
-
atomicshop/wrappers/socketw/socket_client.py,sha256=
|
|
315
|
+
atomicshop/wrappers/socketw/socket_client.py,sha256=oa3GwS4OPgokrJE5_Oc4-5_wlXHxSH9J5f2DKebms8k,22035
|
|
316
316
|
atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
|
|
317
317
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9Exd4j3qhDXcFc74-E,35567
|
|
318
318
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
|
|
319
|
-
atomicshop/wrappers/socketw/statistics_csv.py,sha256=
|
|
319
|
+
atomicshop/wrappers/socketw/statistics_csv.py,sha256=NvN4i7TxTe1kaOYGlIFkSMtrDXuqKlVngc5JIcNkDOg,3305
|
|
320
320
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
321
321
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=zZQfps-CdODQaTUADbHAwKHr5RUg7BLafnKWBbKaLN4,8728
|
|
322
|
-
atomicshop-2.
|
|
323
|
-
atomicshop-2.
|
|
324
|
-
atomicshop-2.
|
|
325
|
-
atomicshop-2.
|
|
326
|
-
atomicshop-2.
|
|
322
|
+
atomicshop-2.18.0.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
323
|
+
atomicshop-2.18.0.dist-info/METADATA,sha256=HR1ivCy6rJMstJDq387Vn9-7DrnIHJ-i4CjK1qD_obs,10499
|
|
324
|
+
atomicshop-2.18.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
325
|
+
atomicshop-2.18.0.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
326
|
+
atomicshop-2.18.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|