atomicshop 2.16.46__py3-none-any.whl → 2.16.48__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/diff_check.py +3 -3
- atomicshop/mitm/connection_thread_worker.py +133 -99
- atomicshop/mitm/initialize_engines.py +0 -3
- atomicshop/mitm/recs_files.py +0 -1
- atomicshop/mitm/shared_functions.py +0 -2
- atomicshop/web_apis/__init__.py +0 -0
- atomicshop/web_apis/google_custom_search.py +0 -0
- atomicshop/web_apis/google_llm.py +42 -0
- atomicshop/wrappers/fibratusw/install.py +1 -2
- atomicshop/wrappers/socketw/receiver.py +19 -0
- atomicshop/wrappers/socketw/sender.py +1 -1
- atomicshop/wrappers/socketw/sni.py +6 -8
- atomicshop/wrappers/socketw/socket_client.py +26 -11
- atomicshop/wrappers/sysmonw.py +1 -1
- {atomicshop-2.16.46.dist-info → atomicshop-2.16.48.dist-info}/METADATA +1 -1
- {atomicshop-2.16.46.dist-info → atomicshop-2.16.48.dist-info}/RECORD +20 -17
- {atomicshop-2.16.46.dist-info → atomicshop-2.16.48.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.16.46.dist-info → atomicshop-2.16.48.dist-info}/WHEEL +0 -0
- {atomicshop-2.16.46.dist-info → atomicshop-2.16.48.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/diff_check.py
CHANGED
|
@@ -54,9 +54,9 @@ class DiffChecker:
|
|
|
54
54
|
function input for that object. So, not always you know what your object type during class initialization.
|
|
55
55
|
:param check_object_display_name: string, name of the object to display in the message.
|
|
56
56
|
If not specified, the provided 'check_object' will be displayed.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
#:param aggregation: boolean, if True, the object will be aggregated with other objects in the list of objects.
|
|
58
|
+
# Meaning, that the object will be checked against the existing objects in the list, and if it is not
|
|
59
|
+
# in the list, it will be added to the list. If it is in the list, it will be ignored.
|
|
60
60
|
:param input_file_path: string, full file path for storing input file for current state of objects,
|
|
61
61
|
to check later if this state isn't updated. If this variable is left empty, all the content will be saved
|
|
62
62
|
in memory and input file will not be used.
|
|
@@ -143,6 +143,111 @@ def thread_worker_main(
|
|
|
143
143
|
|
|
144
144
|
network_logger.info("Thread Finished. Will continue listening on the Main thread")
|
|
145
145
|
|
|
146
|
+
def process_client_raw_data_request() -> bool:
|
|
147
|
+
"""
|
|
148
|
+
Process the client raw data request.
|
|
149
|
+
|
|
150
|
+
:return: True if the socket should be closed, False if not.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
# If the message is empty, then the connection was closed already by the other side,
|
|
154
|
+
# so we can close the socket as well.
|
|
155
|
+
# If the received message from the client is not empty, then continue.
|
|
156
|
+
if not client_received_raw_data:
|
|
157
|
+
return True
|
|
158
|
+
|
|
159
|
+
# Putting the received message to the aggregating message class.
|
|
160
|
+
client_message.request_raw_bytes = client_received_raw_data
|
|
161
|
+
|
|
162
|
+
parse_http()
|
|
163
|
+
if protocol != '':
|
|
164
|
+
client_message.protocol = protocol
|
|
165
|
+
|
|
166
|
+
# Parse websocket frames only if it is not the first protocol upgrade request.
|
|
167
|
+
if protocol == 'Websocket' and cycle_count != 0:
|
|
168
|
+
client_message.request_raw_decoded = parse_websocket(client_message.request_raw_bytes)
|
|
169
|
+
|
|
170
|
+
# Custom parser, should parse HTTP body or the whole message if not HTTP.
|
|
171
|
+
parser_instance = parser(client_message)
|
|
172
|
+
parser_instance.parse()
|
|
173
|
+
|
|
174
|
+
# Converting body parsed to string on logging, since there is no strict rule for the parameter
|
|
175
|
+
# to be string.
|
|
176
|
+
parser_instance.logger.info(f"{str(client_message.request_body_parsed)[0: 100]}...")
|
|
177
|
+
|
|
178
|
+
return False
|
|
179
|
+
|
|
180
|
+
def create_responder_response():
|
|
181
|
+
# Since we're in response mode, we'll record the request anyway, after the responder did its job.
|
|
182
|
+
client_message.info = "In Server Response Mode"
|
|
183
|
+
|
|
184
|
+
# Re-initiate the 'client_message.response_list_of_raw_bytes' list, since we'll be appending
|
|
185
|
+
# new entries for empty list.
|
|
186
|
+
client_message.response_list_of_raw_bytes = list()
|
|
187
|
+
|
|
188
|
+
# If it's the first cycle and the protocol is Websocket, then we'll create the HTTP Handshake
|
|
189
|
+
# response automatically.
|
|
190
|
+
if protocol == 'Websocket' and cycle_count == 0:
|
|
191
|
+
client_message.response_list_of_raw_bytes.append(
|
|
192
|
+
websocket_parse.create_byte_http_response(client_message.request_raw_bytes))
|
|
193
|
+
# Creating response for parsed message and printing
|
|
194
|
+
responder.create_response(client_message)
|
|
195
|
+
|
|
196
|
+
# Output first 100 characters of all the responses in the list.
|
|
197
|
+
for response_raw_bytes_single in client_message.response_list_of_raw_bytes:
|
|
198
|
+
responder.logger.info(f"{response_raw_bytes_single[0: 100]}...")
|
|
199
|
+
|
|
200
|
+
def create_client_socket():
|
|
201
|
+
# If we're on localhost, then use external services list in order to resolve the domain:
|
|
202
|
+
# config['tcp']['forwarding_dns_service_ipv4_list___only_for_localhost']
|
|
203
|
+
if client_message.client_ip in base.THIS_DEVICE_IP_LIST:
|
|
204
|
+
service_client_instance = socket_client.SocketClient(
|
|
205
|
+
service_name=client_message.server_name, service_port=client_message.destination_port,
|
|
206
|
+
tls=is_tls,
|
|
207
|
+
dns_servers_list=(
|
|
208
|
+
config_static.TCPServer.forwarding_dns_service_ipv4_list___only_for_localhost),
|
|
209
|
+
logger=network_logger
|
|
210
|
+
)
|
|
211
|
+
# If we're not on localhost, then connect to domain directly.
|
|
212
|
+
else:
|
|
213
|
+
service_client_instance = socket_client.SocketClient(
|
|
214
|
+
service_name=client_message.server_name, service_port=client_message.destination_port,
|
|
215
|
+
tls=is_tls, logger=network_logger)
|
|
216
|
+
|
|
217
|
+
return service_client_instance
|
|
218
|
+
|
|
219
|
+
def process_received_response_from_service_client():
|
|
220
|
+
if client_message.error is not None:
|
|
221
|
+
statistics_error_list.append(client_message.error)
|
|
222
|
+
|
|
223
|
+
# Since we need a list for raw bytes, we'll add the 'response_raw_bytes' to our list object.
|
|
224
|
+
# But we need to re-initiate it first.
|
|
225
|
+
client_message.response_list_of_raw_bytes = list()
|
|
226
|
+
# If there was error during send or receive from the service and response was None,
|
|
227
|
+
# It means that there was no response at all because of the error.
|
|
228
|
+
if client_message.error and response_raw_bytes is None:
|
|
229
|
+
client_message.response_list_of_raw_bytes.append(None)
|
|
230
|
+
# If there was no error, but response came empty, it means that the service has closed the
|
|
231
|
+
# socket after it received the request, without sending any data.
|
|
232
|
+
elif client_message.error is None and response_raw_bytes is None:
|
|
233
|
+
client_message.response_list_of_raw_bytes.append("")
|
|
234
|
+
else:
|
|
235
|
+
client_message.response_list_of_raw_bytes.append(response_raw_bytes)
|
|
236
|
+
|
|
237
|
+
client_message.response_list_of_raw_decoded = list()
|
|
238
|
+
# Make HTTP Response parsing only if there was response at all.
|
|
239
|
+
if response_raw_bytes:
|
|
240
|
+
response_raw_decoded, is_http_response, response_parsing_error = (
|
|
241
|
+
HTTPResponseParse(response_raw_bytes).parse())
|
|
242
|
+
|
|
243
|
+
if is_http_response:
|
|
244
|
+
client_message.response_list_of_raw_decoded.append(response_raw_decoded)
|
|
245
|
+
elif protocol == 'Websocket' and cycle_count != 0:
|
|
246
|
+
response_decoded = parse_websocket(response_raw_bytes)
|
|
247
|
+
client_message.response_list_of_raw_decoded.append(response_decoded)
|
|
248
|
+
else:
|
|
249
|
+
client_message.response_list_of_raw_decoded.append(None)
|
|
250
|
+
|
|
146
251
|
# Building client message object before the loop only for any exception to occurs, since we write it to
|
|
147
252
|
# recording file in its current state.
|
|
148
253
|
client_message: ClientMessage = ClientMessage()
|
|
@@ -191,6 +296,7 @@ def thread_worker_main(
|
|
|
191
296
|
network_logger.info(f"Thread Created - Client [{client_ip}:{source_port}] | "
|
|
192
297
|
f"Destination service: [{server_name}:{destination_port}]")
|
|
193
298
|
|
|
299
|
+
end_socket: bool = False
|
|
194
300
|
service_client = None
|
|
195
301
|
# Loop while received message is not empty, if so, close socket, since other side already closed.
|
|
196
302
|
# noinspection PyTypeChecker
|
|
@@ -217,79 +323,34 @@ def thread_worker_main(
|
|
|
217
323
|
# Getting current time of message received from client.
|
|
218
324
|
client_message.request_time_received = datetime.now()
|
|
219
325
|
|
|
220
|
-
|
|
221
|
-
#
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if client_received_raw_data:
|
|
229
|
-
# Putting the received message to the aggregating message class.
|
|
230
|
-
client_message.request_raw_bytes = client_received_raw_data
|
|
231
|
-
|
|
232
|
-
parse_http()
|
|
233
|
-
if protocol != '':
|
|
234
|
-
client_message.protocol = protocol
|
|
326
|
+
# Peek if there is some data in the socket.
|
|
327
|
+
# This is needed to check if the client just connects without sending data, if so we need to try and
|
|
328
|
+
# receive data from the server and send it to the client.
|
|
329
|
+
# We will do it only on the first cycle, after that the connection should work as usual.
|
|
330
|
+
# Sometimes the client will execute connection without sending data, just for the server to send response.
|
|
331
|
+
is_socket_ready: bool = True
|
|
332
|
+
if cycle_count == 0:
|
|
333
|
+
is_socket_ready = receiver.is_socket_ready_for_read(client_socket)
|
|
235
334
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
335
|
+
if is_socket_ready:
|
|
336
|
+
network_logger.info(f"Initializing Receiver on cycle: {str(cycle_count+1)}")
|
|
337
|
+
# Getting message from the client over the socket using specific class.
|
|
338
|
+
client_received_raw_data = receiver.Receiver(
|
|
339
|
+
ssl_socket=client_socket, logger=network_logger).receive()
|
|
239
340
|
|
|
240
|
-
|
|
241
|
-
parser_instance = parser(client_message)
|
|
242
|
-
parser_instance.parse()
|
|
243
|
-
|
|
244
|
-
# Converting body parsed to string on logging, since there is no strict rule for the parameter
|
|
245
|
-
# to be string.
|
|
246
|
-
parser_instance.logger.info(f"{str(client_message.request_body_parsed)[0: 100]}...")
|
|
341
|
+
end_socket = process_client_raw_data_request()
|
|
247
342
|
|
|
343
|
+
if not end_socket:
|
|
248
344
|
# If we're in response mode, execute responder.
|
|
249
345
|
response_raw_bytes = None
|
|
250
346
|
if config_static.TCPServer.server_response_mode:
|
|
251
|
-
|
|
252
|
-
client_message.info = "In Server Response Mode"
|
|
253
|
-
|
|
254
|
-
# Re-initiate the 'client_message.response_list_of_raw_bytes' list, since we'll be appending
|
|
255
|
-
# new entries for empty list.
|
|
256
|
-
client_message.response_list_of_raw_bytes = list()
|
|
257
|
-
|
|
258
|
-
# If it's the first cycle and the protocol is Websocket, then we'll create the HTTP Handshake
|
|
259
|
-
# response automatically.
|
|
260
|
-
if protocol == 'Websocket' and cycle_count == 0:
|
|
261
|
-
client_message.response_list_of_raw_bytes.append(
|
|
262
|
-
websocket_parse.create_byte_http_response(client_message.request_raw_bytes))
|
|
263
|
-
# Creating response for parsed message and printing
|
|
264
|
-
responder.create_response(client_message)
|
|
265
|
-
|
|
266
|
-
# Output first 100 characters of all the responses in the list.
|
|
267
|
-
for response_raw_bytes in client_message.response_list_of_raw_bytes:
|
|
268
|
-
if response_raw_bytes:
|
|
269
|
-
responder.logger.info(f"{response_raw_bytes[0: 100]}...")
|
|
270
|
-
else:
|
|
271
|
-
responder.logger.info(f"Response empty...")
|
|
347
|
+
create_responder_response()
|
|
272
348
|
# Else, we're not in response mode, then execute client connect and record section.
|
|
273
349
|
else:
|
|
274
350
|
# If "service_client" object is not defined, we'll define it.
|
|
275
|
-
# If it's defined, then
|
|
276
|
-
# domain.
|
|
351
|
+
# If it's defined, then there's still active "ssl_socket" with connection to the service domain.
|
|
277
352
|
if not service_client:
|
|
278
|
-
|
|
279
|
-
# config['tcp']['forwarding_dns_service_ipv4_list___only_for_localhost']
|
|
280
|
-
if client_message.client_ip in base.THIS_DEVICE_IP_LIST:
|
|
281
|
-
service_client = socket_client.SocketClient(
|
|
282
|
-
service_name=client_message.server_name, service_port=client_message.destination_port,
|
|
283
|
-
tls=is_tls,
|
|
284
|
-
dns_servers_list=(
|
|
285
|
-
config_static.TCPServer.forwarding_dns_service_ipv4_list___only_for_localhost),
|
|
286
|
-
logger=network_logger
|
|
287
|
-
)
|
|
288
|
-
# If we're not on localhost, then connect to domain directly.
|
|
289
|
-
else:
|
|
290
|
-
service_client = socket_client.SocketClient(
|
|
291
|
-
service_name=client_message.server_name, service_port=client_message.destination_port,
|
|
292
|
-
tls=is_tls, logger=network_logger)
|
|
353
|
+
service_client = create_client_socket()
|
|
293
354
|
|
|
294
355
|
# Sending current client message and receiving a response.
|
|
295
356
|
# If there was an error it will be passed to "client_message" object class and if not, "None" will
|
|
@@ -297,40 +358,9 @@ def thread_worker_main(
|
|
|
297
358
|
# If there was connection error or socket close, then "ssl_socket" of the "service_client"
|
|
298
359
|
# will be empty.
|
|
299
360
|
response_raw_bytes, client_message.error, client_message.server_ip, service_ssl_socket = (
|
|
300
|
-
service_client.send_receive_to_service(client_message.request_raw_bytes))
|
|
301
|
-
|
|
302
|
-
if client_message.error is not None:
|
|
303
|
-
statistics_error_list.append(client_message.error)
|
|
304
|
-
|
|
305
|
-
# Since we need a list for raw bytes, we'll add the 'response_raw_bytes' to our list object.
|
|
306
|
-
# But we need to re-initiate it first.
|
|
307
|
-
client_message.response_list_of_raw_bytes = list()
|
|
308
|
-
# If there was error during send or receive from the service and response was None,
|
|
309
|
-
# It means that there was no response at all because of the error.
|
|
310
|
-
if client_message.error and response_raw_bytes is None:
|
|
311
|
-
client_message.response_list_of_raw_bytes.append(None)
|
|
312
|
-
# If there was no error, but response came empty, it means that the service has closed the
|
|
313
|
-
# socket after it received the request, without sending any data.
|
|
314
|
-
elif client_message.error is None and response_raw_bytes is None:
|
|
315
|
-
client_message.response_list_of_raw_bytes.append("")
|
|
316
|
-
else:
|
|
317
|
-
client_message.response_list_of_raw_bytes.append(response_raw_bytes)
|
|
318
|
-
|
|
319
|
-
client_message.response_list_of_raw_decoded = list()
|
|
320
|
-
# Make HTTP Response parsing only if there was response at all.
|
|
321
|
-
if response_raw_bytes:
|
|
322
|
-
response_raw_decoded, is_http_response, response_parsing_error = (
|
|
323
|
-
HTTPResponseParse(response_raw_bytes).parse())
|
|
324
|
-
|
|
325
|
-
if is_http_response:
|
|
326
|
-
client_message.response_list_of_raw_decoded.append(response_raw_decoded)
|
|
327
|
-
elif protocol == 'Websocket' and cycle_count != 0:
|
|
328
|
-
response_decoded = parse_websocket(response_raw_bytes)
|
|
329
|
-
client_message.response_list_of_raw_decoded.append(response_decoded)
|
|
330
|
-
else:
|
|
331
|
-
client_message.response_list_of_raw_decoded.append(None)
|
|
332
|
-
|
|
361
|
+
service_client.send_receive_to_service(client_message.request_raw_bytes, (not is_socket_ready)))
|
|
333
362
|
|
|
363
|
+
process_received_response_from_service_client()
|
|
334
364
|
|
|
335
365
|
# So if the socket was closed and there was an error we can break the loop
|
|
336
366
|
if not service_ssl_socket:
|
|
@@ -338,8 +368,8 @@ def thread_worker_main(
|
|
|
338
368
|
recorded = True
|
|
339
369
|
break
|
|
340
370
|
|
|
341
|
-
# If there is a response, then send it.
|
|
342
|
-
if
|
|
371
|
+
# If there is a response(s), then send it.
|
|
372
|
+
if client_message.response_list_of_raw_bytes:
|
|
343
373
|
# Sending response/s to client no matter if in record mode or not.
|
|
344
374
|
network_logger.info(
|
|
345
375
|
f"Sending messages to client: {len(client_message.response_list_of_raw_bytes)}")
|
|
@@ -362,7 +392,10 @@ def thread_worker_main(
|
|
|
362
392
|
|
|
363
393
|
record_and_statistics_write()
|
|
364
394
|
recorded = True
|
|
365
|
-
|
|
395
|
+
|
|
396
|
+
# If the message is empty, then the connection was closed already by the other side, also if there will
|
|
397
|
+
# be empty response from the server, so we can close the socket as well and exceptions will be raised.
|
|
398
|
+
if end_socket:
|
|
366
399
|
# If it's the first cycle we will record the message from the client if it came empty.
|
|
367
400
|
if cycle_count == 0:
|
|
368
401
|
record_and_statistics_write()
|
|
@@ -370,6 +403,7 @@ def thread_worker_main(
|
|
|
370
403
|
# In other cases, we'll just break the loop, since empty message means that the other side closed the
|
|
371
404
|
# connection.
|
|
372
405
|
recorded = True
|
|
406
|
+
|
|
373
407
|
break
|
|
374
408
|
|
|
375
409
|
finish_thread()
|
|
@@ -5,12 +5,9 @@ from pathlib import Path
|
|
|
5
5
|
from .. import filesystem
|
|
6
6
|
from ..file_io import tomls
|
|
7
7
|
from ..basics.classes import import_first_class_name_from_file_path
|
|
8
|
-
from ..wrappers.loggingw import loggingw
|
|
9
8
|
from .engines.__reference_general import parser___reference_general, responder___reference_general, \
|
|
10
9
|
recorder___reference_general
|
|
11
10
|
|
|
12
|
-
from . import config_static
|
|
13
|
-
|
|
14
11
|
|
|
15
12
|
class ModuleCategory:
|
|
16
13
|
def __init__(self, script_directory: str):
|
atomicshop/mitm/recs_files.py
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import google.generativeai as genai
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GoogleLLM:
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
llm_api_key: str
|
|
10
|
+
) -> None:
|
|
11
|
+
self.genai = genai
|
|
12
|
+
|
|
13
|
+
os.environ["API_KEY"] = llm_api_key
|
|
14
|
+
genai.configure(api_key=os.environ["API_KEY"])
|
|
15
|
+
|
|
16
|
+
def get_current_models(self) -> list[str]:
|
|
17
|
+
""" Function to get the current models available in the Gemini API """
|
|
18
|
+
result_list: list[str] = []
|
|
19
|
+
for model in self.genai.list_models():
|
|
20
|
+
result_list.append(model.name)
|
|
21
|
+
|
|
22
|
+
return result_list
|
|
23
|
+
|
|
24
|
+
def get_answer_online(
|
|
25
|
+
self,
|
|
26
|
+
search_query: str,
|
|
27
|
+
additional_llm_instructions: str,
|
|
28
|
+
number_of_top_links: int = 2,
|
|
29
|
+
number_of_characters_per_link: int = 15000,
|
|
30
|
+
temperature: float = 0,
|
|
31
|
+
max_output_tokens: int = 4096
|
|
32
|
+
):
|
|
33
|
+
"""
|
|
34
|
+
Function to get the answer to a question by searching Google Custom Console API and processing the content using Gemini API.
|
|
35
|
+
:param search_query:
|
|
36
|
+
:param additional_llm_instructions:
|
|
37
|
+
:param number_of_top_links:
|
|
38
|
+
:param number_of_characters_per_link:
|
|
39
|
+
:param temperature:
|
|
40
|
+
:param max_output_tokens:
|
|
41
|
+
:return:
|
|
42
|
+
"""
|
|
@@ -40,8 +40,7 @@ def install_fibratus(
|
|
|
40
40
|
exclude_string='slim')
|
|
41
41
|
|
|
42
42
|
# Install the MSI file
|
|
43
|
-
msiw.install_msi(
|
|
44
|
-
msi_path=fibratus_setup_file_path, exit_on_error=True, as_admin=True)
|
|
43
|
+
msiw.install_msi(msi_path=fibratus_setup_file_path)
|
|
45
44
|
|
|
46
45
|
count = 0
|
|
47
46
|
while count != WAIT_SECONDS_FOR_EXECUTABLE_TO_APPEAR_AFTER_INSTALLATION:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import socket
|
|
3
3
|
import ssl
|
|
4
|
+
import select
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
|
|
6
7
|
from ...print_api import print_api
|
|
@@ -20,6 +21,24 @@ def peek_first_bytes(client_socket, bytes_amount: int = 1) -> bytes:
|
|
|
20
21
|
return client_socket.recv(bytes_amount, socket.MSG_PEEK)
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
def is_socket_ready_for_read(client_socket, timeout: int = 0) -> bool:
|
|
25
|
+
"""
|
|
26
|
+
Check if socket is ready for read.
|
|
27
|
+
|
|
28
|
+
:param client_socket: Socket object.
|
|
29
|
+
:param timeout: Timeout in seconds. The default is no timeout.
|
|
30
|
+
|
|
31
|
+
:return: True if socket is ready for read, False otherwise.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
# Use select to check if the socket is ready for reading.
|
|
35
|
+
# 'readable' returns a list of sockets that are ready for reading.
|
|
36
|
+
# Since we use only one socket, it will return a list with one element if the socket is ready for reading,
|
|
37
|
+
# or an empty list if the socket is not ready for reading.
|
|
38
|
+
readable, _, _ = select.select([client_socket], [], [], timeout)
|
|
39
|
+
return bool(readable)
|
|
40
|
+
|
|
41
|
+
|
|
23
42
|
class Receiver:
|
|
24
43
|
""" Receiver Class is responsible for receiving the message from socket and populate the message class """
|
|
25
44
|
def __init__(
|
|
@@ -254,15 +254,13 @@ class SNIHandler:
|
|
|
254
254
|
|
|
255
255
|
# Try on general settings in the SNI function.
|
|
256
256
|
try:
|
|
257
|
-
# Check if SNI was passed.
|
|
258
|
-
if self.sni_received_parameters.destination_name:
|
|
259
|
-
service_name_from_sni = self.sni_received_parameters.destination_name
|
|
260
|
-
# If no SNI was passed.
|
|
261
|
-
else:
|
|
257
|
+
# Check if SNI was passed. If no SNI was passed.
|
|
258
|
+
if not self.sni_received_parameters.destination_name:
|
|
262
259
|
# If DNS server is enabled we'll get the domain from dns server.
|
|
263
260
|
if self.domain_from_dns_server:
|
|
264
|
-
|
|
265
|
-
message =
|
|
261
|
+
self.sni_received_parameters.destination_name = self.domain_from_dns_server
|
|
262
|
+
message = \
|
|
263
|
+
f"SNI Handler: No SNI was passed, using domain from DNS Server: {self.domain_from_dns_server}"
|
|
266
264
|
print_api(message, **(print_kwargs or {}))
|
|
267
265
|
# If DNS server is disabled, the domain from dns server will be empty.
|
|
268
266
|
else:
|
|
@@ -271,7 +269,7 @@ class SNIHandler:
|
|
|
271
269
|
print_api(message, **(print_kwargs or {}))
|
|
272
270
|
|
|
273
271
|
# Setting "server_hostname" as a domain.
|
|
274
|
-
self.sni_received_parameters.ssl_socket.server_hostname =
|
|
272
|
+
self.sni_received_parameters.ssl_socket.server_hostname = self.sni_received_parameters.destination_name
|
|
275
273
|
message = \
|
|
276
274
|
f"SNI Handler: port {self.sni_received_parameters.ssl_socket.getsockname()[1]}: " \
|
|
277
275
|
f"Incoming connection for [{self.sni_received_parameters.ssl_socket.server_hostname}]"
|
|
@@ -163,7 +163,7 @@ class SocketClient:
|
|
|
163
163
|
error_string: str = f"Socket Client Connect: {destination}: {exception_type}"
|
|
164
164
|
|
|
165
165
|
if exception_type in ['ConnectionRefusedError', 'ConnectionAbortedError', 'ConnectionResetError',
|
|
166
|
-
'
|
|
166
|
+
'TimeoutError'] or 'ssl' in exception_type.lower():
|
|
167
167
|
error_message: str = f"{error_string}: {exception_error}"
|
|
168
168
|
print_api(error_message, logger=self.logger, logger_method='error')
|
|
169
169
|
return None, error_message
|
|
@@ -192,7 +192,18 @@ class SocketClient:
|
|
|
192
192
|
self.logger.info(f"Closed socket to service server [{self.service_name}:{self.service_port}]")
|
|
193
193
|
|
|
194
194
|
# noinspection PyUnusedLocal
|
|
195
|
-
def send_receive_to_service(
|
|
195
|
+
def send_receive_to_service(
|
|
196
|
+
self,
|
|
197
|
+
request_bytes: Union[bytearray, bytes],
|
|
198
|
+
skip_send: bool = False
|
|
199
|
+
):
|
|
200
|
+
"""
|
|
201
|
+
Function to send data to service server and receive response.
|
|
202
|
+
|
|
203
|
+
:param request_bytes: The data that will be sent to the service server.
|
|
204
|
+
:param skip_send: If True, the data will not be sent to the service server. After the connection is established,
|
|
205
|
+
the function will wait for the response only.
|
|
206
|
+
"""
|
|
196
207
|
# Define variables
|
|
197
208
|
function_service_data = None
|
|
198
209
|
error_message = None
|
|
@@ -214,18 +225,22 @@ class SocketClient:
|
|
|
214
225
|
self.logger.info(
|
|
215
226
|
f"[{self.service_name}] resolves to ip: [{self.connection_ip}]. Pulled IP from the socket.")
|
|
216
227
|
|
|
217
|
-
#
|
|
218
|
-
error_on_send: str =
|
|
219
|
-
|
|
228
|
+
# noinspection PyTypeChecker
|
|
229
|
+
error_on_send: str = None
|
|
230
|
+
if not skip_send:
|
|
231
|
+
# Send the data received from the client to the service over socket
|
|
232
|
+
error_on_send = Sender(
|
|
233
|
+
ssl_socket=self.socket_instance, class_message=request_bytes, logger=self.logger).send()
|
|
220
234
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
235
|
+
# If the socket disconnected on data send
|
|
236
|
+
if error_on_send:
|
|
237
|
+
error_message = f"Service socket closed on data send: {error_on_send}"
|
|
238
|
+
|
|
239
|
+
# We'll close the socket and nullify the object
|
|
240
|
+
self.close_socket()
|
|
224
241
|
|
|
225
|
-
# We'll close the socket and nullify the object
|
|
226
|
-
self.close_socket()
|
|
227
242
|
# Else if send was successful
|
|
228
|
-
|
|
243
|
+
if not error_on_send:
|
|
229
244
|
function_service_data = Receiver(
|
|
230
245
|
ssl_socket=self.socket_instance, logger=self.logger).receive()
|
|
231
246
|
|
atomicshop/wrappers/sysmonw.py
CHANGED
|
@@ -49,7 +49,7 @@ def is_sysmon_running():
|
|
|
49
49
|
"""
|
|
50
50
|
|
|
51
51
|
process_list: list = process.get_running_processes_by_cmdline_pattern(
|
|
52
|
-
pattern=SYSMON_FILE_NAME, first=True,
|
|
52
|
+
pattern=SYSMON_FILE_NAME, first=True, cmdline_case_insensitive=True)
|
|
53
53
|
|
|
54
54
|
if process_list:
|
|
55
55
|
return True
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=g4si8ZVmv-cmrXDPNTeEfgvWGFAXNNlfF5E-_j8xNMo,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
|
|
@@ -9,7 +9,7 @@ atomicshop/config_init.py,sha256=50kD2lXP8sgwPekcmAbfADcY46YvXkF-6XIdA7W_638,250
|
|
|
9
9
|
atomicshop/console_output.py,sha256=AOSJjrRryE97PAGtgDL03IBtWSi02aNol8noDnW3k6M,4667
|
|
10
10
|
atomicshop/console_user_response.py,sha256=31HIy9QGXa7f-GVR8MzJauQ79E_ZqAeagF3Ks4GGdDU,3234
|
|
11
11
|
atomicshop/datetimes.py,sha256=IQZ66lmta-ZqxYbyHzm_9eugbJFSilXK1e0kfMgoXGg,18371
|
|
12
|
-
atomicshop/diff_check.py,sha256=
|
|
12
|
+
atomicshop/diff_check.py,sha256=vxTDccVbGZHEge6Ja9_ArLWwslOUgIoJAdYPylh4cZg,27176
|
|
13
13
|
atomicshop/dns.py,sha256=5Gimq_WY2arqg7BeGmR7P--fGfnH0Dsh8lrOt_H0jRY,6817
|
|
14
14
|
atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
|
|
15
15
|
atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
|
|
@@ -126,13 +126,13 @@ atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,21
|
|
|
126
126
|
atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
127
127
|
atomicshop/mitm/config_static.py,sha256=ROAtbibSWSsF3BraUbhu-QO3MPIFqYY5KUKgsQbiSkk,7813
|
|
128
128
|
atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
|
|
129
|
-
atomicshop/mitm/connection_thread_worker.py,sha256=
|
|
129
|
+
atomicshop/mitm/connection_thread_worker.py,sha256=vfFClzwDfaoT4zHCOfky4DnEDoSonp9N1MCj62dS9Nk,20451
|
|
130
130
|
atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
|
|
131
|
-
atomicshop/mitm/initialize_engines.py,sha256=
|
|
131
|
+
atomicshop/mitm/initialize_engines.py,sha256=Naseof9JGY7oxDz9ueOyW7-KYTu7QDlFxv2ABqq9DD4,8219
|
|
132
132
|
atomicshop/mitm/message.py,sha256=URR5JKSuAT8XmGIkyprEjlPW2GW4ef_gfUz_GgcFseE,2184
|
|
133
133
|
atomicshop/mitm/mitm_main.py,sha256=5c-9oxBiLueTbZr4Dyd4EEOorEUix5vSWxX9p5O1fBs,23375
|
|
134
|
-
atomicshop/mitm/recs_files.py,sha256=
|
|
135
|
-
atomicshop/mitm/shared_functions.py,sha256=
|
|
134
|
+
atomicshop/mitm/recs_files.py,sha256=gzFuTonqcXkMvhpOj1Nwse3E8umFGrKN2H5AleMjJ3w,3051
|
|
135
|
+
atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
|
|
136
136
|
atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
|
|
137
137
|
atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
138
138
|
atomicshop/mitm/engines/create_module_template.py,sha256=tRjVSm1sD6FzML71Qbuwvita0qsusdFGm8NZLsZ-XMs,4853
|
|
@@ -175,6 +175,9 @@ atomicshop/startup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
|
175
175
|
atomicshop/startup/win/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
176
176
|
atomicshop/startup/win/startup_folder.py,sha256=2RZEyF-Mf8eWPlt_-OaoGKKnMs6YhELEzJZ376EI0E0,1891
|
|
177
177
|
atomicshop/startup/win/task_scheduler.py,sha256=qALe-8sfthYxsdCViH2r8OsH3x-WauDqteg5RzElPdk,4348
|
|
178
|
+
atomicshop/web_apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
179
|
+
atomicshop/web_apis/google_custom_search.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
180
|
+
atomicshop/web_apis/google_llm.py,sha256=WVLqyfZHFIGEncxdBvrHCv2FbvQw40z75uMGzq9lxB4,1291
|
|
178
181
|
atomicshop/wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
179
182
|
atomicshop/wrappers/_process_wrapper_curl.py,sha256=XkZZXYl7D0Q6UfdWqy-18AvpU0yVp9i2BVD2qRcXlkk,841
|
|
180
183
|
atomicshop/wrappers/_process_wrapper_tar.py,sha256=WUMZFKNrlG4nJP9tWZ51W7BR1j_pIjsjgyAStmWjRGs,655
|
|
@@ -189,7 +192,7 @@ atomicshop/wrappers/olefilew.py,sha256=biD5m58rogifCYmYhJBrAFb9O_Bn_spLek_9HofLe
|
|
|
189
192
|
atomicshop/wrappers/pipw.py,sha256=mu4jnHkSaYNfpBiLZKMZxEX_E2LqW5BVthMZkblPB_c,1317
|
|
190
193
|
atomicshop/wrappers/process_wrapper_pbtk.py,sha256=ycPmBRnv627RWks6N8OhxJQe8Gu3h3Vwj-4HswPOw0k,599
|
|
191
194
|
atomicshop/wrappers/pyopensslw.py,sha256=OBWxA6EJ2vU_Qlf4M8m6ilcG3hyYB4yB0EsXUf7NhEU,6804
|
|
192
|
-
atomicshop/wrappers/sysmonw.py,sha256=
|
|
195
|
+
atomicshop/wrappers/sysmonw.py,sha256=CdawuWuy_uUi3ALCm6lKP7pSyKeTk1MXyzOaTMbBSO8,5346
|
|
193
196
|
atomicshop/wrappers/ubuntu_terminal.py,sha256=3UJaje_Ke5G9xEyj3b37XZ_KjR_FSSnb4gupdCyI-jE,11965
|
|
194
197
|
atomicshop/wrappers/wslw.py,sha256=2Z7X0j5M2hoRZjbHfm_vqwNXZeptsdkNCdhdcM_S9vo,6998
|
|
195
198
|
atomicshop/wrappers/certauthw/certauth.py,sha256=hKedW0DOWlEigSNm8wu4SqHkCQsGJ1tJfH7s4nr3Bk0,12223
|
|
@@ -246,7 +249,7 @@ atomicshop/wrappers/factw/rest/router.py,sha256=fdGok5ESBxcZHIBgM93l4yTPRGoeooQN
|
|
|
246
249
|
atomicshop/wrappers/factw/rest/statistics.py,sha256=vznwzKP1gEF7uXz3HsuV66BU9wrp73N_eFqpFpye9Qw,653
|
|
247
250
|
atomicshop/wrappers/factw/rest/status.py,sha256=4O3xS1poafwyUiLDkhyx4oMMe4PBwABuRPpOMnMKgIU,641
|
|
248
251
|
atomicshop/wrappers/fibratusw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
249
|
-
atomicshop/wrappers/fibratusw/install.py,sha256=
|
|
252
|
+
atomicshop/wrappers/fibratusw/install.py,sha256=GnaAAqcXRhovxZ3x5uB9RAXTMCh5xd5k1niCKTzh4Z0,3242
|
|
250
253
|
atomicshop/wrappers/loggingw/consts.py,sha256=JWiUJEydjhwatBxtIJsGTmDUSTLbmIRidtR6qRLMaIY,1608
|
|
251
254
|
atomicshop/wrappers/loggingw/filters.py,sha256=48UVhJHemCS0agXmQP8dHvAHM8r9DFphJ1TNEBP3Dlg,3545
|
|
252
255
|
atomicshop/wrappers/loggingw/formatters.py,sha256=ZY12IokVY1G_Wzn2Zlv9qjK-e8CtIK6yUgUfPHvH2BU,5802
|
|
@@ -305,18 +308,18 @@ atomicshop/wrappers/socketw/creator.py,sha256=3_OraDkw2DAWZfoSdY3svCGMOIxpjLEEY7
|
|
|
305
308
|
atomicshop/wrappers/socketw/dns_server.py,sha256=RklzINNuoMQn4PGGQEI5hiAldprbVwwvikY6u9X-jTY,49067
|
|
306
309
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=B-X5SHLSUIWToihH2MKnOB1F4A81_X0DpLLfnYKYbEc,7067
|
|
307
310
|
atomicshop/wrappers/socketw/get_process.py,sha256=aJC-_qFUv3NgWCSUzDI72E4z8_-VTZE9NVZ0CwUoNlM,5698
|
|
308
|
-
atomicshop/wrappers/socketw/receiver.py,sha256
|
|
309
|
-
atomicshop/wrappers/socketw/sender.py,sha256=
|
|
310
|
-
atomicshop/wrappers/socketw/sni.py,sha256=
|
|
311
|
-
atomicshop/wrappers/socketw/socket_client.py,sha256=
|
|
311
|
+
atomicshop/wrappers/socketw/receiver.py,sha256=-QtKK0T_lmoAIypTYaIKOD3pgB1npWGPxcVEN37y_gk,10060
|
|
312
|
+
atomicshop/wrappers/socketw/sender.py,sha256=gwSzF51QD5paeeFav6fpbQpO8KgBO5lNztHYQyN5id0,4959
|
|
313
|
+
atomicshop/wrappers/socketw/sni.py,sha256=Nc8WMZZR21o5GXILQLVWbf7OzNPXAfE8trJY153e9Qk,17591
|
|
314
|
+
atomicshop/wrappers/socketw/socket_client.py,sha256=9_VXXo8r4upP5v0Rhzx7dJIblM23_0Ggh2PfktYj-fE,20489
|
|
312
315
|
atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
|
|
313
316
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9Exd4j3qhDXcFc74-E,35567
|
|
314
317
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
|
|
315
318
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=SDYI1cN0oaapvPeLxSXiJrelTy6xbZl-bopR0jAjVGE,3149
|
|
316
319
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
317
320
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=zZQfps-CdODQaTUADbHAwKHr5RUg7BLafnKWBbKaLN4,8728
|
|
318
|
-
atomicshop-2.16.
|
|
319
|
-
atomicshop-2.16.
|
|
320
|
-
atomicshop-2.16.
|
|
321
|
-
atomicshop-2.16.
|
|
322
|
-
atomicshop-2.16.
|
|
321
|
+
atomicshop-2.16.48.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
322
|
+
atomicshop-2.16.48.dist-info/METADATA,sha256=zxLRU6GxTBO675CZCx48ARUCy2CYk9CTkD-0jhyE3AQ,10500
|
|
323
|
+
atomicshop-2.16.48.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
324
|
+
atomicshop-2.16.48.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
325
|
+
atomicshop-2.16.48.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|