atomicshop 2.18.0__py3-none-any.whl → 2.18.1__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/mitm/config_static.py +1 -1
- atomicshop/mitm/connection_thread_worker.py +77 -32
- atomicshop/mitm/message.py +2 -0
- atomicshop/wrappers/socketw/statistics_csv.py +5 -2
- {atomicshop-2.18.0.dist-info → atomicshop-2.18.1.dist-info}/METADATA +1 -1
- {atomicshop-2.18.0.dist-info → atomicshop-2.18.1.dist-info}/RECORD +10 -10
- {atomicshop-2.18.0.dist-info → atomicshop-2.18.1.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.18.0.dist-info → atomicshop-2.18.1.dist-info}/WHEEL +0 -0
- {atomicshop-2.18.0.dist-info → atomicshop-2.18.1.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/mitm/config_static.py
CHANGED
|
@@ -72,6 +72,7 @@ def thread_worker_main(
|
|
|
72
72
|
tls_version=tls_version,
|
|
73
73
|
protocol=client_message.protocol,
|
|
74
74
|
protocol2=client_message.protocol2,
|
|
75
|
+
protocol3=client_message.protocol3,
|
|
75
76
|
path=http_path,
|
|
76
77
|
status_code=http_status_code,
|
|
77
78
|
command=http_command,
|
|
@@ -97,6 +98,8 @@ def thread_worker_main(
|
|
|
97
98
|
raw_bytes: bytes,
|
|
98
99
|
client_message: ClientMessage):
|
|
99
100
|
nonlocal protocol
|
|
101
|
+
nonlocal protocol3
|
|
102
|
+
|
|
100
103
|
# Parsing the raw bytes as HTTP.
|
|
101
104
|
request_http_parsed, is_http_request, request_parsing_error = (
|
|
102
105
|
HTTPRequestParse(raw_bytes).parse())
|
|
@@ -117,9 +120,14 @@ def thread_worker_main(
|
|
|
117
120
|
auto_parsed = response_http_parsed
|
|
118
121
|
network_logger.info(
|
|
119
122
|
f"HTTP Response Parsed: Status: {response_http_parsed.code}")
|
|
123
|
+
protocol3 = auto_parsed.headers.get('Sec-WebSocket-Protocol', None)
|
|
124
|
+
if protocol3:
|
|
125
|
+
client_message.protocol3 = protocol3
|
|
120
126
|
elif protocol == 'Websocket':
|
|
121
127
|
client_message.protocol2 = 'Frame'
|
|
122
128
|
auto_parsed = parse_websocket(raw_bytes)
|
|
129
|
+
if protocol3:
|
|
130
|
+
client_message.protocol3 = protocol3
|
|
123
131
|
else:
|
|
124
132
|
auto_parsed = None
|
|
125
133
|
|
|
@@ -276,6 +284,36 @@ def thread_worker_main(
|
|
|
276
284
|
|
|
277
285
|
return client_message
|
|
278
286
|
|
|
287
|
+
def responder_thread_worker():
|
|
288
|
+
nonlocal exception_or_close_in_receiving_thread
|
|
289
|
+
|
|
290
|
+
client_message: ClientMessage = client_message_first_start()
|
|
291
|
+
try:
|
|
292
|
+
while True:
|
|
293
|
+
client_message = responder_queue.get()
|
|
294
|
+
raw_responses: list[bytes] = create_responder_response(client_message)
|
|
295
|
+
|
|
296
|
+
is_socket_closed: bool = False
|
|
297
|
+
for response_raw_bytes in raw_responses:
|
|
298
|
+
client_message.reinitialize_dynamic_vars()
|
|
299
|
+
client_message.timestamp = datetime.now()
|
|
300
|
+
client_message.response_raw_bytes = response_raw_bytes
|
|
301
|
+
error_on_send: str = sender.Sender(
|
|
302
|
+
ssl_socket=client_socket, class_message=client_message.response_raw_bytes,
|
|
303
|
+
logger=network_logger).send()
|
|
304
|
+
|
|
305
|
+
# If there was problem with sending data, we'll break the main while loop.
|
|
306
|
+
if error_on_send:
|
|
307
|
+
client_message.errors.append(error_on_send)
|
|
308
|
+
record_and_statistics_write(client_message)
|
|
309
|
+
is_socket_closed = True
|
|
310
|
+
|
|
311
|
+
if is_socket_closed:
|
|
312
|
+
exception_or_close_in_receiving_thread = True
|
|
313
|
+
return
|
|
314
|
+
except Exception as exc:
|
|
315
|
+
handle_exceptions_on_sub_connection_thread(client_message, client_exception_queue, exc)
|
|
316
|
+
|
|
279
317
|
def receive_send_start(
|
|
280
318
|
receiving_socket,
|
|
281
319
|
sending_socket = None,
|
|
@@ -346,26 +384,7 @@ def thread_worker_main(
|
|
|
346
384
|
|
|
347
385
|
# If we're in response mode, execute responder.
|
|
348
386
|
if config_static.TCPServer.server_response_mode:
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
is_socket_closed: bool = False
|
|
352
|
-
for response_raw_bytes in raw_responses:
|
|
353
|
-
client_message.reinitialize_dynamic_vars()
|
|
354
|
-
client_message.timestamp = datetime.now()
|
|
355
|
-
client_message.response_raw_bytes = response_raw_bytes
|
|
356
|
-
error_on_send: str = sender.Sender(
|
|
357
|
-
ssl_socket=client_socket, class_message=client_message.response_raw_bytes,
|
|
358
|
-
logger=network_logger).send()
|
|
359
|
-
|
|
360
|
-
# If there was problem with sending data, we'll break the main while loop.
|
|
361
|
-
if error_on_send:
|
|
362
|
-
client_message.errors.append(error_on_send)
|
|
363
|
-
record_and_statistics_write(client_message)
|
|
364
|
-
is_socket_closed = True
|
|
365
|
-
|
|
366
|
-
if is_socket_closed:
|
|
367
|
-
# exception_or_close_in_receiving_thread = True
|
|
368
|
-
return
|
|
387
|
+
responder_queue.put(client_message)
|
|
369
388
|
else:
|
|
370
389
|
# if side == 'Client':
|
|
371
390
|
# raise NotImplementedError
|
|
@@ -397,20 +416,30 @@ def thread_worker_main(
|
|
|
397
416
|
if isinstance(exc, OSError) and exc.errno == 10038:
|
|
398
417
|
print_api("Both sockets are closed, breaking the loop", logger=network_logger, logger_method='info')
|
|
399
418
|
else:
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
419
|
+
handle_exceptions_on_sub_connection_thread(client_message, exception_queue, exc)
|
|
420
|
+
|
|
421
|
+
def handle_exceptions_on_sub_connection_thread(
|
|
422
|
+
client_message: ClientMessage,
|
|
423
|
+
exception_queue: queue.Queue,
|
|
424
|
+
exc: Exception
|
|
425
|
+
):
|
|
426
|
+
nonlocal exception_or_close_in_receiving_thread
|
|
427
|
+
|
|
428
|
+
exception_or_close_in_receiving_thread=True
|
|
429
|
+
# handle_exceptions(exc, client_message, recorded)
|
|
430
|
+
exception_message = tracebacks.get_as_string(one_line=True)
|
|
406
431
|
|
|
407
|
-
|
|
408
|
-
|
|
432
|
+
error_message = f'Socket Thread [{str(thread_id)}] Exception: {exception_message}'
|
|
433
|
+
print_api("Exception in a thread, forwarding to parent thread.", logger_method='info', logger=network_logger)
|
|
434
|
+
client_message.errors.append(error_message)
|
|
409
435
|
|
|
410
|
-
|
|
411
|
-
|
|
436
|
+
# if not recorded:
|
|
437
|
+
# record_and_statistics_write(client_message)
|
|
438
|
+
|
|
439
|
+
finish_thread()
|
|
440
|
+
exception_queue.put(exc)
|
|
412
441
|
|
|
413
|
-
def
|
|
442
|
+
def handle_exceptions_on_main_connection_thread(
|
|
414
443
|
exc: Exception,
|
|
415
444
|
client_message: ClientMessage
|
|
416
445
|
):
|
|
@@ -441,7 +470,10 @@ def thread_worker_main(
|
|
|
441
470
|
|
|
442
471
|
thread_id = threads.current_thread_id()
|
|
443
472
|
|
|
473
|
+
# This is the main protocols.
|
|
444
474
|
protocol: str = str()
|
|
475
|
+
# This is the secondary protocol in the websocket.
|
|
476
|
+
protocol3: str = str()
|
|
445
477
|
# # This is Client Masked Frame Parser.
|
|
446
478
|
# websocket_masked_frame_parser = websocket_parse.WebsocketFrameParser()
|
|
447
479
|
# # This is Server UnMasked Frame Parser.
|
|
@@ -465,6 +497,8 @@ def thread_worker_main(
|
|
|
465
497
|
client_message_connection: ClientMessage = ClientMessage()
|
|
466
498
|
# This is needed to indicate if there was an exception or socket was closed in any of the receiving thread.
|
|
467
499
|
exception_or_close_in_receiving_thread: bool = False
|
|
500
|
+
# Responder queue for ClientMessage objects.
|
|
501
|
+
responder_queue: queue.Queue = queue.Queue()
|
|
468
502
|
|
|
469
503
|
try:
|
|
470
504
|
client_ip, source_port = client_socket.getpeername()
|
|
@@ -473,6 +507,12 @@ def thread_worker_main(
|
|
|
473
507
|
network_logger.info(f"Thread Created - Client [{client_ip}:{source_port}] | "
|
|
474
508
|
f"Destination service: [{server_name}:{destination_port}]")
|
|
475
509
|
|
|
510
|
+
# If we're in response mode, we'll start the responder thread.
|
|
511
|
+
if config_static.TCPServer.server_response_mode:
|
|
512
|
+
responder_thread: threading.Thread = threading.Thread(
|
|
513
|
+
target=responder_thread_worker, name=f"Thread-{thread_id}-Responder", daemon=True)
|
|
514
|
+
responder_thread.start()
|
|
515
|
+
|
|
476
516
|
service_client = None
|
|
477
517
|
client_receive_count: int = 0
|
|
478
518
|
server_receive_count: int = 0
|
|
@@ -488,6 +528,11 @@ def thread_worker_main(
|
|
|
488
528
|
if not service_client:
|
|
489
529
|
service_client = create_client_socket(client_message_connection)
|
|
490
530
|
service_socket_instance, connection_error = service_client.service_connection()
|
|
531
|
+
else:
|
|
532
|
+
client_message_connection.timestamp = datetime.now()
|
|
533
|
+
client_message_connection.action = 'service_connect'
|
|
534
|
+
client_message_connection.info = 'Server Response Mode'
|
|
535
|
+
responder_queue.put(client_message_connection)
|
|
491
536
|
|
|
492
537
|
if connection_error:
|
|
493
538
|
client_message_connection.timestamp = datetime.now()
|
|
@@ -524,4 +569,4 @@ def thread_worker_main(
|
|
|
524
569
|
if not client_message_connection.timestamp:
|
|
525
570
|
client_message_connection.timestamp = datetime.now()
|
|
526
571
|
|
|
527
|
-
|
|
572
|
+
handle_exceptions_on_main_connection_thread(e, client_message_connection)
|
atomicshop/mitm/message.py
CHANGED
|
@@ -31,6 +31,7 @@ class ClientMessage:
|
|
|
31
31
|
self.errors: list = list()
|
|
32
32
|
self.protocol: str = str()
|
|
33
33
|
self.protocol2: str = str()
|
|
34
|
+
self.protocol3: str = str()
|
|
34
35
|
self.recorded_file_path: str = str()
|
|
35
36
|
self.action: str = str()
|
|
36
37
|
|
|
@@ -52,6 +53,7 @@ class ClientMessage:
|
|
|
52
53
|
self.errors = list()
|
|
53
54
|
self.protocol = str()
|
|
54
55
|
self.protocol2 = str()
|
|
56
|
+
self.protocol3 = str()
|
|
55
57
|
self.recorded_file_path = str()
|
|
56
58
|
|
|
57
59
|
def __iter__(self):
|
|
@@ -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,protocol2,host,path,command,status_code,request_size_bytes,
|
|
10
|
-
'process_cmd,action,error')
|
|
9
|
+
'request_time_sent,thread_id,tls,protocol,protocol2,protocol3,host,path,command,status_code,request_size_bytes,'
|
|
10
|
+
'response_size_bytes,file_path,process_cmd,action,error')
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class StatisticsCSVWriter:
|
|
@@ -36,6 +36,7 @@ class StatisticsCSVWriter:
|
|
|
36
36
|
tls_version: str,
|
|
37
37
|
protocol: str,
|
|
38
38
|
protocol2: str,
|
|
39
|
+
protocol3: str,
|
|
39
40
|
path: str,
|
|
40
41
|
status_code: str,
|
|
41
42
|
command: str,
|
|
@@ -61,6 +62,7 @@ class StatisticsCSVWriter:
|
|
|
61
62
|
tls_info,
|
|
62
63
|
protocol,
|
|
63
64
|
protocol2,
|
|
65
|
+
protocol3,
|
|
64
66
|
host,
|
|
65
67
|
path,
|
|
66
68
|
command,
|
|
@@ -100,6 +102,7 @@ class StatisticsCSVWriter:
|
|
|
100
102
|
tls_version='',
|
|
101
103
|
protocol='',
|
|
102
104
|
protocol2='',
|
|
105
|
+
protocol3='',
|
|
103
106
|
path='',
|
|
104
107
|
status_code='',
|
|
105
108
|
command='',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=sd-5MCzdxJLvLvlvBmT3hqetHRPabTPPEglAUqrWUSo,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
|
|
@@ -125,12 +125,12 @@ atomicshop/file_io/tomls.py,sha256=ol8EvQPf9sryTmZUf1v55BYSUQ6ml7HVVBHpNKbsIlA,9
|
|
|
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=HIzxyMEj7DZksYvJsN5VuKpB-_HSVvuR6U59ztS9gi0,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=NHRa_f7k12JH9eDuGmr_-eCPRQVjO77RgCmLe9K2lWA,26073
|
|
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=
|
|
133
|
+
atomicshop/mitm/message.py,sha256=mNo4Lphr_Jo6IlNX5mPJzABpogWGkjOhwI4meAivwHw,2987
|
|
134
134
|
atomicshop/mitm/mitm_main.py,sha256=AxmqUiDHgfzqmIF8v2GZxlEKth6_AMaYcqAxziWMG0U,23430
|
|
135
135
|
atomicshop/mitm/recs_files.py,sha256=ZAAD0twun-FtmbSniXe3XQhIlawvANNB_HxwbHj7kwI,3151
|
|
136
136
|
atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
|
|
@@ -316,11 +316,11 @@ atomicshop/wrappers/socketw/socket_client.py,sha256=oa3GwS4OPgokrJE5_Oc4-5_wlXHx
|
|
|
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=fgMzDXI0cybwUEqAxprRmY3lqbh30KAV-jOpoFKT-m8,3395
|
|
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.18.
|
|
323
|
-
atomicshop-2.18.
|
|
324
|
-
atomicshop-2.18.
|
|
325
|
-
atomicshop-2.18.
|
|
326
|
-
atomicshop-2.18.
|
|
322
|
+
atomicshop-2.18.1.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
323
|
+
atomicshop-2.18.1.dist-info/METADATA,sha256=udb7ZbArHpKHBqBMXmBZbJw4FBWF0EVZeWc3yVZHeak,10499
|
|
324
|
+
atomicshop-2.18.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
325
|
+
atomicshop-2.18.1.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
326
|
+
atomicshop-2.18.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|