atomicshop 2.11.47__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/addons/process_list/compile.cmd +7 -0
- atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.dll +0 -0
- atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.exp +0 -0
- atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.lib +0 -0
- atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +8 -1
- 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/{addons/mains → a_mains}/msi_unpacker.py +3 -1
- 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/appointment_management.py +5 -3
- 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/dicts.py +12 -0
- atomicshop/basics/enums.py +2 -2
- atomicshop/basics/exceptions.py +5 -1
- atomicshop/basics/list_of_classes.py +29 -0
- atomicshop/basics/list_of_dicts.py +69 -5
- atomicshop/basics/lists.py +14 -0
- atomicshop/basics/multiprocesses.py +374 -50
- atomicshop/basics/package_module.py +10 -0
- atomicshop/basics/strings.py +160 -7
- atomicshop/basics/threads.py +14 -0
- atomicshop/basics/tracebacks.py +13 -4
- atomicshop/certificates.py +153 -52
- atomicshop/config_init.py +12 -7
- atomicshop/console_user_response.py +7 -14
- atomicshop/consoles.py +9 -0
- atomicshop/datetimes.py +98 -0
- atomicshop/diff_check.py +340 -40
- atomicshop/dns.py +128 -12
- atomicshop/etws/_pywintrace_fix.py +17 -0
- atomicshop/etws/const.py +38 -0
- atomicshop/etws/providers.py +21 -0
- atomicshop/etws/sessions.py +43 -0
- atomicshop/etws/trace.py +168 -0
- atomicshop/etws/traces/trace_dns.py +162 -0
- atomicshop/etws/traces/trace_sysmon_process_creation.py +126 -0
- atomicshop/etws/traces/trace_tcp.py +130 -0
- atomicshop/file_io/csvs.py +222 -24
- atomicshop/file_io/docxs.py +35 -18
- atomicshop/file_io/file_io.py +35 -19
- atomicshop/file_io/jsons.py +49 -0
- atomicshop/file_io/tomls.py +139 -0
- atomicshop/filesystem.py +864 -293
- atomicshop/get_process_list.py +133 -0
- atomicshop/{process_name_cmd.py → get_process_name_cmd_dll.py} +52 -19
- 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 -74
- 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 +257 -166
- atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py +136 -0
- atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +525 -0
- atomicshop/monitor/change_monitor.py +96 -120
- atomicshop/monitor/checks/dns.py +139 -70
- atomicshop/monitor/checks/file.py +77 -0
- atomicshop/monitor/checks/network.py +81 -77
- atomicshop/monitor/checks/process_running.py +33 -34
- atomicshop/monitor/checks/url.py +94 -0
- atomicshop/networks.py +671 -0
- atomicshop/on_exit.py +205 -0
- 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 -41
- atomicshop/process.py +63 -17
- atomicshop/process_poller/__init__.py +0 -0
- atomicshop/process_poller/pollers/__init__.py +0 -0
- atomicshop/process_poller/pollers/psutil_pywin32wmi_dll.py +95 -0
- atomicshop/process_poller/process_pool.py +207 -0
- atomicshop/process_poller/simple_process_pool.py +311 -0
- atomicshop/process_poller/tracer_base.py +45 -0
- atomicshop/process_poller/tracers/__init__.py +0 -0
- atomicshop/process_poller/tracers/event_log.py +46 -0
- atomicshop/process_poller/tracers/sysmon_etw.py +68 -0
- atomicshop/python_file_patcher.py +1 -1
- atomicshop/python_functions.py +27 -75
- atomicshop/question_answer_engine.py +2 -2
- atomicshop/scheduling.py +24 -5
- atomicshop/sound.py +4 -2
- atomicshop/speech_recognize.py +8 -0
- atomicshop/ssh_remote.py +158 -172
- atomicshop/startup/__init__.py +0 -0
- atomicshop/startup/win/__init__.py +0 -0
- atomicshop/startup/win/startup_folder.py +53 -0
- atomicshop/startup/win/task_scheduler.py +119 -0
- atomicshop/system_resource_monitor.py +61 -46
- atomicshop/system_resources.py +8 -8
- atomicshop/tempfiles.py +1 -2
- atomicshop/timer.py +30 -11
- atomicshop/urls.py +41 -0
- atomicshop/venvs.py +28 -0
- atomicshop/versioning.py +27 -0
- atomicshop/web.py +110 -25
- atomicshop/web_apis/__init__.py +0 -0
- 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/__init__.py +0 -0
- atomicshop/wrappers/ctyping/etw_winapi/const.py +335 -0
- atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py +393 -0
- 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 +13 -9
- atomicshop/wrappers/ctyping/msi_windows_installer/tables.py +35 -0
- 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/factw/postgresql/firmware.py +4 -6
- atomicshop/wrappers/githubw.py +583 -51
- atomicshop/wrappers/loggingw/consts.py +49 -0
- atomicshop/wrappers/loggingw/filters.py +102 -0
- atomicshop/wrappers/loggingw/formatters.py +58 -71
- atomicshop/wrappers/loggingw/handlers.py +459 -40
- atomicshop/wrappers/loggingw/loggers.py +19 -0
- atomicshop/wrappers/loggingw/loggingw.py +1010 -178
- atomicshop/wrappers/loggingw/reading.py +344 -19
- atomicshop/wrappers/mongodbw/__init__.py +0 -0
- atomicshop/wrappers/mongodbw/mongo_infra.py +31 -0
- atomicshop/wrappers/mongodbw/mongodbw.py +1432 -0
- 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 +81 -0
- atomicshop/wrappers/psutilw/psutil_networks.py +85 -0
- atomicshop/wrappers/psutilw/psutilw.py +9 -0
- atomicshop/wrappers/pyopensslw.py +9 -2
- atomicshop/wrappers/pywin32w/__init__.py +0 -0
- atomicshop/wrappers/pywin32w/cert_store.py +116 -0
- atomicshop/wrappers/pywin32w/console.py +34 -0
- atomicshop/wrappers/pywin32w/win_event_log/__init__.py +0 -0
- atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
- atomicshop/wrappers/pywin32w/win_event_log/subscribe.py +212 -0
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/__init__.py +0 -0
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +57 -0
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +49 -0
- atomicshop/wrappers/pywin32w/win_event_log/subscribes/schannel_logging.py +97 -0
- atomicshop/wrappers/pywin32w/winshell.py +19 -0
- atomicshop/wrappers/pywin32w/wmis/__init__.py +0 -0
- 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 +500 -173
- 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 +14 -9
- 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 +157 -0
- 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.11.47.dist-info → atomicshop-3.10.5.dist-info}/METADATA +31 -49
- atomicshop-3.10.5.dist-info/RECORD +306 -0
- {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/WHEEL +1 -1
- atomicshop/_basics_temp.py +0 -101
- 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/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/addons/process_list/compile.cmd +0 -2
- atomicshop/addons/process_list/compiled/Win10x64/process_list.dll +0 -0
- atomicshop/addons/process_list/compiled/Win10x64/process_list.exp +0 -0
- atomicshop/addons/process_list/compiled/Win10x64/process_list.lib +0 -0
- 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/etw/dns_trace.py +0 -118
- atomicshop/etw/etw.py +0 -61
- atomicshop/file_types.py +0 -24
- atomicshop/mitm/engines/create_module_template_example.py +0 -13
- atomicshop/mitm/initialize_mitm_server.py +0 -240
- atomicshop/monitor/checks/hash.py +0 -44
- atomicshop/monitor/checks/hash_checks/file.py +0 -55
- atomicshop/monitor/checks/hash_checks/url.py +0 -62
- atomicshop/pbtkmultifile_argparse.py +0 -88
- atomicshop/permissions.py +0 -110
- atomicshop/process_poller.py +0 -237
- 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/loggingw/checks.py +0 -20
- atomicshop/wrappers/nodejsw/install_nodejs.py +0 -139
- atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
- atomicshop/wrappers/socketw/base.py +0 -59
- atomicshop/wrappers/socketw/get_process.py +0 -107
- atomicshop/wrappers/wslw.py +0 -191
- atomicshop-2.11.47.dist-info/RECORD +0 -251
- /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/mains → 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/mains → a_mains}/search_for_hyperlinks_in_docx.py +0 -0
- /atomicshop/{archiver → etws}/__init__.py +0 -0
- /atomicshop/{etw → etws/traces}/__init__.py +0 -0
- /atomicshop/{monitor/checks/hash_checks → mitm/statistic_analyzer_helper}/__init__.py +0 -0
- /atomicshop/{wrappers/nodejsw → permissions}/__init__.py +0 -0
- /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
- {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info/licenses}/LICENSE.txt +0 -0
- {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import winreg
|
|
3
|
+
|
|
4
|
+
from ..print_api import print_api
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
AUDITING_REG_PATH: str = r"Software\Microsoft\Windows\CurrentVersion\Policies\System\Audit"
|
|
8
|
+
PROCESS_CREATION_INCLUDE_CMDLINE_VALUE: str = "ProcessCreationIncludeCmdLine_Enabled"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def enable_command_line_auditing(print_kwargs: dict = None):
|
|
12
|
+
"""
|
|
13
|
+
Enable the 'Include command line in process creation events' policy.
|
|
14
|
+
|
|
15
|
+
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v ProcessCreationIncludeCmdLine_Enabled /t REG_DWORD /d 1 /f
|
|
16
|
+
|
|
17
|
+
:param print_kwargs: Optional keyword arguments for the print function.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
if is_command_line_auditing_enabled():
|
|
21
|
+
print_api(
|
|
22
|
+
"[Include command line in process creation events] is already enabled.", color='blue',
|
|
23
|
+
**(print_kwargs or {}))
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
# Open the registry key
|
|
28
|
+
with winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, AUDITING_REG_PATH) as reg_key:
|
|
29
|
+
# Set the value
|
|
30
|
+
winreg.SetValueEx(reg_key, PROCESS_CREATION_INCLUDE_CMDLINE_VALUE, 0, winreg.REG_DWORD, 1)
|
|
31
|
+
|
|
32
|
+
print_api(
|
|
33
|
+
"Successfully enabled [Include command line in process creation events].",
|
|
34
|
+
color='green', **(print_kwargs or {}))
|
|
35
|
+
except WindowsError as e:
|
|
36
|
+
print_api(
|
|
37
|
+
f"Failed to enable [Include command line in process creation events]: {e}", error_type=True,
|
|
38
|
+
color='red', **(print_kwargs or {}))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def is_command_line_auditing_enabled():
|
|
42
|
+
try:
|
|
43
|
+
# Open the registry key
|
|
44
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, AUDITING_REG_PATH, 0, winreg.KEY_READ) as reg_key:
|
|
45
|
+
# Query the value
|
|
46
|
+
value, reg_type = winreg.QueryValueEx(reg_key, PROCESS_CREATION_INCLUDE_CMDLINE_VALUE)
|
|
47
|
+
# Check if the value is 1 (enabled)
|
|
48
|
+
return value == 1
|
|
49
|
+
except FileNotFoundError:
|
|
50
|
+
# Key or value not found, assume it's not enabled
|
|
51
|
+
return False
|
|
52
|
+
except WindowsError as e:
|
|
53
|
+
print(f"Failed to read the 'Include command line in process creation events' setting: {e}")
|
|
54
|
+
return False
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def enable_audit_process_creation(print_kwargs: dict = None):
|
|
58
|
+
"""
|
|
59
|
+
Enable the 'Audit Process Creation' policy.
|
|
60
|
+
Log: Security
|
|
61
|
+
Event ID: 4688 - A new process has been created.
|
|
62
|
+
|
|
63
|
+
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enable
|
|
64
|
+
|
|
65
|
+
:param print_kwargs: Optional keyword arguments for the print function.
|
|
66
|
+
"""
|
|
67
|
+
if is_audit_process_creation_enabled():
|
|
68
|
+
print_api("Audit Process Creation is already enabled.", color='blue', **(print_kwargs or {}))
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
# Enable "Audit Process Creation" policy
|
|
72
|
+
audit_policy_command = [
|
|
73
|
+
"auditpol", "/set", "/subcategory:Process Creation", "/success:enable", "/failure:enable"
|
|
74
|
+
]
|
|
75
|
+
try:
|
|
76
|
+
subprocess.run(audit_policy_command, check=True)
|
|
77
|
+
print_api("Successfully enabled 'Audit Process Creation'.", color='green', **(print_kwargs or {}))
|
|
78
|
+
except subprocess.CalledProcessError as e:
|
|
79
|
+
print_api(f"Failed to enable 'Audit Process Creation': {e}", error_type=True, color='red', **(print_kwargs or {}))
|
|
80
|
+
raise e
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def is_audit_process_creation_enabled(print_kwargs: dict = None) -> bool:
|
|
84
|
+
"""
|
|
85
|
+
Check if the 'Audit Process Creation' policy is enabled.
|
|
86
|
+
|
|
87
|
+
:param print_kwargs: Optional keyword arguments for the print function.
|
|
88
|
+
"""
|
|
89
|
+
# Command to check the "Audit Process Creation" policy
|
|
90
|
+
audit_policy_check_command = [
|
|
91
|
+
"auditpol", "/get", "/subcategory:Process Creation"
|
|
92
|
+
]
|
|
93
|
+
try:
|
|
94
|
+
result = subprocess.run(audit_policy_check_command, check=True, capture_output=True, text=True)
|
|
95
|
+
output = result.stdout
|
|
96
|
+
# print_api(output) # Print the output for inspection
|
|
97
|
+
|
|
98
|
+
if "Process Creation" in output and "Success and Failure" in output:
|
|
99
|
+
# print_api(
|
|
100
|
+
# "'Audit Process Creation' is enabled for both success and failure.",
|
|
101
|
+
# color='green', **(print_kwargs or {}))
|
|
102
|
+
return True
|
|
103
|
+
else:
|
|
104
|
+
# print_api(output, **(print_kwargs or {}))
|
|
105
|
+
# print_api(
|
|
106
|
+
# "'Audit Process Creation' is not fully enabled. Check the output above for details.",
|
|
107
|
+
# color='yellow', **(print_kwargs or {}))
|
|
108
|
+
return False
|
|
109
|
+
except subprocess.CalledProcessError as e:
|
|
110
|
+
print_api(f"Failed to check 'Audit Process Creation': {e}", color='red', error_type=True, **(print_kwargs or {}))
|
|
111
|
+
return False
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def enable_audit_process_termination(print_kwargs: dict = None):
|
|
115
|
+
"""
|
|
116
|
+
Enable the 'Audit Process Termination' policy.
|
|
117
|
+
|
|
118
|
+
:param print_kwargs: Optional keyword arguments for the print function.
|
|
119
|
+
"""
|
|
120
|
+
if is_audit_process_termination_enabled():
|
|
121
|
+
print_api("Audit Process Termination is already enabled.", color='blue', **(print_kwargs or {}))
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
audit_policy_command = [
|
|
125
|
+
"auditpol", "/set", "/subcategory:Process Termination", "/success:enable", "/failure:enable"
|
|
126
|
+
]
|
|
127
|
+
try:
|
|
128
|
+
subprocess.run(audit_policy_command, check=True)
|
|
129
|
+
print_api("Successfully enabled 'Audit Process Termination'.", color='green', **(print_kwargs or {}))
|
|
130
|
+
except subprocess.CalledProcessError as e:
|
|
131
|
+
print_api(f"Failed to enable 'Audit Process Termination': {e}", error_type=True, color='red', **(print_kwargs or {}))
|
|
132
|
+
raise e
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def is_audit_process_termination_enabled(print_kwargs: dict = None) -> bool:
|
|
136
|
+
"""
|
|
137
|
+
Check if the 'Audit Process Termination' policy is enabled.
|
|
138
|
+
|
|
139
|
+
:param print_kwargs: Optional keyword arguments for the print function.
|
|
140
|
+
"""
|
|
141
|
+
# Command to check the "Audit Process Creation" policy
|
|
142
|
+
audit_policy_check_command = [
|
|
143
|
+
"auditpol", "/get", "/subcategory:Process Termination"
|
|
144
|
+
]
|
|
145
|
+
try:
|
|
146
|
+
result = subprocess.run(audit_policy_check_command, check=True, capture_output=True, text=True)
|
|
147
|
+
output = result.stdout
|
|
148
|
+
# print_api(output) # Print the output for inspection
|
|
149
|
+
|
|
150
|
+
if "Process Termination" in output and "Success and Failure" in output:
|
|
151
|
+
# print_api(
|
|
152
|
+
# "'Audit Process Termination' is enabled for both success and failure.",
|
|
153
|
+
# color='green', **(print_kwargs or {}))
|
|
154
|
+
return True
|
|
155
|
+
else:
|
|
156
|
+
# print_api(output, **(print_kwargs or {}))
|
|
157
|
+
# print_api(
|
|
158
|
+
# "'Audit Process Termination' is not fully enabled. Check the output above for details.",
|
|
159
|
+
# color='yellow', **(print_kwargs or {}))
|
|
160
|
+
return False
|
|
161
|
+
except subprocess.CalledProcessError as e:
|
|
162
|
+
print_api(f"Failed to check 'Audit Process Termination': {e}", color='red', error_type=True, **(print_kwargs or {}))
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def enable_audit_filtering_platform_connection(print_kwargs: dict = None):
|
|
167
|
+
"""
|
|
168
|
+
Enable the 'Filtering Platform Connection' policy.
|
|
169
|
+
This enables you to fetch connection creations and deletions from the Windows Security Event Log.
|
|
170
|
+
Log: Security
|
|
171
|
+
Event IDs:
|
|
172
|
+
5156 - The Windows Filtering Platform has permitted a connection.
|
|
173
|
+
5158 - The Windows Filtering Platform has blocked a connection.
|
|
174
|
+
Events include information about source and destination IP addresses and ports.
|
|
175
|
+
|
|
176
|
+
auditpol /set /subcategory:"Filtering Platform Connection" /success:enable /failure:enable
|
|
177
|
+
|
|
178
|
+
:param print_kwargs: Optional keyword arguments for the print function.
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
audit_policy_command = [
|
|
182
|
+
"auditpol", "/set", '/subcategory:"Filtering Platform Connection"', "/success:enable", "/failure:enable"
|
|
183
|
+
]
|
|
184
|
+
try:
|
|
185
|
+
subprocess.run(audit_policy_command, check=True)
|
|
186
|
+
print_api("Successfully enabled 'Audit Filtering Platform Connection'.", color='green', **(print_kwargs or {}))
|
|
187
|
+
except subprocess.CalledProcessError as e:
|
|
188
|
+
print_api(f"Failed to enable 'Audit Filtering Platform Connection': {e}", error_type=True, color='red', **(print_kwargs or {}))
|
|
189
|
+
raise e
|
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import winreg
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def get_installed_software() -> list[dict]:
|
|
6
|
+
registry_path: str = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
|
|
7
|
+
data: list[dict] = []
|
|
8
|
+
|
|
9
|
+
# Open the specified registry path
|
|
10
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, registry_path) as reg_key:
|
|
11
|
+
i = 0
|
|
12
|
+
while True:
|
|
13
|
+
try:
|
|
14
|
+
# Enumerate all sub-keys
|
|
15
|
+
subkey_name = winreg.EnumKey(reg_key, i)
|
|
16
|
+
subkey_path = os.path.join(registry_path, subkey_name)
|
|
17
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, subkey_path) as subkey:
|
|
18
|
+
try:
|
|
19
|
+
# Fetch DisplayName and DisplayVersion if they exist
|
|
20
|
+
display_name, _ = winreg.QueryValueEx(subkey, "DisplayName")
|
|
21
|
+
except FileNotFoundError:
|
|
22
|
+
display_name = "N/A"
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
display_version, _ = winreg.QueryValueEx(subkey, "DisplayVersion")
|
|
26
|
+
except FileNotFoundError:
|
|
27
|
+
display_version = "N/A"
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
install_date, _ = winreg.QueryValueEx(subkey, "InstallDate")
|
|
31
|
+
except FileNotFoundError:
|
|
32
|
+
install_date = "N/A"
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
install_location, _ = winreg.QueryValueEx(subkey, "InstallLocation")
|
|
36
|
+
except FileNotFoundError:
|
|
37
|
+
install_location = "N/A"
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
install_source, _ = winreg.QueryValueEx(subkey, "InstallSource")
|
|
41
|
+
except FileNotFoundError:
|
|
42
|
+
install_source = "N/A"
|
|
43
|
+
|
|
44
|
+
if display_name != "N/A":
|
|
45
|
+
data.append({
|
|
46
|
+
"DisplayName": display_name,
|
|
47
|
+
"DisplayVersion": display_version,
|
|
48
|
+
"InstallDate": install_date,
|
|
49
|
+
"SubkeyName": subkey_name,
|
|
50
|
+
"InstallLocation": install_location,
|
|
51
|
+
"InstallSource": install_source
|
|
52
|
+
})
|
|
53
|
+
except OSError:
|
|
54
|
+
break # No more subkeys
|
|
55
|
+
|
|
56
|
+
i += 1
|
|
57
|
+
|
|
58
|
+
return data
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import winreg
|
|
2
|
+
import socket
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def get_network_interfaces_settings(
|
|
6
|
+
interface_guid: str = None
|
|
7
|
+
) -> dict:
|
|
8
|
+
"""
|
|
9
|
+
Get network interface settings from the Windows registry.
|
|
10
|
+
|
|
11
|
+
:param interface_guid: str, GUID of the network interface to retrieve settings for.
|
|
12
|
+
If None, settings for all interfaces will be retrieved.
|
|
13
|
+
:return: dict, network interface settings.
|
|
14
|
+
"""
|
|
15
|
+
registry_path = r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
|
|
16
|
+
network_info = {}
|
|
17
|
+
|
|
18
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, registry_path) as interfaces_key:
|
|
19
|
+
interface_count = winreg.QueryInfoKey(interfaces_key)[0]
|
|
20
|
+
|
|
21
|
+
for i in range(interface_count):
|
|
22
|
+
current_interface_guid = winreg.EnumKey(interfaces_key, i)
|
|
23
|
+
|
|
24
|
+
# If an interface GUID is provided, and it doesn't match the current one, skip it
|
|
25
|
+
if interface_guid and interface_guid != current_interface_guid:
|
|
26
|
+
continue
|
|
27
|
+
|
|
28
|
+
interface_path = f"{registry_path}\\{current_interface_guid}"
|
|
29
|
+
interface_data = {}
|
|
30
|
+
|
|
31
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, interface_path) as key:
|
|
32
|
+
value_count = winreg.QueryInfoKey(key)[1]
|
|
33
|
+
|
|
34
|
+
for j in range(value_count):
|
|
35
|
+
value_name, value_data, _ = winreg.EnumValue(key, j)
|
|
36
|
+
interface_data[value_name] = value_data
|
|
37
|
+
|
|
38
|
+
# Populate the dictionary for the current interface
|
|
39
|
+
network_info[current_interface_guid] = interface_data
|
|
40
|
+
|
|
41
|
+
return network_info
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_network_connections_to_guids() -> dict:
|
|
45
|
+
"""
|
|
46
|
+
Get a dictionary mapping network connection names to their corresponding GUIDs.
|
|
47
|
+
|
|
48
|
+
:return: dict, GUIDs to connection names.
|
|
49
|
+
"""
|
|
50
|
+
adapters = {}
|
|
51
|
+
registry_path = r"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}"
|
|
52
|
+
|
|
53
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, registry_path) as network_key:
|
|
54
|
+
adapter_count = winreg.QueryInfoKey(network_key)[0]
|
|
55
|
+
|
|
56
|
+
for i in range(adapter_count):
|
|
57
|
+
adapter_guid = winreg.EnumKey(network_key, i)
|
|
58
|
+
adapter_path = f"{registry_path}\\{adapter_guid}\\Connection"
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, adapter_path) as connection_key:
|
|
62
|
+
adapter_name, _ = winreg.QueryValueEx(connection_key, "Name")
|
|
63
|
+
adapters[adapter_guid] = adapter_name
|
|
64
|
+
except FileNotFoundError:
|
|
65
|
+
# Some GUIDs might not have a corresponding 'Connection' key, so we skip them
|
|
66
|
+
continue
|
|
67
|
+
|
|
68
|
+
return adapters
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_enum_info_by_pnpinstanceid(
|
|
72
|
+
pnp_instance_id: str
|
|
73
|
+
) -> dict:
|
|
74
|
+
"""
|
|
75
|
+
Get all information from the Enum registry key for a device with a specific PnPInstanceId.
|
|
76
|
+
|
|
77
|
+
:param pnp_instance_id: str, PnPInstanceId of the device.
|
|
78
|
+
:return: dict, device information.
|
|
79
|
+
"""
|
|
80
|
+
enum_registry_path = r"SYSTEM\CurrentControlSet\Enum"
|
|
81
|
+
device_info = {}
|
|
82
|
+
|
|
83
|
+
# Construct the full path to the device in the Enum registry
|
|
84
|
+
hardware_path = f"{enum_registry_path}\\{pnp_instance_id}"
|
|
85
|
+
|
|
86
|
+
# Open the registry key corresponding to the device
|
|
87
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, hardware_path) as hardware_key:
|
|
88
|
+
num_values = winreg.QueryInfoKey(hardware_key)[1]
|
|
89
|
+
|
|
90
|
+
# Retrieve all values under this key
|
|
91
|
+
for i in range(num_values):
|
|
92
|
+
value_name, value_data, _ = winreg.EnumValue(hardware_key, i)
|
|
93
|
+
device_info[value_name] = value_data
|
|
94
|
+
|
|
95
|
+
return device_info
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_network_connections_details(get_enum_info: bool = True) -> dict:
|
|
99
|
+
"""
|
|
100
|
+
Get network adapter details from the Windows registry.
|
|
101
|
+
|
|
102
|
+
:param get_enum_info: bool, if True, retrieve all information from the corresponding Enum key.
|
|
103
|
+
This is useful for getting additional information about the network adapter, like make, model, diver details.
|
|
104
|
+
:return: dict, network adapter details.
|
|
105
|
+
"""
|
|
106
|
+
adapter_details = {}
|
|
107
|
+
network_registry_path = r"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}"
|
|
108
|
+
|
|
109
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, network_registry_path) as network_key:
|
|
110
|
+
adapter_count = winreg.QueryInfoKey(network_key)[0]
|
|
111
|
+
|
|
112
|
+
for i in range(adapter_count):
|
|
113
|
+
adapter_guid = winreg.EnumKey(network_key, i)
|
|
114
|
+
adapter_path = f"{network_registry_path}\\{adapter_guid}\\Connection"
|
|
115
|
+
|
|
116
|
+
try:
|
|
117
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, adapter_path) as connection_key:
|
|
118
|
+
adapter_name, _ = winreg.QueryValueEx(connection_key, "Name")
|
|
119
|
+
pnp_instance_id, _ = winreg.QueryValueEx(connection_key, "PnPInstanceId")
|
|
120
|
+
|
|
121
|
+
# Get all information from the corresponding Enum key
|
|
122
|
+
if get_enum_info:
|
|
123
|
+
enum_info: dict = get_enum_info_by_pnpinstanceid(pnp_instance_id)
|
|
124
|
+
else:
|
|
125
|
+
enum_info: dict = {}
|
|
126
|
+
|
|
127
|
+
# Store the retrieved information
|
|
128
|
+
adapter_details[adapter_guid] = {
|
|
129
|
+
"Name": adapter_name,
|
|
130
|
+
"PnPInstanceId": pnp_instance_id,
|
|
131
|
+
"EnumInfo": enum_info
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
except FileNotFoundError:
|
|
135
|
+
continue
|
|
136
|
+
|
|
137
|
+
return adapter_details
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _get_default_dns_gateway() -> tuple[bool, list[str]]:
|
|
141
|
+
"""
|
|
142
|
+
NOTICE: This stopped working from the last Windows update on 11.06.2025.
|
|
143
|
+
They moved it to 'ProfileNameServer', anyway Since Windows 8 the recommended API has been the WMI
|
|
144
|
+
NetTCPIP CIM provider (MSFT_DNSClientServerAddress) - didn't test it though.
|
|
145
|
+
Just moved to netsh wrapping for now.
|
|
146
|
+
|
|
147
|
+
Get the default DNS gateway from the Windows registry.
|
|
148
|
+
|
|
149
|
+
:return: tuple(is dynamic boolean, list of DNS server IPv4s).
|
|
150
|
+
If nothing found will return (None, None).
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
def get_current_interface_status(current_interface_settings: dict) -> tuple[bool, list[str]]:
|
|
154
|
+
if current_interface_settings['NameServer']:
|
|
155
|
+
result = (False, current_interface_settings['NameServer'].split(','))
|
|
156
|
+
else:
|
|
157
|
+
result = (True, current_interface_settings['DhcpNameServer'].split(','))
|
|
158
|
+
|
|
159
|
+
return result
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# Get current default IPv4 address of the interface that is being used for internet.
|
|
163
|
+
default_ipv4_address: str = socket.gethostbyname(socket.gethostname())
|
|
164
|
+
# If the default IPv4 address is localhost, then it could mean that the system is not connected to the internet.
|
|
165
|
+
# Or there is no network adapter at all.
|
|
166
|
+
default_dns_gateway_list: list[str] = []
|
|
167
|
+
if default_ipv4_address == '127.0.0.1':
|
|
168
|
+
from ... import dns
|
|
169
|
+
default_dns_gateway_list = dns.get_default_dns_gateway_with_dns_resolver()
|
|
170
|
+
|
|
171
|
+
# Get all network interface settings from the registry.
|
|
172
|
+
all_interfaces_configurations = get_network_interfaces_settings()
|
|
173
|
+
|
|
174
|
+
# Find the interface that has this IPv4 assigned.
|
|
175
|
+
function_result: tuple = tuple()
|
|
176
|
+
for interface_guid, interface_settings in all_interfaces_configurations.items():
|
|
177
|
+
if not interface_settings:
|
|
178
|
+
continue
|
|
179
|
+
|
|
180
|
+
if ' ' in interface_settings['NameServer']:
|
|
181
|
+
interface_settings['NameServer'] = interface_settings['NameServer'].replace(' ', ',')
|
|
182
|
+
if 'DhcpNameServer' in interface_settings and ' ' in interface_settings['DhcpNameServer']:
|
|
183
|
+
interface_settings['DhcpNameServer'] = interface_settings['DhcpNameServer'].replace(' ', ',')
|
|
184
|
+
|
|
185
|
+
if not default_dns_gateway_list:
|
|
186
|
+
current_interface_static_ipv4_address: list = interface_settings.get('IPAddress', None)
|
|
187
|
+
current_interface_dynamic_ipv4_address: str = interface_settings.get('DhcpIPAddress', None)
|
|
188
|
+
|
|
189
|
+
static_and_ip_match: bool = (
|
|
190
|
+
current_interface_static_ipv4_address and
|
|
191
|
+
current_interface_static_ipv4_address[0] == default_ipv4_address)
|
|
192
|
+
dynamic_and_ip_match: bool = (
|
|
193
|
+
current_interface_dynamic_ipv4_address and
|
|
194
|
+
current_interface_dynamic_ipv4_address == default_ipv4_address)
|
|
195
|
+
if static_and_ip_match or dynamic_and_ip_match:
|
|
196
|
+
function_result = get_current_interface_status(interface_settings)
|
|
197
|
+
|
|
198
|
+
break
|
|
199
|
+
else:
|
|
200
|
+
current_interface_name_server_list: list[str] = interface_settings['NameServer'].split(',')
|
|
201
|
+
current_interface_dhcp_name_server_list: list[str] = interface_settings['DhcpNameServer'].split(',')
|
|
202
|
+
if (current_interface_name_server_list == default_dns_gateway_list or
|
|
203
|
+
current_interface_dhcp_name_server_list == default_dns_gateway_list):
|
|
204
|
+
function_result = get_current_interface_status(interface_settings)
|
|
205
|
+
|
|
206
|
+
break
|
|
207
|
+
|
|
208
|
+
if not function_result:
|
|
209
|
+
function_result = (None, None)
|
|
210
|
+
|
|
211
|
+
# noinspection PyTypeChecker
|
|
212
|
+
return function_result
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def change_metric_of_network_adapter(
|
|
216
|
+
adapter_guid: str,
|
|
217
|
+
metric: int
|
|
218
|
+
) -> None:
|
|
219
|
+
"""
|
|
220
|
+
Change the metric of a network adapter.
|
|
221
|
+
After you set new metric you need to restart the network adapter for the changes to take effect.
|
|
222
|
+
|
|
223
|
+
:param adapter_guid: str, GUID of the network adapter.
|
|
224
|
+
:param metric: int, new metric value.
|
|
225
|
+
:return: None
|
|
226
|
+
"""
|
|
227
|
+
|
|
228
|
+
reg_path = fr"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{adapter_guid}"
|
|
229
|
+
|
|
230
|
+
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_path, 0, winreg.KEY_SET_VALUE) as key:
|
|
231
|
+
winreg.SetValueEx(key, "UseAutomaticMetric", 0, winreg.REG_DWORD, 0)
|
|
232
|
+
winreg.SetValueEx(key, "InterfaceMetric", 0, winreg.REG_DWORD, metric)
|
|
@@ -1,65 +1,47 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: atomicshop
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.10.5
|
|
4
4
|
Summary: Atomic functions and classes to make developer life easier
|
|
5
5
|
Author: Denis Kras
|
|
6
|
-
License: MIT
|
|
7
|
-
|
|
8
|
-
Copyright (c) 2023 Bugsec, Denis Kras
|
|
9
|
-
|
|
10
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
-
in the Software without restriction, including without limitation the rights
|
|
13
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
-
furnished to do so, subject to the following conditions:
|
|
16
|
-
|
|
17
|
-
The above copyright notice and this permission notice shall be included in all
|
|
18
|
-
copies or substantial portions of the Software.
|
|
19
|
-
|
|
20
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
-
SOFTWARE.
|
|
6
|
+
License-Expression: MIT
|
|
27
7
|
Project-URL: Homepage, https://github.com/BugSec-Official/atomicshop
|
|
28
8
|
Classifier: Intended Audience :: Developers
|
|
29
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
30
9
|
Classifier: Programming Language :: Python :: 3
|
|
31
10
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
32
|
-
Requires-Python:
|
|
11
|
+
Requires-Python: <3.14,>=3.12
|
|
33
12
|
Description-Content-Type: text/markdown
|
|
34
13
|
License-File: LICENSE.txt
|
|
35
14
|
Requires-Dist: wheel
|
|
36
|
-
Requires-Dist:
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist:
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist:
|
|
15
|
+
Requires-Dist: setuptools
|
|
16
|
+
Requires-Dist: beautifulsoup4==4.14.3
|
|
17
|
+
Requires-Dist: cryptography==46.0.3
|
|
18
|
+
Requires-Dist: dkarchiver==1.0.1
|
|
19
|
+
Requires-Dist: dkinst
|
|
20
|
+
Requires-Dist: dnslib==0.9.26
|
|
21
|
+
Requires-Dist: dnspython==2.8.0
|
|
22
|
+
Requires-Dist: docker==7.1.0
|
|
23
|
+
Requires-Dist: flask_socketio==5.5.1
|
|
24
|
+
Requires-Dist: google-api-python-client==2.187.0
|
|
25
|
+
Requires-Dist: google-genai==1.53.0
|
|
26
|
+
Requires-Dist: icmplib==3.0.4
|
|
41
27
|
Requires-Dist: numpy
|
|
42
|
-
Requires-Dist: olefile
|
|
43
|
-
Requires-Dist: openpyxl
|
|
44
|
-
Requires-Dist: pandas
|
|
45
|
-
Requires-Dist: paramiko
|
|
46
|
-
Requires-Dist:
|
|
47
|
-
Requires-Dist: playwright
|
|
48
|
-
Requires-Dist:
|
|
49
|
-
Requires-Dist:
|
|
50
|
-
Requires-Dist:
|
|
51
|
-
Requires-Dist: pyautogui
|
|
52
|
-
Requires-Dist: pyopenssl
|
|
53
|
-
Requires-Dist: python-bidi
|
|
28
|
+
Requires-Dist: olefile==0.47
|
|
29
|
+
Requires-Dist: openpyxl==3.1.5
|
|
30
|
+
Requires-Dist: pandas==2.3.3
|
|
31
|
+
Requires-Dist: paramiko==4.0.0
|
|
32
|
+
Requires-Dist: pefile==2024.8.26
|
|
33
|
+
Requires-Dist: playwright==1.56.0
|
|
34
|
+
Requires-Dist: psutil==7.1.3
|
|
35
|
+
Requires-Dist: pymongo==4.15.5
|
|
36
|
+
Requires-Dist: pyopenssl==25.3.0
|
|
54
37
|
Requires-Dist: python-docx
|
|
55
|
-
Requires-Dist:
|
|
56
|
-
Requires-Dist: reportlab
|
|
57
|
-
Requires-Dist: setuptools
|
|
38
|
+
Requires-Dist: pywin32==311; platform_system == "Windows"
|
|
58
39
|
Requires-Dist: SoundCard
|
|
59
40
|
Requires-Dist: soundfile
|
|
60
41
|
Requires-Dist: SpeechRecognition
|
|
61
|
-
Requires-Dist: tldextract
|
|
62
|
-
Requires-Dist:
|
|
42
|
+
Requires-Dist: tldextract==5.3.0
|
|
43
|
+
Requires-Dist: websockets==15.0.1
|
|
44
|
+
Dynamic: license-file
|
|
63
45
|
|
|
64
46
|
<h1 align="center">Atomic Workshop</h1>
|
|
65
47
|
|
|
@@ -151,9 +133,9 @@ To get a local copy up and running follow these simple steps.
|
|
|
151
133
|
```
|
|
152
134
|
|
|
153
135
|
The latest version on PyPI is 0.2, so you will need to install from GitHub.
|
|
154
|
-
Alternatively, you can use a
|
|
136
|
+
Alternatively, you can use a command anywhere in CMD after 'atomicshop' installation:
|
|
155
137
|
```sh
|
|
156
|
-
|
|
138
|
+
pywintrace install
|
|
157
139
|
```
|
|
158
140
|
|
|
159
141
|
4. If you get an exception while installing the 'psycopg2' package on ubuntu, install this binary:
|