atomicshop 2.15.11__py3-none-any.whl → 3.10.5__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.
- atomicshop/__init__.py +1 -1
- atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
- atomicshop/a_mains/dns_gateway_setting.py +11 -0
- atomicshop/a_mains/get_local_tcp_ports.py +85 -0
- atomicshop/a_mains/github_wrapper.py +11 -0
- atomicshop/a_mains/install_ca_certificate.py +172 -0
- atomicshop/a_mains/process_from_port.py +119 -0
- atomicshop/a_mains/set_default_dns_gateway.py +90 -0
- atomicshop/a_mains/update_config_toml.py +38 -0
- atomicshop/basics/ansi_escape_codes.py +3 -1
- atomicshop/basics/argparse_template.py +2 -0
- atomicshop/basics/booleans.py +27 -30
- atomicshop/basics/bytes_arrays.py +43 -0
- atomicshop/basics/classes.py +149 -1
- atomicshop/basics/enums.py +2 -2
- atomicshop/basics/exceptions.py +5 -1
- atomicshop/basics/list_of_classes.py +29 -0
- atomicshop/basics/multiprocesses.py +374 -50
- atomicshop/basics/strings.py +72 -3
- atomicshop/basics/threads.py +14 -0
- atomicshop/basics/tracebacks.py +13 -3
- atomicshop/certificates.py +153 -52
- atomicshop/config_init.py +11 -6
- atomicshop/console_user_response.py +7 -14
- atomicshop/consoles.py +9 -0
- atomicshop/datetimes.py +1 -1
- atomicshop/diff_check.py +3 -3
- atomicshop/dns.py +128 -3
- atomicshop/etws/_pywintrace_fix.py +17 -0
- atomicshop/etws/trace.py +40 -42
- atomicshop/etws/traces/trace_dns.py +56 -44
- atomicshop/etws/traces/trace_tcp.py +130 -0
- atomicshop/file_io/csvs.py +27 -5
- atomicshop/file_io/docxs.py +34 -17
- atomicshop/file_io/file_io.py +31 -17
- atomicshop/file_io/jsons.py +49 -0
- atomicshop/file_io/tomls.py +139 -0
- atomicshop/filesystem.py +616 -291
- atomicshop/get_process_list.py +3 -3
- atomicshop/http_parse.py +149 -93
- atomicshop/ip_addresses.py +6 -1
- atomicshop/mitm/centered_settings.py +132 -0
- atomicshop/mitm/config_static.py +207 -0
- atomicshop/mitm/config_toml_editor.py +55 -0
- atomicshop/mitm/connection_thread_worker.py +875 -357
- atomicshop/mitm/engines/__parent/parser___parent.py +4 -17
- atomicshop/mitm/engines/__parent/recorder___parent.py +108 -51
- atomicshop/mitm/engines/__parent/requester___parent.py +116 -0
- atomicshop/mitm/engines/__parent/responder___parent.py +75 -114
- atomicshop/mitm/engines/__reference_general/parser___reference_general.py +10 -7
- atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +5 -5
- atomicshop/mitm/engines/__reference_general/requester___reference_general.py +47 -0
- atomicshop/mitm/engines/__reference_general/responder___reference_general.py +95 -13
- atomicshop/mitm/engines/create_module_template.py +58 -14
- atomicshop/mitm/import_config.py +359 -139
- atomicshop/mitm/initialize_engines.py +160 -80
- atomicshop/mitm/message.py +64 -23
- atomicshop/mitm/mitm_main.py +892 -0
- atomicshop/mitm/recs_files.py +183 -0
- atomicshop/mitm/shared_functions.py +4 -10
- atomicshop/mitm/ssh_tester.py +82 -0
- atomicshop/mitm/statistic_analyzer.py +136 -40
- atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +265 -83
- atomicshop/monitor/checks/dns.py +1 -1
- atomicshop/networks.py +671 -0
- atomicshop/on_exit.py +39 -9
- atomicshop/package_mains_processor.py +84 -0
- atomicshop/permissions/permissions.py +22 -0
- atomicshop/permissions/ubuntu_permissions.py +239 -0
- atomicshop/permissions/win_permissions.py +33 -0
- atomicshop/print_api.py +24 -42
- atomicshop/process.py +24 -6
- atomicshop/process_poller/process_pool.py +0 -1
- atomicshop/process_poller/simple_process_pool.py +204 -5
- atomicshop/python_file_patcher.py +1 -1
- atomicshop/python_functions.py +27 -75
- atomicshop/speech_recognize.py +8 -0
- atomicshop/ssh_remote.py +158 -172
- atomicshop/system_resource_monitor.py +61 -47
- atomicshop/system_resources.py +8 -8
- atomicshop/tempfiles.py +1 -2
- atomicshop/urls.py +6 -0
- atomicshop/venvs.py +28 -0
- atomicshop/versioning.py +27 -0
- atomicshop/web.py +98 -27
- atomicshop/web_apis/google_custom_search.py +44 -0
- atomicshop/web_apis/google_llm.py +188 -0
- atomicshop/websocket_parse.py +450 -0
- atomicshop/wrappers/certauthw/certauth.py +1 -0
- atomicshop/wrappers/cryptographyw.py +29 -8
- atomicshop/wrappers/ctyping/etw_winapi/const.py +97 -47
- atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py +178 -49
- atomicshop/wrappers/ctyping/file_details_winapi.py +67 -0
- atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py +2 -1
- atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py +2 -2
- atomicshop/wrappers/ctyping/setup_device.py +466 -0
- atomicshop/wrappers/ctyping/win_console.py +39 -0
- atomicshop/wrappers/dockerw/dockerw.py +113 -2
- atomicshop/wrappers/elasticsearchw/config_basic.py +0 -12
- atomicshop/wrappers/elasticsearchw/elastic_infra.py +75 -0
- atomicshop/wrappers/elasticsearchw/elasticsearchw.py +2 -20
- atomicshop/wrappers/factw/get_file_data.py +12 -5
- atomicshop/wrappers/factw/install/install_after_restart.py +89 -5
- atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +20 -14
- atomicshop/wrappers/githubw.py +537 -54
- atomicshop/wrappers/loggingw/consts.py +1 -1
- atomicshop/wrappers/loggingw/filters.py +23 -0
- atomicshop/wrappers/loggingw/formatters.py +12 -0
- atomicshop/wrappers/loggingw/handlers.py +214 -107
- atomicshop/wrappers/loggingw/loggers.py +19 -0
- atomicshop/wrappers/loggingw/loggingw.py +860 -22
- atomicshop/wrappers/loggingw/reading.py +134 -112
- atomicshop/wrappers/mongodbw/mongo_infra.py +31 -0
- atomicshop/wrappers/mongodbw/mongodbw.py +1324 -36
- atomicshop/wrappers/netshw.py +271 -0
- atomicshop/wrappers/playwrightw/engine.py +34 -19
- atomicshop/wrappers/playwrightw/infra.py +5 -0
- atomicshop/wrappers/playwrightw/javascript.py +7 -3
- atomicshop/wrappers/playwrightw/keyboard.py +14 -0
- atomicshop/wrappers/playwrightw/scenarios.py +172 -5
- atomicshop/wrappers/playwrightw/waits.py +9 -7
- atomicshop/wrappers/powershell_networking.py +80 -0
- atomicshop/wrappers/psutilw/processes.py +37 -1
- atomicshop/wrappers/psutilw/psutil_networks.py +85 -0
- atomicshop/wrappers/pyopensslw.py +9 -2
- atomicshop/wrappers/pywin32w/cert_store.py +116 -0
- atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +3 -105
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +3 -57
- atomicshop/wrappers/pywin32w/wmis/msft_netipaddress.py +113 -0
- atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +259 -0
- atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +112 -0
- atomicshop/wrappers/pywin32w/wmis/wmi_helpers.py +236 -0
- atomicshop/wrappers/socketw/accepter.py +21 -7
- atomicshop/wrappers/socketw/certificator.py +216 -150
- atomicshop/wrappers/socketw/creator.py +190 -50
- atomicshop/wrappers/socketw/dns_server.py +491 -182
- atomicshop/wrappers/socketw/exception_wrapper.py +45 -52
- atomicshop/wrappers/socketw/process_getter.py +86 -0
- atomicshop/wrappers/socketw/receiver.py +144 -102
- atomicshop/wrappers/socketw/sender.py +65 -35
- atomicshop/wrappers/socketw/sni.py +334 -165
- atomicshop/wrappers/socketw/socket_base.py +134 -0
- atomicshop/wrappers/socketw/socket_client.py +137 -95
- atomicshop/wrappers/socketw/socket_server_tester.py +11 -7
- atomicshop/wrappers/socketw/socket_wrapper.py +717 -116
- atomicshop/wrappers/socketw/ssl_base.py +15 -14
- atomicshop/wrappers/socketw/statistics_csv.py +148 -17
- atomicshop/wrappers/sysmonw.py +1 -1
- atomicshop/wrappers/ubuntu_terminal.py +65 -26
- atomicshop/wrappers/win_auditw.py +189 -0
- atomicshop/wrappers/winregw/__init__.py +0 -0
- atomicshop/wrappers/winregw/winreg_installed_software.py +58 -0
- atomicshop/wrappers/winregw/winreg_network.py +232 -0
- {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/METADATA +31 -51
- atomicshop-3.10.5.dist-info/RECORD +306 -0
- {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/WHEEL +1 -1
- atomicshop/_basics_temp.py +0 -101
- atomicshop/a_installs/win/fibratus.py +0 -9
- atomicshop/a_installs/win/mongodb.py +0 -9
- atomicshop/a_installs/win/pycharm.py +0 -9
- atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh +0 -3
- atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd +0 -2
- atomicshop/addons/mains/__pycache__/install_fibratus_windows.cpython-312.pyc +0 -0
- atomicshop/addons/mains/__pycache__/msi_unpacker.cpython-312.pyc +0 -0
- atomicshop/addons/mains/install_docker_rootless_ubuntu.py +0 -11
- atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py +0 -11
- atomicshop/addons/mains/install_elastic_search_and_kibana_ubuntu.py +0 -10
- atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py +0 -9
- atomicshop/addons/package_setup/CreateWheel.cmd +0 -7
- atomicshop/addons/package_setup/Setup in Edit mode.cmd +0 -6
- atomicshop/addons/package_setup/Setup.cmd +0 -7
- atomicshop/archiver/_search_in_zip.py +0 -189
- atomicshop/archiver/archiver.py +0 -34
- atomicshop/archiver/search_in_archive.py +0 -250
- atomicshop/archiver/sevenz_app_w.py +0 -86
- atomicshop/archiver/sevenzs.py +0 -44
- atomicshop/archiver/zips.py +0 -293
- atomicshop/file_types.py +0 -24
- atomicshop/mitm/config_editor.py +0 -37
- atomicshop/mitm/engines/create_module_template_example.py +0 -13
- atomicshop/mitm/initialize_mitm_server.py +0 -268
- atomicshop/pbtkmultifile_argparse.py +0 -88
- atomicshop/permissions.py +0 -151
- atomicshop/script_as_string_processor.py +0 -38
- atomicshop/ssh_scripts/process_from_ipv4.py +0 -37
- atomicshop/ssh_scripts/process_from_port.py +0 -27
- atomicshop/wrappers/_process_wrapper_curl.py +0 -27
- atomicshop/wrappers/_process_wrapper_tar.py +0 -21
- atomicshop/wrappers/dockerw/install_docker.py +0 -209
- atomicshop/wrappers/elasticsearchw/infrastructure.py +0 -265
- atomicshop/wrappers/elasticsearchw/install_elastic.py +0 -232
- atomicshop/wrappers/ffmpegw.py +0 -125
- atomicshop/wrappers/fibratusw/install.py +0 -81
- atomicshop/wrappers/mongodbw/infrastructure.py +0 -53
- atomicshop/wrappers/mongodbw/install_mongodb.py +0 -190
- atomicshop/wrappers/msiw.py +0 -149
- atomicshop/wrappers/nodejsw/install_nodejs.py +0 -139
- atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
- atomicshop/wrappers/psutilw/networks.py +0 -45
- atomicshop/wrappers/pycharmw.py +0 -81
- atomicshop/wrappers/socketw/base.py +0 -59
- atomicshop/wrappers/socketw/get_process.py +0 -107
- atomicshop/wrappers/wslw.py +0 -191
- atomicshop-2.15.11.dist-info/RECORD +0 -302
- /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
- /atomicshop/{addons → a_mains/addons}/PlayWrightCodegen.cmd +0 -0
- /atomicshop/{addons → a_mains/addons}/ScriptExecution.cmd +0 -0
- /atomicshop/{addons → a_mains/addons}/inits/init_to_import_all_modules.py +0 -0
- /atomicshop/{addons → a_mains/addons}/process_list/ReadMe.txt +0 -0
- /atomicshop/{addons → a_mains/addons}/process_list/compile.cmd +0 -0
- /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.dll +0 -0
- /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.exp +0 -0
- /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.lib +0 -0
- /atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +0 -0
- /atomicshop/{archiver → permissions}/__init__.py +0 -0
- /atomicshop/{wrappers/fibratusw → web_apis}/__init__.py +0 -0
- /atomicshop/wrappers/{nodejsw → pywin32w/wmis}/__init__.py +0 -0
- /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
- {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info/licenses}/LICENSE.txt +0 -0
- {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/top_level.txt +0 -0
atomicshop/get_process_list.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import Union, Literal
|
|
2
2
|
|
|
3
|
-
from .wrappers.pywin32w import
|
|
3
|
+
from .wrappers.pywin32w.wmis import win32process
|
|
4
4
|
from .wrappers.psutilw import psutilw
|
|
5
5
|
from .basics import dicts
|
|
6
6
|
from . import get_process_name_cmd_dll
|
|
@@ -36,7 +36,7 @@ class GetProcessList:
|
|
|
36
36
|
self.process_polling_instance = psutilw.PsutilProcesses()
|
|
37
37
|
self.connected = True
|
|
38
38
|
elif self.get_method == 'pywin32':
|
|
39
|
-
self.process_polling_instance =
|
|
39
|
+
self.process_polling_instance = win32process.Pywin32Processes()
|
|
40
40
|
elif self.get_method == 'process_dll':
|
|
41
41
|
self.process_polling_instance = get_process_name_cmd_dll.ProcessNameCmdline()
|
|
42
42
|
|
|
@@ -130,4 +130,4 @@ test = get_process_list.get_processes()
|
|
|
130
130
|
|
|
131
131
|
# globals need to be specified, otherwise the setup_code won't work with passed variables.
|
|
132
132
|
times = timeit.timeit(setup=setup_code, stmt=test_code, number=times_to_test, globals=locals())
|
|
133
|
-
print(f'Execution time: {times}')
|
|
133
|
+
print(f'Execution time: {times}')
|
atomicshop/http_parse.py
CHANGED
|
@@ -1,10 +1,43 @@
|
|
|
1
|
-
# v1.0.1 - 26.03.2023 23:40
|
|
2
1
|
from http.server import BaseHTTPRequestHandler
|
|
3
2
|
from http.client import HTTPResponse
|
|
4
3
|
import http
|
|
5
4
|
from io import BytesIO
|
|
6
5
|
|
|
7
6
|
|
|
7
|
+
def get_request_methods() -> list[str]:
|
|
8
|
+
"""
|
|
9
|
+
Function to return all available HTTP request methods.
|
|
10
|
+
"""
|
|
11
|
+
# noinspection PyUnresolvedReferences
|
|
12
|
+
return [method.value for method in http.HTTPMethod]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def is_first_bytes_http_request(request_bytes: bytes) -> bool:
|
|
16
|
+
"""
|
|
17
|
+
Function to check if the first bytes are HTTP request or not.
|
|
18
|
+
"""
|
|
19
|
+
http_request_methods_list: list = get_request_methods()
|
|
20
|
+
http_request_methods_list = [method.encode() for method in http_request_methods_list]
|
|
21
|
+
|
|
22
|
+
# If the first bytes are HTTP request, then the first word should be one of the HTTP request methods.
|
|
23
|
+
for method in http_request_methods_list:
|
|
24
|
+
if request_bytes.startswith(method):
|
|
25
|
+
return True
|
|
26
|
+
return False
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def is_first_bytes_http_response(response_bytes: bytes) -> bool:
|
|
30
|
+
"""
|
|
31
|
+
Function to check if the first bytes are HTTP response or not.
|
|
32
|
+
"""
|
|
33
|
+
http_response_beginning: bytes = b'HTTP/'
|
|
34
|
+
|
|
35
|
+
# If the first bytes are HTTP response, then the first word should be 'HTTP/'.
|
|
36
|
+
if response_bytes.startswith(http_response_beginning):
|
|
37
|
+
return True
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
|
|
8
41
|
class HTTPRequestParse(BaseHTTPRequestHandler):
|
|
9
42
|
"""
|
|
10
43
|
The class will parse HTTP requests.
|
|
@@ -49,41 +82,27 @@ class HTTPRequestParse(BaseHTTPRequestHandler):
|
|
|
49
82
|
client_message.request_raw_decoded = request_decoded
|
|
50
83
|
"""
|
|
51
84
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
self.
|
|
55
|
-
self.error_code = self.error_message = None
|
|
56
|
-
self.parse_request()
|
|
57
|
-
|
|
58
|
-
# Check if ".path" attribute exists after HTTP request parsing
|
|
59
|
-
if not hasattr(self, 'path'):
|
|
60
|
-
self.path = None
|
|
85
|
+
# noinspection PyMissingConstructor
|
|
86
|
+
def __init__(self, request_bytes: bytes):
|
|
87
|
+
self.request_bytes: bytes = request_bytes
|
|
61
88
|
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
self.content_length = int(self.headers.get('Content-Length'))
|
|
68
|
-
self.body = self.rfile.read(self.content_length)
|
|
69
|
-
else:
|
|
70
|
-
self.content_length = None
|
|
71
|
-
self.body = None
|
|
72
|
-
except Exception:
|
|
73
|
-
self.content_length = None
|
|
74
|
-
self.body = None
|
|
75
|
-
pass
|
|
89
|
+
# noinspection PyTypeChecker
|
|
90
|
+
self.rfile = None
|
|
91
|
+
self.raw_requestline = None
|
|
92
|
+
self.error_code = None
|
|
93
|
+
self.error_message = None
|
|
76
94
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
#
|
|
80
|
-
|
|
95
|
+
self.content_length = None
|
|
96
|
+
self.body = None
|
|
97
|
+
# noinspection PyTypeChecker
|
|
98
|
+
self.path = None
|
|
81
99
|
|
|
100
|
+
# noinspection PyMethodOverriding
|
|
82
101
|
def send_error(self, code, message):
|
|
83
102
|
self.error_code = code
|
|
84
103
|
self.error_message = message
|
|
85
104
|
|
|
86
|
-
def
|
|
105
|
+
def parse(self):
|
|
87
106
|
"""
|
|
88
107
|
Function to check if parsed object is HTTP request or not.
|
|
89
108
|
'reason' will be populated with parsing status and errors.
|
|
@@ -117,88 +136,125 @@ class HTTPRequestParse(BaseHTTPRequestHandler):
|
|
|
117
136
|
|
|
118
137
|
client_message.request_raw_decoded = request_decoded
|
|
119
138
|
"""
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
# If there's any error in HTTP parsing
|
|
126
|
-
if self.error_message:
|
|
127
|
-
# If error status is "BAD_REQUEST"
|
|
128
|
-
if self.error_message.startswith("Bad request"):
|
|
129
|
-
# If it's 'Bad request' this is not HTTP request, so we can
|
|
130
|
-
# continue the execution and parse the code as NON-HTTP Request.
|
|
131
|
-
# Currently, seen 'Bad request syntax' and 'Bad request version'.
|
|
132
|
-
reason = f"HTTP Request Parsing: Not HTTP request: {self.error_message}"
|
|
133
|
-
function_result = False
|
|
134
|
-
error: False
|
|
135
|
-
else:
|
|
136
|
-
reason = f"HTTP Request Parsing: HTTP Request with Script Undocumented ERROR: {self.error_message}"
|
|
137
|
-
function_result = True
|
|
138
|
-
error = True
|
|
139
|
-
# If there's no error at all in HTTP Parsing, then it's fine HTTP Request
|
|
139
|
+
|
|
140
|
+
if self.request_bytes is None or not is_first_bytes_http_request(self.request_bytes):
|
|
141
|
+
error = "HTTP Request Parsing: Not HTTP request by first bytes."
|
|
142
|
+
is_http = False
|
|
140
143
|
else:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
error: str = str()
|
|
145
|
+
|
|
146
|
+
self.rfile = BytesIO(self.request_bytes)
|
|
147
|
+
self.raw_requestline = self.rfile.readline()
|
|
148
|
+
self.error_code = self.error_message = None
|
|
149
|
+
self.parse_request()
|
|
144
150
|
|
|
145
|
-
|
|
151
|
+
# Before checking for body, we need to make sure that ".headers" property exists, if not, return empty values.
|
|
152
|
+
if hasattr(self, 'headers'):
|
|
153
|
+
# The "body" of request is in the 'Content-Length' key. If it exists in "headers" - get the body
|
|
154
|
+
if 'Content-Length' in self.headers.keys():
|
|
155
|
+
# "self.headers.get('Content-Length')" returns number in string format, "int" converts it to integer
|
|
156
|
+
self.content_length = int(self.headers.get('Content-Length'))
|
|
157
|
+
self.body = self.rfile.read(self.content_length)
|
|
158
|
+
|
|
159
|
+
# Examples:
|
|
160
|
+
# Getting path: self.path
|
|
161
|
+
# Getting Request Version: self.request_version
|
|
162
|
+
# Getting specific header: self.headers['host']
|
|
163
|
+
|
|
164
|
+
# If there's any error in HTTP parsing
|
|
165
|
+
if self.error_message:
|
|
166
|
+
# If error status is "BAD_REQUEST"
|
|
167
|
+
if self.error_message.startswith("Bad request"):
|
|
168
|
+
# If it's 'Bad request' this is not HTTP request, so we can
|
|
169
|
+
# continue the execution and parse the code as NON-HTTP Request.
|
|
170
|
+
# Currently, seen 'Bad request syntax' and 'Bad request version'.
|
|
171
|
+
error = f"HTTP Request Parsing: Not HTTP request: {self.error_message}"
|
|
172
|
+
is_http = False
|
|
173
|
+
else:
|
|
174
|
+
error = f"HTTP Request Parsing: HTTP Request with Script Undocumented ERROR: {self.error_message}"
|
|
175
|
+
is_http = False
|
|
176
|
+
# If there's no error at all in HTTP Parsing, then it's fine HTTP Request
|
|
177
|
+
else:
|
|
178
|
+
is_http = True
|
|
179
|
+
|
|
180
|
+
return self, is_http, error
|
|
146
181
|
|
|
147
182
|
|
|
148
183
|
class FakeSocket:
|
|
149
184
|
"""
|
|
150
|
-
FakeSocket
|
|
185
|
+
FakeSocket mimics a socket object for parsing HTTP responses.
|
|
151
186
|
"""
|
|
152
187
|
def __init__(self, response_bytes):
|
|
153
188
|
self._file = BytesIO(response_bytes)
|
|
154
189
|
|
|
155
|
-
|
|
190
|
+
# noinspection PyUnusedLocal
|
|
191
|
+
def makefile(self, mode='rb', buffering=-1) -> BytesIO:
|
|
192
|
+
"""
|
|
193
|
+
Mimics the socket's makefile method, returning the BytesIO object.
|
|
194
|
+
"""
|
|
156
195
|
return self._file
|
|
157
196
|
|
|
197
|
+
def fileno(self) -> int:
|
|
198
|
+
"""
|
|
199
|
+
Provide a dummy file descriptor, as some code might call this.
|
|
200
|
+
"""
|
|
201
|
+
raise OSError("File descriptor not available in FakeSocket")
|
|
202
|
+
|
|
158
203
|
|
|
159
204
|
class HTTPResponseParse:
|
|
160
205
|
def __init__(self, response_raw_bytes: bytes):
|
|
161
|
-
self.error = None
|
|
162
206
|
self.response_raw_bytes: bytes = response_raw_bytes
|
|
163
|
-
# Assigning FakeSocket with response_raw_bytes.
|
|
164
|
-
self.source = FakeSocket(self.response_raw_bytes)
|
|
165
207
|
|
|
166
|
-
|
|
167
|
-
self.
|
|
208
|
+
self.error = None
|
|
209
|
+
self.source = None
|
|
210
|
+
self.response_raw_parsed = None
|
|
211
|
+
self.is_http: bool = False
|
|
168
212
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
self.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
213
|
+
def parse(self):
|
|
214
|
+
if self.response_raw_bytes is None or not is_first_bytes_http_response(self.response_raw_bytes):
|
|
215
|
+
self.error = "HTTP Response Parsing: Not a valid HTTP Response by first bytes."
|
|
216
|
+
self.is_http = False
|
|
217
|
+
self.response_raw_parsed = None
|
|
218
|
+
else:
|
|
219
|
+
# Assigning FakeSocket with response_raw_bytes.
|
|
220
|
+
self.source = FakeSocket(self.response_raw_bytes)
|
|
176
221
|
|
|
177
|
-
|
|
178
|
-
#
|
|
179
|
-
|
|
222
|
+
# Initializing HTTPResponse class with the FakeSocket with response_raw_bytes as input.
|
|
223
|
+
# noinspection PyTypeChecker
|
|
224
|
+
self.response_raw_parsed = HTTPResponse(self.source)
|
|
225
|
+
|
|
226
|
+
# Try to parse HTTP Response.
|
|
227
|
+
try:
|
|
228
|
+
self.response_raw_parsed.begin()
|
|
229
|
+
self.is_http = True
|
|
230
|
+
# If there were problems with the status line.
|
|
231
|
+
except http.client.BadStatusLine:
|
|
232
|
+
self.error = "HTTP Response Parsing: Not a valid HTTP Response: Bad Status Line."
|
|
233
|
+
self.is_http = False
|
|
234
|
+
|
|
235
|
+
header_exists: bool = False
|
|
236
|
+
if (self.response_raw_parsed is not None and hasattr(self.response_raw_parsed, 'headers') and
|
|
237
|
+
self.response_raw_parsed.headers is not None):
|
|
238
|
+
header_exists = True
|
|
239
|
+
|
|
240
|
+
if header_exists and self.response_raw_parsed.headers.defects:
|
|
180
241
|
self.error = f"HTTP Response Parsing: Not a valid HTTP Response: Some defects in headers: " \
|
|
181
|
-
f"{self.
|
|
182
|
-
|
|
183
|
-
# Meaning, that the exception was already handled.
|
|
184
|
-
except AttributeError:
|
|
185
|
-
pass
|
|
242
|
+
f"{self.response_raw_parsed.headers.defects}"
|
|
243
|
+
self.is_http = False
|
|
186
244
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
self.response_raw_decoded.body = None
|
|
204
|
-
pass
|
|
245
|
+
if self.is_http:
|
|
246
|
+
# Before checking for body, we need to make sure that ".headers" property exists,
|
|
247
|
+
# if not, return empty values.
|
|
248
|
+
self.response_raw_parsed.content_length = None
|
|
249
|
+
self.response_raw_parsed.body = None
|
|
250
|
+
if header_exists and 'Content-Length' in self.response_raw_parsed.headers.keys():
|
|
251
|
+
# The "body" of response is in the 'Content-Length' key. If it exists in "headers" - get the body.
|
|
252
|
+
# "self.response_raw_decoded.headers.get('Content-Length')" returns number in string format,
|
|
253
|
+
# "int" converts it to integer.
|
|
254
|
+
self.response_raw_parsed.content_length = int(self.response_raw_parsed.headers.get('Content-Length'))
|
|
255
|
+
# Basically we need to extract only the number of bytes specified in 'Content-Length' from the end
|
|
256
|
+
# of the response that we received.
|
|
257
|
+
# self.response_raw_bytes[-23:]
|
|
258
|
+
self.response_raw_parsed.body = self.response_raw_bytes[-self.response_raw_parsed.content_length:]
|
|
259
|
+
|
|
260
|
+
return self.response_raw_parsed, self.is_http, self.error
|
atomicshop/ip_addresses.py
CHANGED
|
@@ -2,7 +2,12 @@ import ipaddress
|
|
|
2
2
|
from typing import Union, Literal
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
def is_ip_address(
|
|
5
|
+
def is_ip_address(
|
|
6
|
+
string_value: str,
|
|
7
|
+
ip_type: Union[
|
|
8
|
+
Literal['ipv4', 'ipv6'],
|
|
9
|
+
None] = None
|
|
10
|
+
) -> bool:
|
|
6
11
|
"""
|
|
7
12
|
The function checks if the string is an IPv4 or IPv6 address.
|
|
8
13
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import argparse
|
|
3
|
+
import base64
|
|
4
|
+
|
|
5
|
+
from ..print_api import print_api
|
|
6
|
+
from .. import networks, ssh_remote, package_mains_processor
|
|
7
|
+
from . import config_static, mitm_main
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _make_parser() -> argparse.ArgumentParser:
|
|
11
|
+
parser = argparse.ArgumentParser(
|
|
12
|
+
description="Apply centered network settings to the target hosts based on the configuration file and arguments."
|
|
13
|
+
)
|
|
14
|
+
parser.add_argument(
|
|
15
|
+
"-t", "--target-hosts-file",
|
|
16
|
+
type=str,
|
|
17
|
+
required=True,
|
|
18
|
+
help="Path to the text file that will include the list of hosts (name/ipv4)."
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
"-dns", "--set-default-dns-gateway",
|
|
23
|
+
action="store_true",
|
|
24
|
+
help="Set the default gateway as this server LAN IPv4 on the target hosts."
|
|
25
|
+
)
|
|
26
|
+
parser.add_argument(
|
|
27
|
+
"-ca", "--install-ca-cert",
|
|
28
|
+
action="store_true",
|
|
29
|
+
help="Install the CA certificate on the target hosts."
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
return parser
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def centered_settings_main(config_file_path: str, script_version: str):
|
|
37
|
+
print(f"Centered Settings Application Script Version: {script_version}")
|
|
38
|
+
# Import the configuration file.
|
|
39
|
+
rc: int = config_static.load_config(config_file_path, print_kwargs=dict(stdout=False))
|
|
40
|
+
if rc != 0:
|
|
41
|
+
return rc
|
|
42
|
+
|
|
43
|
+
if config_static.MainConfig.is_localhost:
|
|
44
|
+
print_api("The server is set to localhost mode. No changes will be applied.", color="yellow")
|
|
45
|
+
return 0
|
|
46
|
+
|
|
47
|
+
interface_name: str = mitm_main._get_interface_name()
|
|
48
|
+
if interface_name is None:
|
|
49
|
+
return 1
|
|
50
|
+
|
|
51
|
+
# File path to the CA certificate file.
|
|
52
|
+
crt_file_path: str = config_static.MainConfig.ca_certificate_crt_filepath
|
|
53
|
+
with open(crt_file_path, 'r') as crt_file:
|
|
54
|
+
ca_certificate_string: str = crt_file.read()
|
|
55
|
+
|
|
56
|
+
# Get the main non-virtual IPv4 address.
|
|
57
|
+
main_ipv4_list: list[str] = networks.get_interface_ips_powershell(interface_name, "dynamic")
|
|
58
|
+
|
|
59
|
+
if not main_ipv4_list:
|
|
60
|
+
print_api(f"Could not determine the main IPv4 address for interface: {interface_name}", color="red")
|
|
61
|
+
return 1
|
|
62
|
+
else:
|
|
63
|
+
main_ipv4: str = main_ipv4_list[0]
|
|
64
|
+
|
|
65
|
+
parser = _make_parser()
|
|
66
|
+
args = parser.parse_args()
|
|
67
|
+
|
|
68
|
+
target_hosts_file_path: str = args.target_hosts_file
|
|
69
|
+
set_default_dns_gateway: bool = args.set_default_dns_gateway
|
|
70
|
+
install_ca_cert: bool = args.install_ca_cert
|
|
71
|
+
|
|
72
|
+
if not set_default_dns_gateway and not install_ca_cert:
|
|
73
|
+
print_api("No actions specified. Use -dns and/or -ca arguments to apply settings.", color="yellow")
|
|
74
|
+
return 0
|
|
75
|
+
|
|
76
|
+
if not os.path.exists(target_hosts_file_path):
|
|
77
|
+
print_api(f"Target host list file does not exist: {target_hosts_file_path}", color="red")
|
|
78
|
+
return 1
|
|
79
|
+
|
|
80
|
+
# Read the target hosts from the file.
|
|
81
|
+
with open(target_hosts_file_path, 'r') as f:
|
|
82
|
+
target_hosts: list[str] = [line.strip() for line in f if line.strip()]
|
|
83
|
+
if not target_hosts:
|
|
84
|
+
print_api(f"No target hosts found in the file: {target_hosts_file_path}", color="red")
|
|
85
|
+
return 1
|
|
86
|
+
|
|
87
|
+
dns_script_string: str | None = None
|
|
88
|
+
if set_default_dns_gateway:
|
|
89
|
+
package_processor: package_mains_processor.PackageMainsProcessor = package_mains_processor.PackageMainsProcessor(
|
|
90
|
+
script_file_stem="set_default_dns_gateway")
|
|
91
|
+
dns_script_string = package_processor.read_script_file_to_string()
|
|
92
|
+
ca_script_string: str | None = None
|
|
93
|
+
if install_ca_cert:
|
|
94
|
+
package_processor: package_mains_processor.PackageMainsProcessor = package_mains_processor.PackageMainsProcessor(
|
|
95
|
+
script_file_stem="install_ca_certificate")
|
|
96
|
+
ca_script_string = package_processor.read_script_file_to_string()
|
|
97
|
+
|
|
98
|
+
for host in target_hosts:
|
|
99
|
+
ssh_client = ssh_remote.SSHRemote(
|
|
100
|
+
ip_address=host,
|
|
101
|
+
username=config_static.ProcessName.ssh_user,
|
|
102
|
+
password=config_static.ProcessName.ssh_pass
|
|
103
|
+
)
|
|
104
|
+
stderr = ssh_client.connect()
|
|
105
|
+
if stderr:
|
|
106
|
+
print_api(f"SSH connection to {host} failed:\n"
|
|
107
|
+
f"{stderr}", color="red")
|
|
108
|
+
continue
|
|
109
|
+
|
|
110
|
+
if set_default_dns_gateway:
|
|
111
|
+
stdout, stderr = ssh_client.remote_execution_python(
|
|
112
|
+
script_string=dns_script_string, script_arg_values=(main_ipv4,))
|
|
113
|
+
|
|
114
|
+
if stderr:
|
|
115
|
+
print_api(f"Failed to apply settings on {host}:\n{stderr}", color="red")
|
|
116
|
+
else:
|
|
117
|
+
print_api(f"Successfully applied settings on {host}:\n{stdout}", color="green")
|
|
118
|
+
if install_ca_cert:
|
|
119
|
+
cert_b64 = base64.b64encode(ca_certificate_string.encode("utf-8")).decode("ascii")
|
|
120
|
+
stdout, stderr = ssh_client.remote_execution_python(
|
|
121
|
+
script_string=ca_script_string, script_arg_values=(config_static.MainConfig.ca_certificate_name, cert_b64,))
|
|
122
|
+
|
|
123
|
+
if stderr:
|
|
124
|
+
print_api(f"Failed to install CA certificate on {host}:\n{stderr}", color="red")
|
|
125
|
+
else:
|
|
126
|
+
print_api(f"Successfully installed CA certificate on {host}:\n{stdout}", color="green")
|
|
127
|
+
|
|
128
|
+
# Closing SSH connection to the target host.
|
|
129
|
+
ssh_client.close()
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
return 0
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from . import import_config
|
|
6
|
+
from .message import ClientMessage
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# noinspection PyTypeChecker
|
|
10
|
+
ENGINES_LIST: list = None # list[initialize_engines.ModuleCategory]
|
|
11
|
+
REFERENCE_MODULE = None # initialize_engines.ModuleCategory
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MainConfig:
|
|
15
|
+
# '' (empty) - system's default internet interface.
|
|
16
|
+
# Any other network interface name available on the system.
|
|
17
|
+
is_offline: bool
|
|
18
|
+
network_interface: str
|
|
19
|
+
is_localhost: bool
|
|
20
|
+
|
|
21
|
+
set_default_dns_gateway: list[str]
|
|
22
|
+
set_default_dns_gateway_to_localhost: bool = False
|
|
23
|
+
set_default_dns_gateway_to_network_interface_ipv4: bool = False
|
|
24
|
+
default_localhost_dns_gateway_ipv4: str = '127.0.0.1'
|
|
25
|
+
|
|
26
|
+
LOGGER_NAME: str = 'network'
|
|
27
|
+
|
|
28
|
+
SCRIPT_DIRECTORY: str = None
|
|
29
|
+
|
|
30
|
+
ENGINES_DIRECTORY_PATH: str = None
|
|
31
|
+
ENGINES_DIRECTORY_NAME: str = "engines"
|
|
32
|
+
ENGINE_CONFIG_FILE_NAME: str = "engine_config.toml"
|
|
33
|
+
|
|
34
|
+
# Certificates.
|
|
35
|
+
default_server_certificate_name: str = 'default'
|
|
36
|
+
ca_certificate_name: str = 'ElaborateCA'
|
|
37
|
+
ca_certificate_pem_filename: str = f'{ca_certificate_name}.pem'
|
|
38
|
+
ca_certificate_crt_filename: str = f'{ca_certificate_name}_for_manual_installation_not_used_by_script.crt'
|
|
39
|
+
# CA Certificate name and file name without extension.
|
|
40
|
+
ca_certificate_filepath: str = None
|
|
41
|
+
ca_certificate_crt_filepath: str = None
|
|
42
|
+
# Default server certificate file name and path.
|
|
43
|
+
default_server_certificate_filename = f'{default_server_certificate_name}.pem'
|
|
44
|
+
default_server_certificate_filepath: str = None
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def update(cls):
|
|
48
|
+
# This runs after the dataclass is initialized
|
|
49
|
+
cls.ENGINES_DIRECTORY_PATH = cls.SCRIPT_DIRECTORY + os.sep + cls.ENGINES_DIRECTORY_NAME
|
|
50
|
+
cls.ca_certificate_filepath = f'{cls.SCRIPT_DIRECTORY}{os.sep}{cls.ca_certificate_pem_filename}'
|
|
51
|
+
cls.ca_certificate_crt_filepath = f'{cls.SCRIPT_DIRECTORY}{os.sep}{cls.ca_certificate_crt_filename}'
|
|
52
|
+
cls.default_server_certificate_filepath = \
|
|
53
|
+
f'{cls.SCRIPT_DIRECTORY}{os.sep}{cls.default_server_certificate_filename}'
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class DNSServer:
|
|
58
|
+
is_enabled: bool
|
|
59
|
+
offline_mode: bool
|
|
60
|
+
|
|
61
|
+
listening_ipv4: str
|
|
62
|
+
listening_port: int
|
|
63
|
+
|
|
64
|
+
listening_address: str
|
|
65
|
+
forwarding_dns_service_ipv4: str
|
|
66
|
+
cache_timeout_minutes: int
|
|
67
|
+
|
|
68
|
+
resolve_by_engine: bool
|
|
69
|
+
resolve_regular_pass_thru: bool
|
|
70
|
+
resolve_all_domains_to_ipv4_enable: bool
|
|
71
|
+
target_ipv4: str
|
|
72
|
+
|
|
73
|
+
# Convertable variables.
|
|
74
|
+
resolve_all_domains_to_ipv4: dict
|
|
75
|
+
|
|
76
|
+
# Static variables.
|
|
77
|
+
forwarding_dns_service_port: int = 53
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass
|
|
82
|
+
class TCPServer:
|
|
83
|
+
is_enabled: bool
|
|
84
|
+
no_engines_usage_to_listen_addresses_enable: bool
|
|
85
|
+
no_engines_listening_address_list: list[str]
|
|
86
|
+
|
|
87
|
+
# Convertable variables.
|
|
88
|
+
no_engines_usage_to_listen_addresses: dict
|
|
89
|
+
|
|
90
|
+
@dataclass
|
|
91
|
+
class LogRec:
|
|
92
|
+
logs_path: str
|
|
93
|
+
recordings_path: str
|
|
94
|
+
enable_request_response_recordings_in_logs: bool
|
|
95
|
+
store_logs_for_x_days: int
|
|
96
|
+
|
|
97
|
+
recordings_directory_name: str = 'recs'
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@dataclass
|
|
101
|
+
class Certificates:
|
|
102
|
+
install_ca_certificate_to_root_store: bool
|
|
103
|
+
uninstall_unused_ca_certificates_with_mitm_ca_name: bool
|
|
104
|
+
|
|
105
|
+
default_server_certificate_usage: bool
|
|
106
|
+
sni_add_new_domains_to_default_server_certificate: bool
|
|
107
|
+
|
|
108
|
+
custom_server_certificate_usage: bool
|
|
109
|
+
custom_server_certificate_path: str
|
|
110
|
+
custom_private_key_path: str
|
|
111
|
+
|
|
112
|
+
sni_create_server_certificate_for_each_domain: bool
|
|
113
|
+
sni_server_certificates_cache_directory: str
|
|
114
|
+
sni_get_server_certificate_from_server_socket: bool
|
|
115
|
+
sni_server_certificate_from_server_socket_download_directory: str
|
|
116
|
+
|
|
117
|
+
domains_all_times: list[str]
|
|
118
|
+
sslkeylog_file_path: str
|
|
119
|
+
|
|
120
|
+
sslkeylog_file_name: str = "sslkeylog.txt"
|
|
121
|
+
enable_sslkeylogfile_env_to_client_ssl_context: bool = True
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@dataclass
|
|
125
|
+
class SkipExtensions:
|
|
126
|
+
tls_web_client_authentication: bool
|
|
127
|
+
crl_distribution_points: bool
|
|
128
|
+
authority_information_access: bool
|
|
129
|
+
|
|
130
|
+
SKIP_EXTENSION_ID_LIST: list
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@dataclass
|
|
134
|
+
class ProcessName:
|
|
135
|
+
get_process_name: bool
|
|
136
|
+
ssh_user: str
|
|
137
|
+
ssh_pass: str
|
|
138
|
+
|
|
139
|
+
ssh_script_to_execute: Literal['process_from_port', 'process_from_ipv4'] = 'process_from_port'
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def load_config(
|
|
143
|
+
config_toml_file_path: str,
|
|
144
|
+
print_kwargs: dict = None
|
|
145
|
+
):
|
|
146
|
+
# global CONFIG
|
|
147
|
+
|
|
148
|
+
script_path = os.path.dirname(config_toml_file_path)
|
|
149
|
+
MainConfig.SCRIPT_DIRECTORY = script_path
|
|
150
|
+
MainConfig.update()
|
|
151
|
+
|
|
152
|
+
# Load the configuration file.
|
|
153
|
+
result = import_config.import_config_files(config_toml_file_path, print_kwargs=print_kwargs or {})
|
|
154
|
+
return result
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def get_listening_addresses(client_message: ClientMessage) -> dict | None:
|
|
158
|
+
"""
|
|
159
|
+
Get the list of listening addresses from the TCPServer configuration.
|
|
160
|
+
If no_engines_usage_to_listen_addresses_enable is True, return the no_engines_listening_address_list.
|
|
161
|
+
Otherwise, return an empty list.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
for engine in ENGINES_LIST:
|
|
165
|
+
if engine.engine_name == client_message.engine_name:
|
|
166
|
+
return {
|
|
167
|
+
'domain_target_dict': engine.domain_target_dict,
|
|
168
|
+
'port_target_dict': engine.port_target_dict
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# ============ Server Tester Specific ===============
|
|
173
|
+
CONFIG_INI_TESTER_FILE_NAME: str = 'config_tester.ini'
|
|
174
|
+
|
|
175
|
+
"""
|
|
176
|
+
config.toml:
|
|
177
|
+
target_domain_or_ip: the domain or ip that the requests will be sent to. Better use domains, for better testing
|
|
178
|
+
simulation.
|
|
179
|
+
target_port: the port that requests will be sent to.
|
|
180
|
+
request_type: type of each request: json / string / binary.
|
|
181
|
+
json format that contain a key with hex string of the request that will be converted to bytes.
|
|
182
|
+
string that will contain a request and will be converted to bytes.
|
|
183
|
+
binary file that will contain all request data - will be converted to bytes.
|
|
184
|
+
request_json_hex_key_list: this key stores raw request in hex format, since there can be characters that can't be
|
|
185
|
+
decoded to string / unicode.
|
|
186
|
+
'request_raw_hex' key is the default key in recorded files from mitm server, you may add keys for your custom
|
|
187
|
+
JSON files.
|
|
188
|
+
requests_directory: the directory that requests are will be taken from. Can be relative folder that will be in
|
|
189
|
+
current working directory.
|
|
190
|
+
|
|
191
|
+
parallel_connections_bool: boolean, sets if sockets should be initialized in threads (in parallel) or one after another.
|
|
192
|
+
Use all the connections / cycles in parallel when 'True'. New sockets will be created for each request.
|
|
193
|
+
Reuse the same socket / connection for all the requests when 'False'.
|
|
194
|
+
interval_between_requests_defaults_seconds: default interval in seconds between request sends.
|
|
195
|
+
interval_between_request_custom_list_seconds: list of intervals in seconds. If this configuration will not be empty,
|
|
196
|
+
this should be a list. Each interval in the list will follow the interval between requests and
|
|
197
|
+
'interval_between_requests_defaults_seconds' will not be used. It will be used only if number of requests
|
|
198
|
+
is less than then number of intervals in 'interval_between_request_custom_list_seconds'. The missing intervals
|
|
199
|
+
will be filled by default values from 'interval_between_requests_defaults_seconds'.
|
|
200
|
+
Example: you have 10 requests.
|
|
201
|
+
interval_between_requests_defaults_seconds = 5
|
|
202
|
+
interval_between_request_custom_list_seconds = 7, 10, 8, 4, 15
|
|
203
|
+
The rest will be filled from defaults: 7, 10, 8, 4, 15, 5, 5, 5, 5
|
|
204
|
+
send_request_batch_cycles: how many batch cycles to send of the same 10 requests (or any other number of requests that
|
|
205
|
+
you might have in the requests folder.
|
|
206
|
+
interval_between_batch_cycles_seconds: interval in seconds between each batch.
|
|
207
|
+
"""
|