atomicshop 3.3.28__py3-none-any.whl → 3.10.0__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.

Files changed (99) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/a_mains/get_local_tcp_ports.py +85 -0
  3. atomicshop/a_mains/install_ca_certificate.py +172 -0
  4. atomicshop/a_mains/process_from_port.py +119 -0
  5. atomicshop/a_mains/set_default_dns_gateway.py +90 -0
  6. atomicshop/basics/strings.py +1 -1
  7. atomicshop/certificates.py +2 -2
  8. atomicshop/dns.py +26 -28
  9. atomicshop/etws/traces/trace_tcp.py +1 -2
  10. atomicshop/mitm/centered_settings.py +133 -0
  11. atomicshop/mitm/config_static.py +18 -43
  12. atomicshop/mitm/connection_thread_worker.py +376 -162
  13. atomicshop/mitm/engines/__parent/recorder___parent.py +1 -1
  14. atomicshop/mitm/engines/__parent/requester___parent.py +1 -1
  15. atomicshop/mitm/engines/__parent/responder___parent.py +15 -2
  16. atomicshop/mitm/engines/create_module_template.py +1 -2
  17. atomicshop/mitm/import_config.py +79 -88
  18. atomicshop/mitm/initialize_engines.py +1 -2
  19. atomicshop/mitm/message.py +5 -4
  20. atomicshop/mitm/mitm_main.py +222 -121
  21. atomicshop/mitm/recs_files.py +61 -5
  22. atomicshop/mitm/ssh_tester.py +82 -0
  23. atomicshop/networks.py +108 -93
  24. atomicshop/package_mains_processor.py +84 -0
  25. atomicshop/permissions/ubuntu_permissions.py +47 -0
  26. atomicshop/print_api.py +3 -5
  27. atomicshop/python_functions.py +23 -108
  28. atomicshop/speech_recognize.py +8 -0
  29. atomicshop/ssh_remote.py +115 -51
  30. atomicshop/web.py +20 -7
  31. atomicshop/web_apis/google_llm.py +22 -14
  32. atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py +2 -1
  33. atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py +2 -1
  34. atomicshop/wrappers/dockerw/dockerw.py +2 -2
  35. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +5 -5
  36. atomicshop/wrappers/githubw.py +175 -63
  37. atomicshop/wrappers/loggingw/handlers.py +1 -1
  38. atomicshop/wrappers/loggingw/loggingw.py +17 -1
  39. atomicshop/wrappers/netshw.py +124 -3
  40. atomicshop/wrappers/playwrightw/scenarios.py +1 -1
  41. atomicshop/wrappers/powershell_networking.py +80 -0
  42. atomicshop/wrappers/psutilw/psutil_networks.py +9 -0
  43. atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
  44. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +3 -105
  45. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +3 -57
  46. atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +12 -27
  47. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +15 -9
  48. atomicshop/wrappers/socketw/certificator.py +19 -9
  49. atomicshop/wrappers/socketw/creator.py +30 -7
  50. atomicshop/wrappers/socketw/dns_server.py +6 -6
  51. atomicshop/wrappers/socketw/exception_wrapper.py +3 -3
  52. atomicshop/wrappers/socketw/process_getter.py +86 -0
  53. atomicshop/wrappers/socketw/receiver.py +29 -9
  54. atomicshop/wrappers/socketw/sender.py +10 -9
  55. atomicshop/wrappers/socketw/sni.py +23 -6
  56. atomicshop/wrappers/socketw/{base.py → socket_base.py} +33 -1
  57. atomicshop/wrappers/socketw/socket_client.py +6 -8
  58. atomicshop/wrappers/socketw/socket_wrapper.py +82 -21
  59. atomicshop/wrappers/socketw/ssl_base.py +6 -2
  60. atomicshop/wrappers/win_auditw.py +189 -0
  61. {atomicshop-3.3.28.dist-info → atomicshop-3.10.0.dist-info}/METADATA +25 -30
  62. {atomicshop-3.3.28.dist-info → atomicshop-3.10.0.dist-info}/RECORD +74 -88
  63. atomicshop/_basics_temp.py +0 -101
  64. atomicshop/a_installs/ubuntu/docker_rootless.py +0 -11
  65. atomicshop/a_installs/ubuntu/docker_sudo.py +0 -11
  66. atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh +0 -3
  67. atomicshop/addons/package_setup/CreateWheel.cmd +0 -7
  68. atomicshop/addons/package_setup/Setup in Edit mode.cmd +0 -6
  69. atomicshop/addons/package_setup/Setup.cmd +0 -7
  70. atomicshop/archiver/__init__.py +0 -0
  71. atomicshop/archiver/_search_in_zip.py +0 -189
  72. atomicshop/archiver/search_in_archive.py +0 -284
  73. atomicshop/archiver/sevenz_app_w.py +0 -86
  74. atomicshop/archiver/sevenzs.py +0 -73
  75. atomicshop/archiver/shutils.py +0 -34
  76. atomicshop/archiver/zips.py +0 -353
  77. atomicshop/file_types.py +0 -24
  78. atomicshop/pbtkmultifile_argparse.py +0 -88
  79. atomicshop/script_as_string_processor.py +0 -42
  80. atomicshop/ssh_scripts/process_from_ipv4.py +0 -37
  81. atomicshop/ssh_scripts/process_from_port.py +0 -27
  82. atomicshop/wrappers/_process_wrapper_curl.py +0 -27
  83. atomicshop/wrappers/_process_wrapper_tar.py +0 -21
  84. atomicshop/wrappers/dockerw/install_docker.py +0 -449
  85. atomicshop/wrappers/ffmpegw.py +0 -125
  86. atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
  87. atomicshop/wrappers/socketw/get_process.py +0 -123
  88. /atomicshop/{addons → a_mains/addons}/PlayWrightCodegen.cmd +0 -0
  89. /atomicshop/{addons → a_mains/addons}/ScriptExecution.cmd +0 -0
  90. /atomicshop/{addons → a_mains/addons}/inits/init_to_import_all_modules.py +0 -0
  91. /atomicshop/{addons → a_mains/addons}/process_list/ReadMe.txt +0 -0
  92. /atomicshop/{addons → a_mains/addons}/process_list/compile.cmd +0 -0
  93. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.dll +0 -0
  94. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.exp +0 -0
  95. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.lib +0 -0
  96. /atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +0 -0
  97. {atomicshop-3.3.28.dist-info → atomicshop-3.10.0.dist-info}/WHEEL +0 -0
  98. {atomicshop-3.3.28.dist-info → atomicshop-3.10.0.dist-info}/licenses/LICENSE.txt +0 -0
  99. {atomicshop-3.3.28.dist-info → atomicshop-3.10.0.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,5 @@
1
1
  import multiprocessing
2
2
  import threading
3
- import time
4
-
5
3
  import select
6
4
  from typing import Literal, Union, Callable, Any
7
5
  from pathlib import Path
@@ -9,17 +7,20 @@ import socket
9
7
  import shutil
10
8
  import os
11
9
 
10
+ import paramiko
11
+
12
12
  from ...mitm import initialize_engines
13
13
  from ..psutilw import psutil_networks
14
14
  from ..certauthw import certauthw
15
15
  from ..loggingw import loggingw
16
- from ...script_as_string_processor import ScriptAsStringProcessor
16
+ from ... import package_mains_processor
17
17
  from ...permissions import permissions
18
18
  from ... import filesystem, certificates
19
19
  from ...basics import booleans, tracebacks
20
20
  from ...print_api import print_api
21
+ from ...ssh_remote import SSHRemote
21
22
 
22
- from . import base, creator, get_process, accepter, statistics_csv, ssl_base, sni
23
+ from . import socket_base, creator, process_getter, accepter, statistics_csv, ssl_base, sni
23
24
 
24
25
 
25
26
  class SocketWrapperPortInUseError(Exception):
@@ -67,10 +68,7 @@ class SocketWrapper:
67
68
  ssh_user: str = None,
68
69
  ssh_pass: str = None,
69
70
  ssh_script_to_execute: Union[
70
- Literal[
71
- 'process_from_port',
72
- 'process_from_ipv4'
73
- ],
71
+ Literal['process_from_port'],
74
72
  None
75
73
  ] = None,
76
74
  logs_directory: str = None,
@@ -80,6 +78,8 @@ class SocketWrapper:
80
78
  statistics_logger_queue: multiprocessing.Queue = None,
81
79
  exceptions_logger_name: str = 'SocketWrapperExceptions',
82
80
  exceptions_logger_queue: multiprocessing.Queue = None,
81
+ enable_sslkeylogfile_env_to_client_ssl_context: bool = False,
82
+ sslkeylog_file_path: str = None,
83
83
  print_kwargs: dict = None,
84
84
  ):
