atomicshop 2.16.20__py3-none-any.whl → 2.16.22__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/classes.py +19 -0
- atomicshop/mitm/connection_thread_worker.py +8 -4
- atomicshop/mitm/engines/__parent/parser___parent.py +2 -11
- atomicshop/mitm/engines/__parent/recorder___parent.py +2 -3
- atomicshop/mitm/engines/__parent/responder___parent.py +4 -7
- atomicshop/mitm/engines/__reference_general/parser___reference_general.py +10 -7
- atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +3 -3
- atomicshop/mitm/engines/__reference_general/responder___reference_general.py +3 -3
- atomicshop/mitm/initialize_engines.py +11 -12
- atomicshop/mitm/mitm_main.py +7 -1
- atomicshop/mitm/statistic_analyzer.py +63 -1
- atomicshop/ssh_remote.py +19 -9
- atomicshop/wrappers/loggingw/loggers.py +8 -0
- atomicshop/wrappers/loggingw/loggingw.py +8 -10
- atomicshop/wrappers/socketw/dns_server.py +21 -3
- atomicshop/wrappers/socketw/get_process.py +6 -2
- atomicshop/wrappers/socketw/receiver.py +13 -3
- atomicshop/wrappers/socketw/sender.py +14 -3
- atomicshop/wrappers/socketw/socket_client.py +20 -5
- atomicshop/wrappers/socketw/socket_wrapper.py +2 -1
- {atomicshop-2.16.20.dist-info → atomicshop-2.16.22.dist-info}/METADATA +1 -1
- {atomicshop-2.16.20.dist-info → atomicshop-2.16.22.dist-info}/RECORD +26 -26
- {atomicshop-2.16.20.dist-info → atomicshop-2.16.22.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.16.20.dist-info → atomicshop-2.16.22.dist-info}/WHEEL +0 -0
- {atomicshop-2.16.20.dist-info → atomicshop-2.16.22.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/basics/classes.py
CHANGED
|
@@ -7,6 +7,25 @@ from pathlib import Path
|
|
|
7
7
|
from ..file_io.file_io import read_file
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
"""
|
|
11
|
+
class ParserParent:
|
|
12
|
+
# Initializing the logger in the "class variable" section will leave the instance of the logger initiated
|
|
13
|
+
# and the rest of the instances of the class will use the same logger.
|
|
14
|
+
# It is not in the "__init__" section, so it's not going to be initiated again.
|
|
15
|
+
# The name of the logger using "__name__" variable, which is the full name of the module package.
|
|
16
|
+
# Example: classes.parsers.parser_1_reference_general
|
|
17
|
+
|
|
18
|
+
# The code outside the functions will be executed during import of the module. When initializing a class
|
|
19
|
+
# in the script these lines will not be called again, only the "init" function.
|
|
20
|
+
logger = create_custom_logger()
|
|
21
|
+
|
|
22
|
+
def __init__(self, class_client_message: ClientMessage):
|
|
23
|
+
self.class_client_message: ClientMessage = class_client_message
|
|
24
|
+
|
|
25
|
+
# Usage: self.logger.info("Message")
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
|
|
10
29
|
def create_empty_class():
|
|
11
30
|
"""
|
|
12
31
|
Function creates empty class, you can add parameters to it dynamically.
|
|
@@ -125,7 +125,8 @@ def thread_worker_main(
|
|
|
125
125
|
|
|
126
126
|
network_logger.info("Initializing Receiver")
|
|
127
127
|
# Getting message from the client over the socket using specific class.
|
|
128
|
-
client_received_raw_data = receiver.Receiver(
|
|
128
|
+
client_received_raw_data = receiver.Receiver(
|
|
129
|
+
ssl_socket=function_client_socket_object, logger=network_logger).receive()
|
|
129
130
|
|
|
130
131
|
# If the message is empty, then the connection was closed already by the other side,
|
|
131
132
|
# so we can close the socket as well.
|
|
@@ -239,13 +240,14 @@ def thread_worker_main(
|
|
|
239
240
|
service_name=client_message.server_name, service_port=client_message.destination_port,
|
|
240
241
|
tls=is_tls,
|
|
241
242
|
dns_servers_list=(
|
|
242
|
-
config_static.TCPServer.forwarding_dns_service_ipv4_list___only_for_localhost)
|
|
243
|
+
config_static.TCPServer.forwarding_dns_service_ipv4_list___only_for_localhost),
|
|
244
|
+
logger=network_logger
|
|
243
245
|
)
|
|
244
246
|
# If we're not on localhost, then connect to domain directly.
|
|
245
247
|
else:
|
|
246
248
|
service_client = socket_client.SocketClient(
|
|
247
249
|
service_name=client_message.server_name, service_port=client_message.destination_port,
|
|
248
|
-
tls=is_tls)
|
|
250
|
+
tls=is_tls, logger=network_logger)
|
|
249
251
|
|
|
250
252
|
# Sending current client message and receiving a response.
|
|
251
253
|
# If there was an error it will be passed to "client_message" object class and if not, "None" will
|
|
@@ -301,7 +303,9 @@ def thread_worker_main(
|
|
|
301
303
|
|
|
302
304
|
# Iterate through the list of byte responses.
|
|
303
305
|
for response_raw_bytes in client_message.response_list_of_raw_bytes:
|
|
304
|
-
function_data_sent = sender.Sender(
|
|
306
|
+
function_data_sent = sender.Sender(
|
|
307
|
+
ssl_socket=function_client_socket_object, class_message=response_raw_bytes,
|
|
308
|
+
logger=network_logger).send()
|
|
305
309
|
|
|
306
310
|
# If there was problem with sending data, we'll break current loop.
|
|
307
311
|
if not function_data_sent:
|
|
@@ -2,20 +2,11 @@ from ...shared_functions import create_custom_logger
|
|
|
2
2
|
from ...message import ClientMessage
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
# Class that parses the message received from client.
|
|
6
5
|
class ParserParent:
|
|
7
|
-
|
|
8
|
-
# and the rest of the instances of the class will use the same logger.
|
|
9
|
-
# It is not in the "__init__" section, so it's not going to be initiated again.
|
|
10
|
-
# The name of the logger using "__name__" variable, which is the full name of the module package.
|
|
11
|
-
# Example: classes.parsers.parser_1_reference_general
|
|
12
|
-
|
|
13
|
-
# The code outside the functions will be executed during import of the module. When initializing a class
|
|
14
|
-
# in the script these lines will not be called again, only the "init" function.
|
|
15
|
-
logger = create_custom_logger()
|
|
16
|
-
|
|
6
|
+
"""Class that parses the message received from client."""
|
|
17
7
|
def __init__(self, class_client_message: ClientMessage):
|
|
18
8
|
self.class_client_message: ClientMessage = class_client_message
|
|
9
|
+
self.logger = create_custom_logger()
|
|
19
10
|
|
|
20
11
|
def parse(self):
|
|
21
12
|
# This is general parser, so we don't parse anything and 'request_body_parsed' gets empty byte string.
|
|
@@ -9,9 +9,6 @@ from ....file_io import file_io
|
|
|
9
9
|
|
|
10
10
|
# The class that is responsible for Recording Requests / Responses.
|
|
11
11
|
class RecorderParent:
|
|
12
|
-
# The code outside the functions will be executed during import of the module. When initializing a class
|
|
13
|
-
# in the script these lines will not be called again, only the "init" function.
|
|
14
|
-
logger = create_custom_logger()
|
|
15
12
|
|
|
16
13
|
def __init__(self, class_client_message: message.ClientMessage, record_path: str):
|
|
17
14
|
self.class_client_message: message.ClientMessage = class_client_message
|
|
@@ -22,6 +19,8 @@ class RecorderParent:
|
|
|
22
19
|
self.engine_record_path: str = str()
|
|
23
20
|
self.record_file_path: str = str()
|
|
24
21
|
|
|
22
|
+
self.logger = create_custom_logger()
|
|
23
|
+
|
|
25
24
|
# Get engine name and module name
|
|
26
25
|
self.get_engine_module()
|
|
27
26
|
# Build full file path.
|
|
@@ -7,20 +7,17 @@ from urllib.parse import unquote
|
|
|
7
7
|
from urllib.parse import urlparse
|
|
8
8
|
from urllib.parse import parse_qs
|
|
9
9
|
|
|
10
|
-
from ...shared_functions import create_custom_logger
|
|
11
10
|
from ...message import ClientMessage
|
|
12
11
|
from ....http_parse import HTTPResponseParse
|
|
13
12
|
from ....print_api import print_api
|
|
14
13
|
|
|
14
|
+
from atomicshop.mitm.shared_functions import create_custom_logger
|
|
15
15
|
|
|
16
|
-
# The class that is responsible for generating response to client based on the received message.
|
|
17
|
-
class ResponderParent:
|
|
18
|
-
# The code outside the functions will be executed during import of the module. When initializing a class
|
|
19
|
-
# in the script these lines will not be called again, only the "init" function.
|
|
20
|
-
logger = create_custom_logger()
|
|
21
16
|
|
|
17
|
+
class ResponderParent:
|
|
18
|
+
"""The class that is responsible for generating response to client based on the received message."""
|
|
22
19
|
def __init__(self):
|
|
23
|
-
|
|
20
|
+
self.logger = create_custom_logger()
|
|
24
21
|
|
|
25
22
|
@staticmethod
|
|
26
23
|
def get_path_parts(path: str):
|
|
@@ -3,21 +3,24 @@ from atomicshop.mitm.engines.__parent.parser___parent import ParserParent
|
|
|
3
3
|
from atomicshop.mitm.shared_functions import create_custom_logger
|
|
4
4
|
from atomicshop.mitm.message import ClientMessage
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
# from
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
# This is 'example' '.proto' file that contains message 'ExampleRequest'.
|
|
9
|
+
from .example_pb2 import ExampleRequest
|
|
10
|
+
# Import from 'protobuf' library of function 'MessageToDict' that
|
|
11
|
+
converts protobuf message object type to python dict.
|
|
12
|
+
from google.protobuf.json_format import MessageToDict
|
|
13
|
+
"""
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
# Class that parses the message received from client.
|
|
14
17
|
class ParserGeneral(ParserParent):
|
|
15
|
-
logger = create_custom_logger()
|
|
16
|
-
|
|
17
18
|
# When initializing main classes through "super" you need to pass parameters to init
|
|
18
19
|
def __init__(self, class_client_message: ClientMessage):
|
|
19
20
|
super().__init__(class_client_message)
|
|
20
21
|
|
|
22
|
+
self.logger = create_custom_logger()
|
|
23
|
+
|
|
21
24
|
# ==================================================================================================================
|
|
22
25
|
# Uncomment this section in order to begin building custom responder.
|
|
23
26
|
# def parse_example_request(self):
|
|
@@ -4,10 +4,10 @@ from atomicshop.mitm.shared_functions import create_custom_logger
|
|
|
4
4
|
from atomicshop.mitm.message import ClientMessage
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
# The class that is responsible for Recording Requests / Responses
|
|
8
7
|
class RecorderGeneral(RecorderParent):
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
"""The class that is responsible for Recording Requests / Responses"""
|
|
11
9
|
# When initializing main classes through "super" you need to pass parameters to init
|
|
12
10
|
def __init__(self, class_client_message: ClientMessage, record_path):
|
|
13
11
|
super().__init__(class_client_message, record_path)
|
|
12
|
+
|
|
13
|
+
self.logger = create_custom_logger()
|
|
@@ -14,14 +14,14 @@ from google.protobuf import json_format
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
# The class that is responsible for generating response to client based on the received message.
|
|
18
17
|
class ResponderGeneral(ResponderParent):
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
"""The class that is responsible for generating response to client based on the received message."""
|
|
21
19
|
# When initializing main classes through "super" you need to pass parameters to init
|
|
22
20
|
def __init__(self):
|
|
23
21
|
super().__init__()
|
|
24
22
|
|
|
23
|
+
self.logger = create_custom_logger()
|
|
24
|
+
|
|
25
25
|
# ==================================================================================================================
|
|
26
26
|
# Uncomment this section in order to begin building custom responder.
|
|
27
27
|
# @staticmethod
|
|
@@ -62,6 +62,17 @@ class ModuleCategory:
|
|
|
62
62
|
engine_directory_path, get_file=True, file_name_check_pattern=configuration_data['recorder_file'])[0].path
|
|
63
63
|
|
|
64
64
|
def initialize_engine(self, logs_path: str, logger=None, reference_general: bool = False, **kwargs):
|
|
65
|
+
# Initiating logger for each engine by its name
|
|
66
|
+
loggingw.create_logger(
|
|
67
|
+
logger_name=self.engine_name,
|
|
68
|
+
directory_path=logs_path,
|
|
69
|
+
add_stream=True,
|
|
70
|
+
add_timedfile=True,
|
|
71
|
+
formatter_streamhandler='DEFAULT',
|
|
72
|
+
formatter_filehandler='DEFAULT',
|
|
73
|
+
backupCount=config_static.LogRec.store_logs_for_x_days
|
|
74
|
+
)
|
|
75
|
+
|
|
65
76
|
if not reference_general:
|
|
66
77
|
self.parser_class_object = import_first_class_name_from_file_path(
|
|
67
78
|
self.script_directory, self.parser_file_path, logger=logger, stdout=False)
|
|
@@ -83,18 +94,6 @@ class ModuleCategory:
|
|
|
83
94
|
logger.error_exception(f"Exception while initializing responder: {exception_object}")
|
|
84
95
|
sys.exit()
|
|
85
96
|
|
|
86
|
-
# Initiating logger for each engine by its name
|
|
87
|
-
# initiate_logger(current_module.engine_name, log_file_extension)
|
|
88
|
-
loggingw.create_logger(
|
|
89
|
-
logger_name=self.engine_name,
|
|
90
|
-
directory_path=logs_path,
|
|
91
|
-
add_stream=True,
|
|
92
|
-
add_timedfile=True,
|
|
93
|
-
formatter_streamhandler='DEFAULT',
|
|
94
|
-
formatter_filehandler='DEFAULT',
|
|
95
|
-
backupCount=config_static.LogRec.store_logs_for_x_days
|
|
96
|
-
)
|
|
97
|
-
|
|
98
97
|
|
|
99
98
|
# Assigning external class object by message domain received from client. If the domain is not in the list,
|
|
100
99
|
# the reference general module will be assigned.
|
atomicshop/mitm/mitm_main.py
CHANGED
|
@@ -242,7 +242,8 @@ def mitm_server_main(config_file_path: str):
|
|
|
242
242
|
resolve_to_tcp_server_all_domains=config_static.DNSServer.resolve_to_tcp_server_all_domains,
|
|
243
243
|
resolve_regular=config_static.DNSServer.resolve_regular,
|
|
244
244
|
cache_timeout_minutes=config_static.DNSServer.cache_timeout_minutes,
|
|
245
|
-
request_domain_queue=domain_queue
|
|
245
|
+
request_domain_queue=domain_queue,
|
|
246
|
+
logger=network_logger
|
|
246
247
|
)
|
|
247
248
|
except (dns_server.DnsPortInUseError, dns_server.DnsConfigurationValuesError) as e:
|
|
248
249
|
print_api(e, error_type=True, color="red", logger=system_logger)
|
|
@@ -302,6 +303,11 @@ def mitm_server_main(config_file_path: str):
|
|
|
302
303
|
# Wait for the message to be printed and saved to file.
|
|
303
304
|
time.sleep(1)
|
|
304
305
|
return 1
|
|
306
|
+
except socket_wrapper.SocketWrapperConfigurationValuesError as e:
|
|
307
|
+
print_api(e, error_type=True, color="red", logger=system_logger, logger_method='critical')
|
|
308
|
+
# Wait for the message to be printed and saved to file.
|
|
309
|
+
time.sleep(1)
|
|
310
|
+
return 1
|
|
305
311
|
|
|
306
312
|
statistics_writer = socket_wrapper_instance.statistics_writer
|
|
307
313
|
|
|
@@ -2,6 +2,7 @@ import os
|
|
|
2
2
|
import datetime
|
|
3
3
|
import json
|
|
4
4
|
from typing import Union, Literal
|
|
5
|
+
import argparse
|
|
5
6
|
|
|
6
7
|
from .statistic_analyzer_helper import analyzer_helper, moving_average_helper
|
|
7
8
|
from .. import filesystem, domains, datetimes, urls
|
|
@@ -344,7 +345,7 @@ def analyze(main_file_path: str):
|
|
|
344
345
|
# ======================================================================================================================
|
|
345
346
|
|
|
346
347
|
|
|
347
|
-
def
|
|
348
|
+
def deviation_calculator_by_moving_average(
|
|
348
349
|
statistics_file_directory: str,
|
|
349
350
|
by_type: Literal['host', 'url'],
|
|
350
351
|
moving_average_window_days: int,
|
|
@@ -470,3 +471,64 @@ def deviation_calculator_by_moving_average_main(
|
|
|
470
471
|
return deviation_list
|
|
471
472
|
|
|
472
473
|
return []
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def deviation_calculator_by_moving_average_main():
|
|
477
|
+
def parse_args():
|
|
478
|
+
description_full: str = (
|
|
479
|
+
f'Description: Calculate deviation by moving average.')
|
|
480
|
+
|
|
481
|
+
parser = argparse.ArgumentParser(
|
|
482
|
+
description=description_full)
|
|
483
|
+
|
|
484
|
+
parser.add_argument(
|
|
485
|
+
'-d', '--directory', type=str, required=True,
|
|
486
|
+
help='Provide full path to directory with statistics.csv files.')
|
|
487
|
+
parser.add_argument(
|
|
488
|
+
'-of', '--output_file', type=str, required=True, help='Provide full path to output file.')
|
|
489
|
+
parser.add_argument(
|
|
490
|
+
'-ot', '--output_type', type=str, required=True, help='Provide output type: [json] or [csv].')
|
|
491
|
+
parser.add_argument(
|
|
492
|
+
'-by', '--by_type', type=str, required=True, help='Calculate by [host] or [url].')
|
|
493
|
+
parser.add_argument(
|
|
494
|
+
'-f', '--full_details', action='store_true', required=False,
|
|
495
|
+
help='(OPTIONAL) Output full processing details instead of summary.')
|
|
496
|
+
parser.add_argument(
|
|
497
|
+
'-w', '--window', type=int, required=True, help='Moving average window in days.')
|
|
498
|
+
parser.add_argument(
|
|
499
|
+
'-p', '--percentage', type=float, required=True,
|
|
500
|
+
help='Percentage of deviation from moving average. Example: 0.1 for 10%%.')
|
|
501
|
+
|
|
502
|
+
return parser.parse_args()
|
|
503
|
+
|
|
504
|
+
args = parse_args()
|
|
505
|
+
|
|
506
|
+
if args.output_type == 'csv' and args.full_details:
|
|
507
|
+
print_api("Full details output is not supported for csv files.", color='red')
|
|
508
|
+
return 1
|
|
509
|
+
|
|
510
|
+
if not os.path.isdir(args.directory):
|
|
511
|
+
print_api(f"Directory does not exist: {args.directory}", color='red')
|
|
512
|
+
return 1
|
|
513
|
+
|
|
514
|
+
if not filesystem.get_paths_from_directory(
|
|
515
|
+
directory_path=args.directory, get_file=True, simple_list=True, file_name_check_pattern='*statistics*.csv'):
|
|
516
|
+
print_api(f"No statistics files found in: {args.directory}", color='red')
|
|
517
|
+
return 1
|
|
518
|
+
|
|
519
|
+
if args.full_details:
|
|
520
|
+
summary = False
|
|
521
|
+
else:
|
|
522
|
+
summary = True
|
|
523
|
+
|
|
524
|
+
_ = deviation_calculator_by_moving_average(
|
|
525
|
+
statistics_file_directory=args.directory,
|
|
526
|
+
by_type=args.by_type,
|
|
527
|
+
moving_average_window_days=args.window,
|
|
528
|
+
top_bottom_deviation_percentage=args.percentage,
|
|
529
|
+
summary=summary,
|
|
530
|
+
output_file_path=args.output_file,
|
|
531
|
+
output_file_type=args.output_type,
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
return 0
|
atomicshop/ssh_remote.py
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
import base64
|
|
3
3
|
import socket
|
|
4
|
+
import logging
|
|
5
|
+
from pathlib import Path
|
|
4
6
|
|
|
5
|
-
from .print_api import print_api
|
|
6
|
-
from .wrappers.loggingw import loggingw
|
|
7
|
-
from .wrappers.socketw import base
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# External Libraries
|
|
11
7
|
try:
|
|
12
8
|
import paramiko
|
|
13
9
|
except ImportError as exception_object:
|
|
14
10
|
print(f"Library missing: {exception_object.name}. Install by executing: pip install paramiko")
|
|
15
11
|
sys.exit()
|
|
16
12
|
|
|
13
|
+
from .print_api import print_api
|
|
14
|
+
from .wrappers.loggingw import loggingw
|
|
15
|
+
from .wrappers.socketw import base
|
|
16
|
+
|
|
17
17
|
|
|
18
18
|
class SSHRemote:
|
|
19
19
|
"""
|
|
@@ -87,9 +87,13 @@ class SSHRemote:
|
|
|
87
87
|
sys.exit(main())
|
|
88
88
|
|
|
89
89
|
"""
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
def __init__(
|
|
91
|
+
self,
|
|
92
|
+
ip_address: str,
|
|
93
|
+
username: str,
|
|
94
|
+
password: str,
|
|
95
|
+
logger: logging.Logger = None
|
|
96
|
+
):
|
|
93
97
|
self.ip_address: str = ip_address
|
|
94
98
|
self.username: str = username
|
|
95
99
|
self.password: str = password
|
|
@@ -97,6 +101,12 @@ class SSHRemote:
|
|
|
97
101
|
# Initializing paramiko SSHClient class
|
|
98
102
|
self.ssh_client = paramiko.SSHClient()
|
|
99
103
|
|
|
104
|
+
if logger:
|
|
105
|
+
# Create child logger for the provided logger with the module's name.
|
|
106
|
+
self.logger: logging.Logger = loggingw.get_logger_with_level(f'{logger.name}.{Path(__file__).stem}')
|
|
107
|
+
else:
|
|
108
|
+
self.logger: logging.Logger = logger
|
|
109
|
+
|
|
100
110
|
def connect(self):
|
|
101
111
|
error: str = str()
|
|
102
112
|
|
|
@@ -25,6 +25,14 @@ def is_logger_exists(
|
|
|
25
25
|
return logger_name in logging.Logger.manager.loggerDict
|
|
26
26
|
|
|
27
27
|
|
|
28
|
+
def get_all_existing_loggers_names() -> list:
|
|
29
|
+
"""
|
|
30
|
+
Function to get all existing loggers names.
|
|
31
|
+
:return: list, List of all existing loggers names.
|
|
32
|
+
"""
|
|
33
|
+
return list(logging.Logger.manager.loggerDict.keys())
|
|
34
|
+
|
|
35
|
+
|
|
28
36
|
def get_logger(logger_name: str) -> logging.Logger:
|
|
29
37
|
"""
|
|
30
38
|
Function to get a logger.
|
|
@@ -5,10 +5,13 @@ from typing import Literal, Union
|
|
|
5
5
|
from . import loggers, handlers
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
class LoggingwLoggerAlreadyExistsError(Exception):
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
|
|
8
12
|
# noinspection PyPep8Naming
|
|
9
13
|
def create_logger(
|
|
10
14
|
logger_name: str,
|
|
11
|
-
get_existing_if_exists: bool = True,
|
|
12
15
|
file_path: str = None,
|
|
13
16
|
directory_path: str = None,
|
|
14
17
|
add_stream: bool = False,
|
|
@@ -43,8 +46,6 @@ def create_logger(
|
|
|
43
46
|
Function to get a logger and add StreamHandler and TimedRotatingFileHandler to it.
|
|
44
47
|
|
|
45
48
|
:param logger_name: Name of the logger.
|
|
46
|
-
:param get_existing_if_exists: bool, If set to True, the logger will be returned if it already exists.
|
|
47
|
-
If set to False, the new stream/file handler will be added to existing logger again.
|
|
48
49
|
:param file_path: full path to the log file. If you don't want to use the file, set it to None.
|
|
49
50
|
You can set the directory_path only and then the 'logger_name' will be used as the file name with the
|
|
50
51
|
'file_type' as the file extension.
|
|
@@ -165,6 +166,10 @@ def create_logger(
|
|
|
165
166
|
main()
|
|
166
167
|
"""
|
|
167
168
|
|
|
169
|
+
# Check if the logger exists before creating it.
|
|
170
|
+
if loggers.is_logger_exists(logger_name):
|
|
171
|
+
raise LoggingwLoggerAlreadyExistsError(f"Logger '{logger_name}' already exists.")
|
|
172
|
+
|
|
168
173
|
if not directory_path and not file_path:
|
|
169
174
|
raise ValueError("You need to provide 'directory_path' or 'file_path'.")
|
|
170
175
|
if directory_path and file_path:
|
|
@@ -176,15 +181,8 @@ def create_logger(
|
|
|
176
181
|
|
|
177
182
|
file_path = f"{directory_path}{os.sep}{logger_name}.{file_type}"
|
|
178
183
|
|
|
179
|
-
# Check if the logger exists before creating it/getting the existing.
|
|
180
|
-
is_logger_exists = loggers.is_logger_exists(logger_name)
|
|
181
|
-
|
|
182
184
|
logger = get_logger_with_level(logger_name, logging_level)
|
|
183
185
|
|
|
184
|
-
# If the logger already exists, and we don't want to add the handlers again, return the logger.
|
|
185
|
-
if get_existing_if_exists and is_logger_exists:
|
|
186
|
-
return logger
|
|
187
|
-
|
|
188
186
|
if add_stream:
|
|
189
187
|
handlers.add_stream_handler(
|
|
190
188
|
logger=logger, logging_level=logging_level, formatter=formatter_streamhandler,
|
|
@@ -3,6 +3,8 @@ import datetime
|
|
|
3
3
|
import time
|
|
4
4
|
import threading
|
|
5
5
|
import socket
|
|
6
|
+
import logging
|
|
7
|
+
from pathlib import Path
|
|
6
8
|
|
|
7
9
|
from ...print_api import print_api
|
|
8
10
|
from ..loggingw import loggingw
|
|
@@ -28,8 +30,7 @@ class DnsServer:
|
|
|
28
30
|
"""
|
|
29
31
|
DnsServer class is responsible to handle DNS Requests on port 53 based on configuration and send DNS Response back.
|
|
30
32
|
"""
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
# noinspection PyPep8Naming
|
|
33
34
|
def __init__(
|
|
34
35
|
self,
|
|
35
36
|
listening_interface: str,
|
|
@@ -49,6 +50,7 @@ class DnsServer:
|
|
|
49
50
|
response_ttl: int = 60,
|
|
50
51
|
dns_service_retries: int = 5,
|
|
51
52
|
cache_timeout_minutes: int = 60,
|
|
53
|
+
logger: logging.Logger = None
|
|
52
54
|
):
|
|
53
55
|
"""
|
|
54
56
|
Initialize the DNS Server object with all the necessary settings.
|
|
@@ -80,6 +82,7 @@ class DnsServer:
|
|
|
80
82
|
(socket connect / request send / response receive).
|
|
81
83
|
:param cache_timeout_minutes: int: Timeout in minutes to clear the DNS Cache.
|
|
82
84
|
server. Each domain will be pass in the queue as a string.
|
|
85
|
+
:param logger: logging.Logger: Logger object to use for logging. If not provided, a new logger will be created.
|
|
83
86
|
"""
|
|
84
87
|
|
|
85
88
|
self.listening_interface: str = listening_interface
|
|
@@ -127,13 +130,28 @@ class DnsServer:
|
|
|
127
130
|
# Logger that logs all the DNS Requests and responses in DNS format. These entries will not present in
|
|
128
131
|
# network log of TCP Server module.
|
|
129
132
|
self.dns_full_logger = loggingw.create_logger(
|
|
130
|
-
logger_name="
|
|
133
|
+
logger_name="dns_full",
|
|
131
134
|
directory_path=self.log_directory_path,
|
|
132
135
|
add_timedfile=True,
|
|
133
136
|
formatter_filehandler='DEFAULT',
|
|
134
137
|
backupCount=backupCount_log_files_x_days
|
|
135
138
|
)
|
|
136
139
|
|
|
140
|
+
# Check if the logger was provided, if not, create a new logger.
|
|
141
|
+
if not logger:
|
|
142
|
+
self.logger = loggingw.create_logger(
|
|
143
|
+
logger_name=Path(__file__).stem,
|
|
144
|
+
directory_path=self.log_directory_path,
|
|
145
|
+
add_stream=True,
|
|
146
|
+
add_timedfile=True,
|
|
147
|
+
formatter_streamhandler='DEFAULT',
|
|
148
|
+
formatter_filehandler='DEFAULT',
|
|
149
|
+
backupCount=backupCount_log_files_x_days
|
|
150
|
+
)
|
|
151
|
+
else:
|
|
152
|
+
# Create child logger for the provided logger with the module's name.
|
|
153
|
+
self.logger: logging.Logger = loggingw.get_logger_with_level(f'{logger.name}.{Path(__file__).stem}')
|
|
154
|
+
|
|
137
155
|
self.test_config()
|
|
138
156
|
|
|
139
157
|
def test_config(self):
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Needed to redirect output from console to logger on LOCALHOST process command line harvesting.
|
|
2
2
|
import io
|
|
3
3
|
from contextlib import redirect_stdout
|
|
4
|
+
import logging
|
|
4
5
|
|
|
5
6
|
from . import base
|
|
6
7
|
from ...ssh_remote import SSHRemote
|
|
@@ -15,12 +16,14 @@ class GetCommandLine:
|
|
|
15
16
|
client_socket=None,
|
|
16
17
|
ssh_script_processor=None,
|
|
17
18
|
ssh_user: str = None,
|
|
18
|
-
ssh_pass: str = None
|
|
19
|
+
ssh_pass: str = None,
|
|
20
|
+
logger: logging.Logger = None
|
|
19
21
|
):
|
|
20
22
|
self.client_socket = client_socket
|
|
21
23
|
self.ssh_script_processor = ssh_script_processor
|
|
22
24
|
self.ssh_user: str = ssh_user
|
|
23
25
|
self.ssh_pass: str = ssh_pass
|
|
26
|
+
self.logger: logging.Logger = logger
|
|
24
27
|
|
|
25
28
|
def get_process_name(self, print_kwargs: dict = None):
|
|
26
29
|
# Get client ip and the source port.
|
|
@@ -53,7 +56,8 @@ class GetCommandLine:
|
|
|
53
56
|
|
|
54
57
|
print_api(f"Initializing SSH connection to [{client_ip}]", **print_kwargs)
|
|
55
58
|
# Initializing SSHRemote class.
|
|
56
|
-
current_ssh_client = SSHRemote(
|
|
59
|
+
current_ssh_client = SSHRemote(
|
|
60
|
+
ip_address=client_ip, username=self.ssh_user, password=self.ssh_pass, logger=self.logger)
|
|
57
61
|
|
|
58
62
|
execution_output, execution_error = current_ssh_client.connect_get_client_commandline(script_string)
|
|
59
63
|
# Else, if we're on localhost, then execute the script directly without SSH.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import socket
|
|
2
3
|
import ssl
|
|
4
|
+
from pathlib import Path
|
|
3
5
|
|
|
4
6
|
from ...print_api import print_api
|
|
5
7
|
from ..loggingw import loggingw
|
|
@@ -20,9 +22,11 @@ def peek_first_bytes(client_socket, bytes_amount: int = 1) -> bytes:
|
|
|
20
22
|
|
|
21
23
|
class Receiver:
|
|
22
24
|
""" Receiver Class is responsible for receiving the message from socket and populate the message class """
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
ssl_socket: ssl.SSLSocket,
|
|
28
|
+
logger: logging.Logger = None
|
|
29
|
+
):
|
|
26
30
|
self.ssl_socket: ssl.SSLSocket = ssl_socket
|
|
27
31
|
self.buffer_size_receive: int = 16384
|
|
28
32
|
# Timeout of 2 is enough for regular HTTP sessions`.
|
|
@@ -39,6 +43,12 @@ class Receiver:
|
|
|
39
43
|
# Will get client Local port from the socket
|
|
40
44
|
self.class_client_local_port: int = int()
|
|
41
45
|
|
|
46
|
+
if logger:
|
|
47
|
+
# Create child logger for the provided logger with the module's name.
|
|
48
|
+
self.logger: logging.Logger = loggingw.get_logger_with_level(f'{logger.name}.{Path(__file__).stem}')
|
|
49
|
+
else:
|
|
50
|
+
self.logger: logging.Logger = logger
|
|
51
|
+
|
|
42
52
|
# Function to receive only the buffer, with error handling
|
|
43
53
|
def socket_receive_message_buffer(self):
|
|
44
54
|
# Defining the data variable
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import ssl
|
|
2
|
+
import logging
|
|
3
|
+
from pathlib import Path
|
|
2
4
|
|
|
3
5
|
from ...print_api import print_api
|
|
4
6
|
from ..loggingw import loggingw
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class Sender:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
ssl_socket: ssl.SSLSocket,
|
|
13
|
+
class_message: bytearray,
|
|
14
|
+
logger: logging.Logger = None
|
|
15
|
+
):
|
|
11
16
|
self.class_message: bytearray = class_message
|
|
12
17
|
self.ssl_socket: ssl.SSLSocket = ssl_socket
|
|
13
18
|
|
|
19
|
+
if logger:
|
|
20
|
+
# Create child logger for the provided logger with the module's name.
|
|
21
|
+
self.logger: logging.Logger = loggingw.get_logger_with_level(f'{logger.name}.{Path(__file__).stem}')
|
|
22
|
+
else:
|
|
23
|
+
self.logger: logging.Logger = logger
|
|
24
|
+
|
|
14
25
|
# Function to send a message to server
|
|
15
26
|
def send(self):
|
|
16
27
|
# "socket.send()" returns number of bytes sent. "0" meaning that the socket was closed by the other side.
|
|
@@ -2,6 +2,8 @@ import socket
|
|
|
2
2
|
import ssl
|
|
3
3
|
import time
|
|
4
4
|
from typing import Literal, Union
|
|
5
|
+
import logging
|
|
6
|
+
from pathlib import Path
|
|
5
7
|
|
|
6
8
|
from cryptography import x509
|
|
7
9
|
|
|
@@ -18,11 +20,15 @@ import dns.resolver
|
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
class SocketClient:
|
|
21
|
-
logger = loggingw.get_logger_with_level("network." + __name__.rpartition('.')[2])
|
|
22
|
-
|
|
23
23
|
def __init__(
|
|
24
24
|
self,
|
|
25
|
-
service_name: str,
|
|
25
|
+
service_name: str,
|
|
26
|
+
service_port: int,
|
|
27
|
+
tls: bool = False,
|
|
28
|
+
connection_ip=None,
|
|
29
|
+
dns_servers_list=None,
|
|
30
|
+
logger: logging.Logger = None
|
|
31
|
+
):
|
|
26
32
|
"""
|
|
27
33
|
If you have a certificate for domain, but not for the IPv4 address, the SSL Socket context can be created for
|
|
28
34
|
domain and the connection itself (socket.connect()) made for the IP. This way YOU decide to which IPv4 your
|
|
@@ -38,6 +44,7 @@ class SocketClient:
|
|
|
38
44
|
'service_name' by these DNS servers, with the first IPv4 result.
|
|
39
45
|
:param dns_servers_list: (Optional) List object with dns IPv4 addresses that 'service_name' will be resolved
|
|
40
46
|
with, using 'dnspython' module. 'connection_ip' will be populated with first resolved IP.
|
|
47
|
+
:param logger: (Optional) Logger object. If not provided, the default logger will be used.
|
|
41
48
|
|
|
42
49
|
If both 'connection_ip' and 'dns_servers_list' specified, ValueException with raise.
|
|
43
50
|
"""
|
|
@@ -60,6 +67,12 @@ class SocketClient:
|
|
|
60
67
|
elif self.connection_ip and self.dns_servers_list:
|
|
61
68
|
raise ValueError("Both 'connection_ip' and 'dns_servers_list' were specified.")
|
|
62
69
|
|
|
70
|
+
if logger:
|
|
71
|
+
# Create child logger for the provided logger with the module's name.
|
|
72
|
+
self.logger: logging.Logger = loggingw.get_logger_with_level(f'{logger.name}.{Path(__file__).stem}')
|
|
73
|
+
else:
|
|
74
|
+
self.logger: logging.Logger = logger
|
|
75
|
+
|
|
63
76
|
# Function to create SSL socket to destination service
|
|
64
77
|
def create_service_socket(self):
|
|
65
78
|
# If TLS is enabled.
|
|
@@ -208,7 +221,8 @@ class SocketClient:
|
|
|
208
221
|
f"[{self.service_name}] resolves to ip: [{self.connection_ip}]. Pulled IP from the socket.")
|
|
209
222
|
|
|
210
223
|
# Send the data received from the client to the service over socket
|
|
211
|
-
function_data_sent = Sender(
|
|
224
|
+
function_data_sent = Sender(
|
|
225
|
+
ssl_socket=self.socket_instance, class_message=request_bytes, logger=self.logger).send()
|
|
212
226
|
|
|
213
227
|
# If the socket disconnected on data send
|
|
214
228
|
if not function_data_sent:
|
|
@@ -218,7 +232,8 @@ class SocketClient:
|
|
|
218
232
|
self.close_socket()
|
|
219
233
|
# Else if send was successful
|
|
220
234
|
else:
|
|
221
|
-
function_service_data = Receiver(
|
|
235
|
+
function_service_data = Receiver(
|
|
236
|
+
ssl_socket=self.socket_instance, logger=self.logger).receive()
|
|
222
237
|
|
|
223
238
|
# If data received is empty meaning the socket was closed on the other side
|
|
224
239
|
if not function_service_data:
|
|
@@ -432,7 +432,8 @@ class SocketWrapper:
|
|
|
432
432
|
client_socket=client_socket,
|
|
433
433
|
ssh_script_processor=self.ssh_script_processor,
|
|
434
434
|
ssh_user=self.ssh_user,
|
|
435
|
-
ssh_pass=self.ssh_pass
|
|
435
|
+
ssh_pass=self.ssh_pass,
|
|
436
|
+
logger=self.logger)
|
|
436
437
|
process_name = get_command_instance.get_process_name(print_kwargs={'logger': self.logger})
|
|
437
438
|
|
|
438
439
|
# If 'accept()' function worked well, SSL worked well, then 'client_socket' won't be empty.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=NVC0lbA3Ua_9Z-pCiq_rauheR-QtAnITRIbPvzPTez0,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
|
|
@@ -35,7 +35,7 @@ atomicshop/scheduling.py,sha256=MvF20M6uU0Kh_CQn2ERxMTLvvF-ToBrdMhXNrKxYFj8,4682
|
|
|
35
35
|
atomicshop/script_as_string_processor.py,sha256=uAIWwhHE-eP2FniuwBqEiM6VzyQX96uwdE3aA31rIm8,1883
|
|
36
36
|
atomicshop/sound.py,sha256=tHiQQbFBk7EYN3pAfGNcxfF9oNsoYnZgu9z9iq8hxQE,24352
|
|
37
37
|
atomicshop/speech_recognize.py,sha256=55-dIjgkpF93mvJnJuxSFuft5H5eRvGNlUj9BeIOZxk,5903
|
|
38
|
-
atomicshop/ssh_remote.py,sha256=
|
|
38
|
+
atomicshop/ssh_remote.py,sha256=Mxixqs2-xGy1bhbcP0LKqjxKTNPz1Gmzz8PzO8aLB4c,17345
|
|
39
39
|
atomicshop/sys_functions.py,sha256=MTBxRve5bh58SPvhX3gMiGqHlSBuI_rdNN1NnnBBWqI,906
|
|
40
40
|
atomicshop/system_resource_monitor.py,sha256=WvnnQrD5W9NRqOWI2YNcL-ut2UrvhrYToVlRR2c1vs8,13720
|
|
41
41
|
atomicshop/system_resources.py,sha256=0mhDZBEcMzToCOw5ArJhtqYjktOW6iJGdyRkJ01Cpwk,9272
|
|
@@ -84,7 +84,7 @@ atomicshop/basics/ansi_escape_codes.py,sha256=WtIkm-BjSZS5J5irDUdAMBNvdX-qXFZcTX
|
|
|
84
84
|
atomicshop/basics/argparse_template.py,sha256=horwgSf3MX1ZgRnYxtmmQuz9OU_vKrKggF65gmjlmfg,5836
|
|
85
85
|
atomicshop/basics/booleans.py,sha256=QM0pibMmEKRKtBlpW9M5hkfD4S4rzirde0f8TSTnScE,2198
|
|
86
86
|
atomicshop/basics/bytes_arrays.py,sha256=WvSRDhIGt1ywF95t-yNgpxLm1nlZUbM1Dz6QckcyE8Y,5915
|
|
87
|
-
atomicshop/basics/classes.py,sha256=
|
|
87
|
+
atomicshop/basics/classes.py,sha256=T0Bm13hKvkXG3med68ptL7XuoWiCi3TE-K5TMINDlrY,10655
|
|
88
88
|
atomicshop/basics/dicts.py,sha256=DeYHIh940pMMBrFhpXt4dsigFVYzTrlqWymNo4Pq_Js,14049
|
|
89
89
|
atomicshop/basics/dicts_nested.py,sha256=StYxYnYPa0SEJr1lmEwAv5zfERWWqoULeyG8e0zRAwE,4107
|
|
90
90
|
atomicshop/basics/enumerations.py,sha256=41VVQYh_vnVapggxKg2IRU5e_EiMpZzX1n1mtxvoSzM,1364
|
|
@@ -124,25 +124,25 @@ atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,21
|
|
|
124
124
|
atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
125
125
|
atomicshop/mitm/config_static.py,sha256=UNvRTb3ZuFVGZpF33fvaIf0xw_VGyml2ExIwqW_uYcg,7777
|
|
126
126
|
atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
|
|
127
|
-
atomicshop/mitm/connection_thread_worker.py,sha256=
|
|
127
|
+
atomicshop/mitm/connection_thread_worker.py,sha256=rfullUfMRR5YUEI45KJdGXlbOGYF89GfPkhUBoHizhM,20297
|
|
128
128
|
atomicshop/mitm/import_config.py,sha256=_nu8mgA-M4s6dZ8_QWx3x0aVb75upvsCuX_PIUg4X2w,8345
|
|
129
|
-
atomicshop/mitm/initialize_engines.py,sha256=
|
|
129
|
+
atomicshop/mitm/initialize_engines.py,sha256=Od1vC1ZGls0BNZiPgoRQj8Mc44UO8INJj3w1p5YQw5A,8274
|
|
130
130
|
atomicshop/mitm/message.py,sha256=d_sm3O_aoZf87dDQP44xOMNEG-uZBN1ZecQgMCacbZs,1814
|
|
131
|
-
atomicshop/mitm/mitm_main.py,sha256=
|
|
131
|
+
atomicshop/mitm/mitm_main.py,sha256=gA8sV7hI107OnoeedCHpy8f3zcE4vAsBc44l_VTjVFo,21622
|
|
132
132
|
atomicshop/mitm/recs_files.py,sha256=B8fSuvYXlh50LWfwLRw_bYswreTjmdZLuHJzbDC5Gss,2930
|
|
133
133
|
atomicshop/mitm/shared_functions.py,sha256=hplm98tz8pgJ4WHUVI9sf_oVqUM2KJ1Y2pD6EFSb8P0,1879
|
|
134
|
-
atomicshop/mitm/statistic_analyzer.py,sha256=
|
|
134
|
+
atomicshop/mitm/statistic_analyzer.py,sha256=0QYmkdSp5tjHkyl5MGWVEsgpRR3FgN7A2fE6pKTSO8I,27164
|
|
135
135
|
atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
136
136
|
atomicshop/mitm/engines/create_module_template.py,sha256=tRjVSm1sD6FzML71Qbuwvita0qsusdFGm8NZLsZ-XMs,4853
|
|
137
137
|
atomicshop/mitm/engines/create_module_template_example.py,sha256=X5xhvbV6-g9jU_bQVhf_crZmaH50LRWz3bS-faQ18ds,489
|
|
138
138
|
atomicshop/mitm/engines/__parent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
139
|
-
atomicshop/mitm/engines/__parent/parser___parent.py,sha256=
|
|
140
|
-
atomicshop/mitm/engines/__parent/recorder___parent.py,sha256=
|
|
141
|
-
atomicshop/mitm/engines/__parent/responder___parent.py,sha256=
|
|
139
|
+
atomicshop/mitm/engines/__parent/parser___parent.py,sha256=VjV_cDuB3V0a3dPbJqLBEo3674Asa8-HVzvqxGULME8,720
|
|
140
|
+
atomicshop/mitm/engines/__parent/recorder___parent.py,sha256=s_FZwqBMZrX3SJZ5wmJNR3qQ5ODiIwmkTMLZ6JQ26DE,4466
|
|
141
|
+
atomicshop/mitm/engines/__parent/responder___parent.py,sha256=7WQeR3UmMnN74bDwn-0nz2OfhXJ3-ClXpNGUFZ7wJUE,12004
|
|
142
142
|
atomicshop/mitm/engines/__reference_general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
143
|
-
atomicshop/mitm/engines/__reference_general/parser___reference_general.py,sha256=
|
|
144
|
-
atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha256=
|
|
145
|
-
atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=
|
|
143
|
+
atomicshop/mitm/engines/__reference_general/parser___reference_general.py,sha256=57MEPZMAjTO6xBDZ-yt6lgGJyqRrP0Do5Gk_cgCiPns,2998
|
|
144
|
+
atomicshop/mitm/engines/__reference_general/recorder___reference_general.py,sha256=3eCGxD2oDulpVDgmMq19TyXohjsY-O_3HUiN8oKsUI4,712
|
|
145
|
+
atomicshop/mitm/engines/__reference_general/responder___reference_general.py,sha256=IUyQYMPeEhIARfALWiKPFeXagSQD6lRzAxUdi4ZIT88,7010
|
|
146
146
|
atomicshop/mitm/statistic_analyzer_helper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
147
147
|
atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py,sha256=pk6L1t1ea1kvlBoR9QEJptOmaX-mumhwLsP2GCKukbk,5920
|
|
148
148
|
atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py,sha256=Wge-OfbbClfjeEWwOyksd-x9C5QZdRD3KRSjtP9VL9Q,16651
|
|
@@ -248,8 +248,8 @@ atomicshop/wrappers/loggingw/consts.py,sha256=JWiUJEydjhwatBxtIJsGTmDUSTLbmIRidt
|
|
|
248
248
|
atomicshop/wrappers/loggingw/filters.py,sha256=CMs5PAMb68zxJgBcQobaOFDG5kLJBOVYnoBHjDgksO8,2859
|
|
249
249
|
atomicshop/wrappers/loggingw/formatters.py,sha256=7XUJvlB0CK4DCkEp8NTL0S0dkyrZD0UTADgEwkStKOY,5483
|
|
250
250
|
atomicshop/wrappers/loggingw/handlers.py,sha256=hAPFJQ-wFoNO8QzGrJRSvyuP09Q1F0Dl9_w7zzlgcW0,18155
|
|
251
|
-
atomicshop/wrappers/loggingw/loggers.py,sha256=
|
|
252
|
-
atomicshop/wrappers/loggingw/loggingw.py,sha256=
|
|
251
|
+
atomicshop/wrappers/loggingw/loggers.py,sha256=mmM__XR3W4QC82wbsDRG_M4_0JYGGEP0Qn0WCOSp-go,2910
|
|
252
|
+
atomicshop/wrappers/loggingw/loggingw.py,sha256=nt4UxOBHL--M-Ls9b3eicffCrspYWDWG1q4ZVlHATIs,12068
|
|
253
253
|
atomicshop/wrappers/loggingw/reading.py,sha256=ERBSiQbEksySKpXpu2E_6k9dZ6MPH95ZIsmdjWW9MUE,16436
|
|
254
254
|
atomicshop/wrappers/mongodbw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
255
255
|
atomicshop/wrappers/mongodbw/install_mongodb.py,sha256=3ZPqrXxj3lC-PnAKGXclylLuOqsbyXYeUpb5iGjdeUU,6626
|
|
@@ -296,21 +296,21 @@ atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-Atq
|
|
|
296
296
|
atomicshop/wrappers/socketw/base.py,sha256=evoOIxg5Xff3THJnrVX00D5HobaOpDp6_e_gso7TJmA,2191
|
|
297
297
|
atomicshop/wrappers/socketw/certificator.py,sha256=3CpQKtcW68FSbH6LVSEZTqWBS6Yg_-3K0x4nFkId4UY,12236
|
|
298
298
|
atomicshop/wrappers/socketw/creator.py,sha256=3_OraDkw2DAWZfoSdY3svCGMOIxpjLEEY7NxWd7M5P4,9873
|
|
299
|
-
atomicshop/wrappers/socketw/dns_server.py,sha256=
|
|
299
|
+
atomicshop/wrappers/socketw/dns_server.py,sha256=G3roqkj_gMRTkVs2kgwiQR9S7YqA-uQWraCt8FqKjlo,46375
|
|
300
300
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=B-X5SHLSUIWToihH2MKnOB1F4A81_X0DpLLfnYKYbEc,7067
|
|
301
|
-
atomicshop/wrappers/socketw/get_process.py,sha256=
|
|
302
|
-
atomicshop/wrappers/socketw/receiver.py,sha256=
|
|
303
|
-
atomicshop/wrappers/socketw/sender.py,sha256=
|
|
301
|
+
atomicshop/wrappers/socketw/get_process.py,sha256=zKEqh98cB9UDLFhtxVpperfXsCjyIMNANHilDD06p0U,6094
|
|
302
|
+
atomicshop/wrappers/socketw/receiver.py,sha256=XVvWOoeCo3vA0O5p19ryi-hcDIyx382WNG7WzMNVeYk,9322
|
|
303
|
+
atomicshop/wrappers/socketw/sender.py,sha256=OcX1aeI2OBDPPfvQkiEcV4Ak22DSJVvjMGYKOlgfpmI,3993
|
|
304
304
|
atomicshop/wrappers/socketw/sni.py,sha256=fVwyh3h9IqfLMnf4__bMIzcF4c-Kk9mlbDWMRXKN-ow,17155
|
|
305
|
-
atomicshop/wrappers/socketw/socket_client.py,sha256=
|
|
305
|
+
atomicshop/wrappers/socketw/socket_client.py,sha256=hcHtOh43UhJAxYe7DSg4YVSJnCEKLRWKPiZ8DD8ite8,20237
|
|
306
306
|
atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
|
|
307
|
-
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=
|
|
307
|
+
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=M47tjC8SoXZJV2fC_OYmSNNTs-3-ZQcpaB1WmvqVCTU,33408
|
|
308
308
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
|
|
309
309
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=V_m1D0KpizQox3IEWp2AUcncwWy5kG25hbFrc-mBSJE,3029
|
|
310
310
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
311
311
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=bQ8Jql8bVGBJ0dt3VQ56lga_1LBOMLI3Km_otvvbU6c,7138
|
|
312
|
-
atomicshop-2.16.
|
|
313
|
-
atomicshop-2.16.
|
|
314
|
-
atomicshop-2.16.
|
|
315
|
-
atomicshop-2.16.
|
|
316
|
-
atomicshop-2.16.
|
|
312
|
+
atomicshop-2.16.22.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
313
|
+
atomicshop-2.16.22.dist-info/METADATA,sha256=lOjy44JtH_ETUEAHES0RmxZDkA4alJcAXWY2IpUDvxA,10473
|
|
314
|
+
atomicshop-2.16.22.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
315
|
+
atomicshop-2.16.22.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
316
|
+
atomicshop-2.16.22.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|