85
85
  """
@@ -173,6 +173,12 @@ class SocketWrapper:
173
173
  :param exceptions_logger_name: string, name of the logger that will be used to log exceptions.
174
174
  :param exceptions_logger_queue: multiprocessing.Queue, queue that will be used to log exceptions in
175
175
  multiprocessing. You need to start the logger listener in the main process to handle the queue.
176
+ :param enable_sslkeylogfile_env_to_client_ssl_context: boolean, if True, each client SSL context
177
+ that will be created by the SocketWrapper will have save the SSL handshake keys to the file
178
+ defined in 'sslkeylog_file_path' parameter.
179
+ :param sslkeylog_file_path: string, path to file where SSL handshake keys will be saved.
180
+ If not provided and 'enable_sslkeylogfile_env_to_client_ssl_context' is True, then
181
+ the environment variable 'SSLKEYLOGFILE' will be used.
176
182
  :param print_kwargs: dict, additional arguments to pass to the print function.
177
183
  """
178
184
 
@@ -208,6 +214,9 @@ class SocketWrapper:
208
214
  self.ssh_script_to_execute = ssh_script_to_execute
209
215
  self.forwarding_dns_service_ipv4_list___only_for_localhost = (
210
216
  forwarding_dns_service_ipv4_list___only_for_localhost)
217
+ self.enable_sslkeylogfile_env_to_client_ssl_context: bool = (
218
+ enable_sslkeylogfile_env_to_client_ssl_context)
219
+ self.sslkeylog_file_path: str = sslkeylog_file_path
211
220
  self.print_kwargs: dict = print_kwargs
212
221
 
213
222
  self.socket_object = None
@@ -226,12 +235,17 @@ class SocketWrapper:
226
235
  # Defining listening sockets list, which will be used with "select" library in 'loop_for_incoming_sockets'.
227
236
  self.listening_sockets: list = list()
228
237
 
229
- # Defining 'ssh_script_processor' variable, which will be used to process SSH scripts.
238
+ # Defining 'ssh_script_string' variable, which will be used to process SSH scripts.
230
239
  self.ssh_script_processor = None
231
240
  if self.get_process_name:
232
241
  # noinspection PyTypeChecker
233
- self.ssh_script_processor = \
234
- ScriptAsStringProcessor().read_script_to_string(self.ssh_script_to_execute)
242
+ self.package_processor: package_mains_processor.PackageMainsProcessor | None = package_mains_processor.PackageMainsProcessor(script_file_stem=self.ssh_script_to_execute)
243
+
244
+ else:
245
+ self.package_processor = None
246
+
247
+ # We will initialize it during the first 'get_process_name' function call.
248
+ self.ssh_client: SSHRemote | None = None
235
249
 
236
250
  # If logs directory was not set, we will use the working directory.
237
251
  if not logs_directory:
@@ -551,8 +565,12 @@ class SocketWrapper:
551
565
  print_kwargs={'logger': self.logger})
552
566
 
553
567
  source_ip: str = client_address[0]
568
+ source_port: int = client_address[1]
554
569
  dest_port: int = listening_socket_object.getsockname()[1]
555
570
 
571
+ message: str = f"Accepted connection from [{source_ip}:{source_port}] to [{listening_ip}:{dest_port}] | domain: {domain_from_engine}"
572
+ print_api(message, logger=self.logger)
573
+
556
574
  # Not always there will be a hostname resolved by the IP address, so we will leave it empty if it fails.
557
575
  try:
558
576
  source_hostname = socket.gethostbyaddr(source_ip)[0]
@@ -564,21 +582,61 @@ class SocketWrapper:
564
582
  # SSH Remote / LOCALHOST script execution to identify process section.
565
583
  # If 'get_process_name' was set to True, then this will be executed.
566
584
  if self.get_process_name:
585
+ # Initializing SSHRemote class if not initialized.
586
+ if self.ssh_client is None:
587
+ self.ssh_client = SSHRemote(
588
+ ip_address=source_ip, username=self.ssh_user, password=self.ssh_pass, logger=self.logger)
589
+
567
590
  # Get the process name from the socket.
568
- get_command_instance = get_process.GetCommandLine(
569
- client_socket=client_socket,
570
- ssh_script_processor=self.ssh_script_processor,
571
- ssh_user=self.ssh_user,
572
- ssh_pass=self.ssh_pass,
591
+ get_command_instance = process_getter.GetCommandLine(
592
+ client_ip=source_ip,
593
+ client_port=source_port,
594
+ package_processor=self.package_processor,
595
+ ssh_client=self.ssh_client,
573
596
  logger=self.logger)
574
597
  process_name = get_command_instance.get_process_name(print_kwargs={'logger': self.logger})
575
598
 
599
+ # from ..pywin32w.win_event_log import fetch
600
+ # events = fetch.get_latest_events(
601
+ # server_ip=source_ip,
602
+ # username=self.ssh_user,
603
+ # password=self.ssh_pass,
604
+ # log_name='Security',
605
+ # count=50,
606
+ # event_id_list=[5156]
607
+ # )
608
+ #
609
+ # source_port = client_address[1]
610
+ # for event in events:
611
+ # if source_port == event['StringsDict']['Source Port']:
612
+ # process_name = event['StringsDict']['Application Name']
613
+ # break
614
+ #
615
+ # if process_name == '':
616
+ # raise RuntimeError("Failed to get process name from the remote host via Event Log.")
617
+
576
618
  # If 'accept()' function worked well, SSL worked well, then 'client_socket' won't be empty.
577
619
  if client_socket:
578
620
  # Get the protocol type from the socket.
579
621
  is_tls: bool = False
580
622
 
581
- tls_properties = ssl_base.is_tls(client_socket)
623
+ try:
624
+ tls_properties = ssl_base.is_tls(client_socket, timeout=1)
625
+ except TimeoutError:
626
+ error: str = "TimeoutError: TLS detection timed out. Dropping accepted socket."
627
+ self.logger.error(error)
628
+
629
+ self.statistics_writer.write_accept_error(
630
+ engine=engine_name,
631
+ source_host=source_hostname,
632
+ source_ip=source_ip,
633
+ error_message=error,
634
+ dest_port=str(dest_port),
635
+ host=domain_from_engine,
636
+ process_name=process_name)
637
+
638
+ client_socket.close()
639
+ continue
582
640
 
583
641
  if tls_properties:
584
642
  is_tls = True
@@ -616,7 +674,9 @@ class SocketWrapper:
616
674
  forwarding_dns_service_ipv4_list___only_for_localhost=(
617
675
  self.forwarding_dns_service_ipv4_list___only_for_localhost),
618
676
  tls=is_tls,
619
- exceptions_logger=self.exceptions_logger
677
+ exceptions_logger=self.exceptions_logger,
678
+ enable_sslkeylogfile_env_to_client_ssl_context=self.enable_sslkeylogfile_env_to_client_ssl_context,
679
+ sslkeylog_file_path=self.sslkeylog_file_path
620
680
  )
621
681
 
622
682
  ssl_client_socket, accept_error_message = \
@@ -678,7 +738,7 @@ class SocketWrapper:
678
738
  self.threads_list.append(thread_current)
679
739
 
680
740
  # 'thread_callable_args[1][0]' is the client socket.
681
- client_address = base.get_source_address_from_socket(client_socket)
741
+ client_address = socket_base.get_source_address_from_socket(client_socket)
682
742
 
683
743
  self.logger.info(f"Accepted connection, thread created {client_address}. Continue listening...")
684
744
  # Else, if no client_socket was opened during, accept, then print the error.
@@ -692,7 +752,8 @@ class SocketWrapper:
692
752
  dest_port=str(dest_port),
693
753
  host=domain_from_engine,
694
754
  process_name=process_name)
695
- except ConnectionResetError as e:
755
+ # Sometimes paramiko SSH connection return EOFError on connection reset, so we need to catch it separately.
756
+ except (ConnectionResetError, paramiko.ssh_exception.SSHException, EOFError) as e:
696
757
  exception_string: str = tracebacks.get_as_string()
697
758
  full_string: str = f"{str(e)} | {exception_string}"
698
759
  self.statistics_writer.write_accept_error(
@@ -726,7 +787,7 @@ def before_socket_thread_worker(
726
787
  try:
727
788
  callable_function(*callable_args)
728
789
  except Exception as e:
729
- exceptions_logger.write(e)
790
+ exceptions_logger.write(e, custom_exception_attribute='engine_name', custom_exception_attribute_placement='before')
730
791
 
731
792
 
732
793
  def get_engine_name(domain: str, engine_list: list):
@@ -24,15 +24,19 @@ def convert_der_x509_bytes_to_pem_string(certificate) -> str:
24
24
  return ssl.DER_cert_to_PEM_cert(certificate)
25
25
 
26
26
 
27
- def is_tls(client_socket) -> Optional[Tuple[str, str]]:
27
+ def is_tls(
28
+ client_socket,
29
+ timeout: float = None
30
+ ) -> Optional[Tuple[str, str]]:
28
31
  """
29
32
  Return protocol type of the incoming socket after 'accept()'.
30
33
  :param client_socket: incoming socket after 'accept()'.
34
+ :param timeout: optional timeout for receiving/peeking the first bytes.
31
35
  :return: tuple with content type, protocol type + version.
32
36
  If the length of the first bytes is less than 3, return None.
33
37
  """
34
38
 
35
- first_bytes = receiver.peek_first_bytes(client_socket, bytes_amount=3)
39
+ first_bytes = receiver.peek_first_bytes(client_socket, bytes_amount=3, timeout=timeout)
36
40
 
37
41
  # Sometimes only one byte is available, so we need to handle that case.
38
42
  # convert to a tuple of ints, add three Nones, and keep only the first 3 items.
@@ -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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atomicshop
3
- Version: 3.3.28
3
+ Version: 3.10.0
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License-Expression: MIT
@@ -8,44 +8,39 @@ Project-URL: Homepage, https://github.com/BugSec-Official/atomicshop
8
8
  Classifier: Intended Audience :: Developers
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
11
- Requires-Python: <3.13,>=3.10
11
+ Requires-Python: <3.14,>=3.12
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE.txt
14
14
  Requires-Dist: wheel
15
- Requires-Dist: beautifulsoup4
16
- Requires-Dist: cryptography
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
17
19
  Requires-Dist: dkinst
18
- Requires-Dist: dnslib
19
- Requires-Dist: dnspython
20
- Requires-Dist: docker
21
- Requires-Dist: flask_socketio
22
- Requires-Dist: google-api-python-client
23
- Requires-Dist: google-generativeai
24
- Requires-Dist: icmplib
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
25
27
  Requires-Dist: numpy
26
- Requires-Dist: olefile
27
- Requires-Dist: openpyxl
28
- Requires-Dist: pandas
29
- Requires-Dist: paramiko
30
- Requires-Dist: pefile
31
- Requires-Dist: playwright
32
- Requires-Dist: protobuf
33
- Requires-Dist: psutil
34
- Requires-Dist: py7zr==0.22.0
35
- Requires-Dist: pyautogui
36
- Requires-Dist: pymongo
37
- Requires-Dist: pyopenssl
38
- 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
39
37
  Requires-Dist: python-docx
40
- Requires-Dist: python-magic
41
- Requires-Dist: pywin32; platform_system == "Windows"
42
- Requires-Dist: reportlab
43
- Requires-Dist: setuptools
38
+ Requires-Dist: pywin32==311; platform_system == "Windows"
44
39
  Requires-Dist: SoundCard
45
40
  Requires-Dist: soundfile
46
41
  Requires-Dist: SpeechRecognition
47
- Requires-Dist: tldextract
48
- Requires-Dist: websockets
42
+ Requires-Dist: tldextract==5.3.0
43
+ Requires-Dist: websockets==15.0.1
49
44
  Dynamic: license-file
50
45
 
51
46
  <h1 align="center">Atomic Workshop</h1>