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.
Files changed (268) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
  3. atomicshop/a_mains/addons/process_list/compile.cmd +7 -0
  4. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.dll +0 -0
  5. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.exp +0 -0
  6. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.lib +0 -0
  7. atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +8 -1
  8. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  9. atomicshop/a_mains/get_local_tcp_ports.py +85 -0
  10. atomicshop/a_mains/github_wrapper.py +11 -0
  11. atomicshop/a_mains/install_ca_certificate.py +172 -0
  12. atomicshop/{addons/mains → a_mains}/msi_unpacker.py +3 -1
  13. atomicshop/a_mains/process_from_port.py +119 -0
  14. atomicshop/a_mains/set_default_dns_gateway.py +90 -0
  15. atomicshop/a_mains/update_config_toml.py +38 -0
  16. atomicshop/appointment_management.py +5 -3
  17. atomicshop/basics/ansi_escape_codes.py +3 -1
  18. atomicshop/basics/argparse_template.py +2 -0
  19. atomicshop/basics/booleans.py +27 -30
  20. atomicshop/basics/bytes_arrays.py +43 -0
  21. atomicshop/basics/classes.py +149 -1
  22. atomicshop/basics/dicts.py +12 -0
  23. atomicshop/basics/enums.py +2 -2
  24. atomicshop/basics/exceptions.py +5 -1
  25. atomicshop/basics/list_of_classes.py +29 -0
  26. atomicshop/basics/list_of_dicts.py +69 -5
  27. atomicshop/basics/lists.py +14 -0
  28. atomicshop/basics/multiprocesses.py +374 -50
  29. atomicshop/basics/package_module.py +10 -0
  30. atomicshop/basics/strings.py +160 -7
  31. atomicshop/basics/threads.py +14 -0
  32. atomicshop/basics/tracebacks.py +13 -4
  33. atomicshop/certificates.py +153 -52
  34. atomicshop/config_init.py +12 -7
  35. atomicshop/console_user_response.py +7 -14
  36. atomicshop/consoles.py +9 -0
  37. atomicshop/datetimes.py +98 -0
  38. atomicshop/diff_check.py +340 -40
  39. atomicshop/dns.py +128 -12
  40. atomicshop/etws/_pywintrace_fix.py +17 -0
  41. atomicshop/etws/const.py +38 -0
  42. atomicshop/etws/providers.py +21 -0
  43. atomicshop/etws/sessions.py +43 -0
  44. atomicshop/etws/trace.py +168 -0
  45. atomicshop/etws/traces/trace_dns.py +162 -0
  46. atomicshop/etws/traces/trace_sysmon_process_creation.py +126 -0
  47. atomicshop/etws/traces/trace_tcp.py +130 -0
  48. atomicshop/file_io/csvs.py +222 -24
  49. atomicshop/file_io/docxs.py +35 -18
  50. atomicshop/file_io/file_io.py +35 -19
  51. atomicshop/file_io/jsons.py +49 -0
  52. atomicshop/file_io/tomls.py +139 -0
  53. atomicshop/filesystem.py +864 -293
  54. atomicshop/get_process_list.py +133 -0
  55. atomicshop/{process_name_cmd.py → get_process_name_cmd_dll.py} +52 -19
  56. atomicshop/http_parse.py +149 -93
  57. atomicshop/ip_addresses.py +6 -1
  58. atomicshop/mitm/centered_settings.py +132 -0
  59. atomicshop/mitm/config_static.py +207 -0
  60. atomicshop/mitm/config_toml_editor.py +55 -0
  61. atomicshop/mitm/connection_thread_worker.py +875 -357
  62. atomicshop/mitm/engines/__parent/parser___parent.py +4 -17
  63. atomicshop/mitm/engines/__parent/recorder___parent.py +108 -51
  64. atomicshop/mitm/engines/__parent/requester___parent.py +116 -0
  65. atomicshop/mitm/engines/__parent/responder___parent.py +75 -114
  66. atomicshop/mitm/engines/__reference_general/parser___reference_general.py +10 -7
  67. atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +5 -5
  68. atomicshop/mitm/engines/__reference_general/requester___reference_general.py +47 -0
  69. atomicshop/mitm/engines/__reference_general/responder___reference_general.py +95 -13
  70. atomicshop/mitm/engines/create_module_template.py +58 -14
  71. atomicshop/mitm/import_config.py +359 -139
  72. atomicshop/mitm/initialize_engines.py +160 -74
  73. atomicshop/mitm/message.py +64 -23
  74. atomicshop/mitm/mitm_main.py +892 -0
  75. atomicshop/mitm/recs_files.py +183 -0
  76. atomicshop/mitm/shared_functions.py +4 -10
  77. atomicshop/mitm/ssh_tester.py +82 -0
  78. atomicshop/mitm/statistic_analyzer.py +257 -166
  79. atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py +136 -0
  80. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +525 -0
  81. atomicshop/monitor/change_monitor.py +96 -120
  82. atomicshop/monitor/checks/dns.py +139 -70
  83. atomicshop/monitor/checks/file.py +77 -0
  84. atomicshop/monitor/checks/network.py +81 -77
  85. atomicshop/monitor/checks/process_running.py +33 -34
  86. atomicshop/monitor/checks/url.py +94 -0
  87. atomicshop/networks.py +671 -0
  88. atomicshop/on_exit.py +205 -0
  89. atomicshop/package_mains_processor.py +84 -0
  90. atomicshop/permissions/permissions.py +22 -0
  91. atomicshop/permissions/ubuntu_permissions.py +239 -0
  92. atomicshop/permissions/win_permissions.py +33 -0
  93. atomicshop/print_api.py +24 -41
  94. atomicshop/process.py +63 -17
  95. atomicshop/process_poller/__init__.py +0 -0
  96. atomicshop/process_poller/pollers/__init__.py +0 -0
  97. atomicshop/process_poller/pollers/psutil_pywin32wmi_dll.py +95 -0
  98. atomicshop/process_poller/process_pool.py +207 -0
  99. atomicshop/process_poller/simple_process_pool.py +311 -0
  100. atomicshop/process_poller/tracer_base.py +45 -0
  101. atomicshop/process_poller/tracers/__init__.py +0 -0
  102. atomicshop/process_poller/tracers/event_log.py +46 -0
  103. atomicshop/process_poller/tracers/sysmon_etw.py +68 -0
  104. atomicshop/python_file_patcher.py +1 -1
  105. atomicshop/python_functions.py +27 -75
  106. atomicshop/question_answer_engine.py +2 -2
  107. atomicshop/scheduling.py +24 -5
  108. atomicshop/sound.py +4 -2
  109. atomicshop/speech_recognize.py +8 -0
  110. atomicshop/ssh_remote.py +158 -172
  111. atomicshop/startup/__init__.py +0 -0
  112. atomicshop/startup/win/__init__.py +0 -0
  113. atomicshop/startup/win/startup_folder.py +53 -0
  114. atomicshop/startup/win/task_scheduler.py +119 -0
  115. atomicshop/system_resource_monitor.py +61 -46
  116. atomicshop/system_resources.py +8 -8
  117. atomicshop/tempfiles.py +1 -2
  118. atomicshop/timer.py +30 -11
  119. atomicshop/urls.py +41 -0
  120. atomicshop/venvs.py +28 -0
  121. atomicshop/versioning.py +27 -0
  122. atomicshop/web.py +110 -25
  123. atomicshop/web_apis/__init__.py +0 -0
  124. atomicshop/web_apis/google_custom_search.py +44 -0
  125. atomicshop/web_apis/google_llm.py +188 -0
  126. atomicshop/websocket_parse.py +450 -0
  127. atomicshop/wrappers/certauthw/certauth.py +1 -0
  128. atomicshop/wrappers/cryptographyw.py +29 -8
  129. atomicshop/wrappers/ctyping/etw_winapi/__init__.py +0 -0
  130. atomicshop/wrappers/ctyping/etw_winapi/const.py +335 -0
  131. atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py +393 -0
  132. atomicshop/wrappers/ctyping/file_details_winapi.py +67 -0
  133. atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py +2 -1
  134. atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py +13 -9
  135. atomicshop/wrappers/ctyping/msi_windows_installer/tables.py +35 -0
  136. atomicshop/wrappers/ctyping/setup_device.py +466 -0
  137. atomicshop/wrappers/ctyping/win_console.py +39 -0
  138. atomicshop/wrappers/dockerw/dockerw.py +113 -2
  139. atomicshop/wrappers/elasticsearchw/config_basic.py +0 -12
  140. atomicshop/wrappers/elasticsearchw/elastic_infra.py +75 -0
  141. atomicshop/wrappers/elasticsearchw/elasticsearchw.py +2 -20
  142. atomicshop/wrappers/factw/get_file_data.py +12 -5
  143. atomicshop/wrappers/factw/install/install_after_restart.py +89 -5
  144. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +20 -14
  145. atomicshop/wrappers/factw/postgresql/firmware.py +4 -6
  146. atomicshop/wrappers/githubw.py +583 -51
  147. atomicshop/wrappers/loggingw/consts.py +49 -0
  148. atomicshop/wrappers/loggingw/filters.py +102 -0
  149. atomicshop/wrappers/loggingw/formatters.py +58 -71
  150. atomicshop/wrappers/loggingw/handlers.py +459 -40
  151. atomicshop/wrappers/loggingw/loggers.py +19 -0
  152. atomicshop/wrappers/loggingw/loggingw.py +1010 -178
  153. atomicshop/wrappers/loggingw/reading.py +344 -19
  154. atomicshop/wrappers/mongodbw/__init__.py +0 -0
  155. atomicshop/wrappers/mongodbw/mongo_infra.py +31 -0
  156. atomicshop/wrappers/mongodbw/mongodbw.py +1432 -0
  157. atomicshop/wrappers/netshw.py +271 -0
  158. atomicshop/wrappers/playwrightw/engine.py +34 -19
  159. atomicshop/wrappers/playwrightw/infra.py +5 -0
  160. atomicshop/wrappers/playwrightw/javascript.py +7 -3
  161. atomicshop/wrappers/playwrightw/keyboard.py +14 -0
  162. atomicshop/wrappers/playwrightw/scenarios.py +172 -5
  163. atomicshop/wrappers/playwrightw/waits.py +9 -7
  164. atomicshop/wrappers/powershell_networking.py +80 -0
  165. atomicshop/wrappers/psutilw/processes.py +81 -0
  166. atomicshop/wrappers/psutilw/psutil_networks.py +85 -0
  167. atomicshop/wrappers/psutilw/psutilw.py +9 -0
  168. atomicshop/wrappers/pyopensslw.py +9 -2
  169. atomicshop/wrappers/pywin32w/__init__.py +0 -0
  170. atomicshop/wrappers/pywin32w/cert_store.py +116 -0
  171. atomicshop/wrappers/pywin32w/console.py +34 -0
  172. atomicshop/wrappers/pywin32w/win_event_log/__init__.py +0 -0
  173. atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
  174. atomicshop/wrappers/pywin32w/win_event_log/subscribe.py +212 -0
  175. atomicshop/wrappers/pywin32w/win_event_log/subscribes/__init__.py +0 -0
  176. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +57 -0
  177. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +49 -0
  178. atomicshop/wrappers/pywin32w/win_event_log/subscribes/schannel_logging.py +97 -0
  179. atomicshop/wrappers/pywin32w/winshell.py +19 -0
  180. atomicshop/wrappers/pywin32w/wmis/__init__.py +0 -0
  181. atomicshop/wrappers/pywin32w/wmis/msft_netipaddress.py +113 -0
  182. atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +259 -0
  183. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +112 -0
  184. atomicshop/wrappers/pywin32w/wmis/wmi_helpers.py +236 -0
  185. atomicshop/wrappers/socketw/accepter.py +21 -7
  186. atomicshop/wrappers/socketw/certificator.py +216 -150
  187. atomicshop/wrappers/socketw/creator.py +190 -50
  188. atomicshop/wrappers/socketw/dns_server.py +500 -173
  189. atomicshop/wrappers/socketw/exception_wrapper.py +45 -52
  190. atomicshop/wrappers/socketw/process_getter.py +86 -0
  191. atomicshop/wrappers/socketw/receiver.py +144 -102
  192. atomicshop/wrappers/socketw/sender.py +65 -35
  193. atomicshop/wrappers/socketw/sni.py +334 -165
  194. atomicshop/wrappers/socketw/socket_base.py +134 -0
  195. atomicshop/wrappers/socketw/socket_client.py +137 -95
  196. atomicshop/wrappers/socketw/socket_server_tester.py +14 -9
  197. atomicshop/wrappers/socketw/socket_wrapper.py +717 -116
  198. atomicshop/wrappers/socketw/ssl_base.py +15 -14
  199. atomicshop/wrappers/socketw/statistics_csv.py +148 -17
  200. atomicshop/wrappers/sysmonw.py +157 -0
  201. atomicshop/wrappers/ubuntu_terminal.py +65 -26
  202. atomicshop/wrappers/win_auditw.py +189 -0
  203. atomicshop/wrappers/winregw/__init__.py +0 -0
  204. atomicshop/wrappers/winregw/winreg_installed_software.py +58 -0
  205. atomicshop/wrappers/winregw/winreg_network.py +232 -0
  206. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/METADATA +31 -49
  207. atomicshop-3.10.5.dist-info/RECORD +306 -0
  208. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/WHEEL +1 -1
  209. atomicshop/_basics_temp.py +0 -101
  210. atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh +0 -3
  211. atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd +0 -2
  212. atomicshop/addons/mains/install_docker_rootless_ubuntu.py +0 -11
  213. atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py +0 -11
  214. atomicshop/addons/mains/install_elastic_search_and_kibana_ubuntu.py +0 -10
  215. atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py +0 -9
  216. atomicshop/addons/package_setup/CreateWheel.cmd +0 -7
  217. atomicshop/addons/package_setup/Setup in Edit mode.cmd +0 -6
  218. atomicshop/addons/package_setup/Setup.cmd +0 -7
  219. atomicshop/addons/process_list/compile.cmd +0 -2
  220. atomicshop/addons/process_list/compiled/Win10x64/process_list.dll +0 -0
  221. atomicshop/addons/process_list/compiled/Win10x64/process_list.exp +0 -0
  222. atomicshop/addons/process_list/compiled/Win10x64/process_list.lib +0 -0
  223. atomicshop/archiver/_search_in_zip.py +0 -189
  224. atomicshop/archiver/archiver.py +0 -34
  225. atomicshop/archiver/search_in_archive.py +0 -250
  226. atomicshop/archiver/sevenz_app_w.py +0 -86
  227. atomicshop/archiver/sevenzs.py +0 -44
  228. atomicshop/archiver/zips.py +0 -293
  229. atomicshop/etw/dns_trace.py +0 -118
  230. atomicshop/etw/etw.py +0 -61
  231. atomicshop/file_types.py +0 -24
  232. atomicshop/mitm/engines/create_module_template_example.py +0 -13
  233. atomicshop/mitm/initialize_mitm_server.py +0 -240
  234. atomicshop/monitor/checks/hash.py +0 -44
  235. atomicshop/monitor/checks/hash_checks/file.py +0 -55
  236. atomicshop/monitor/checks/hash_checks/url.py +0 -62
  237. atomicshop/pbtkmultifile_argparse.py +0 -88
  238. atomicshop/permissions.py +0 -110
  239. atomicshop/process_poller.py +0 -237
  240. atomicshop/script_as_string_processor.py +0 -38
  241. atomicshop/ssh_scripts/process_from_ipv4.py +0 -37
  242. atomicshop/ssh_scripts/process_from_port.py +0 -27
  243. atomicshop/wrappers/_process_wrapper_curl.py +0 -27
  244. atomicshop/wrappers/_process_wrapper_tar.py +0 -21
  245. atomicshop/wrappers/dockerw/install_docker.py +0 -209
  246. atomicshop/wrappers/elasticsearchw/infrastructure.py +0 -265
  247. atomicshop/wrappers/elasticsearchw/install_elastic.py +0 -232
  248. atomicshop/wrappers/ffmpegw.py +0 -125
  249. atomicshop/wrappers/loggingw/checks.py +0 -20
  250. atomicshop/wrappers/nodejsw/install_nodejs.py +0 -139
  251. atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
  252. atomicshop/wrappers/socketw/base.py +0 -59
  253. atomicshop/wrappers/socketw/get_process.py +0 -107
  254. atomicshop/wrappers/wslw.py +0 -191
  255. atomicshop-2.11.47.dist-info/RECORD +0 -251
  256. /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
  257. /atomicshop/{addons → a_mains/addons}/PlayWrightCodegen.cmd +0 -0
  258. /atomicshop/{addons → a_mains/addons}/ScriptExecution.cmd +0 -0
  259. /atomicshop/{addons/mains → a_mains/addons}/inits/init_to_import_all_modules.py +0 -0
  260. /atomicshop/{addons → a_mains/addons}/process_list/ReadMe.txt +0 -0
  261. /atomicshop/{addons/mains → a_mains}/search_for_hyperlinks_in_docx.py +0 -0
  262. /atomicshop/{archiver → etws}/__init__.py +0 -0
  263. /atomicshop/{etw → etws/traces}/__init__.py +0 -0
  264. /atomicshop/{monitor/checks/hash_checks → mitm/statistic_analyzer_helper}/__init__.py +0 -0
  265. /atomicshop/{wrappers/nodejsw → permissions}/__init__.py +0 -0
  266. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  267. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info/licenses}/LICENSE.txt +0 -0
  268. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/top_level.txt +0 -0
@@ -1,293 +0,0 @@
1
- import os
2
- import time
3
- import zipfile
4
- from io import BytesIO
5
- from typing import Union
6
-
7
- from .. import filesystem
8
- from ..print_api import print_api
9
-
10
-
11
- def is_zip_zipfile(file_object: Union[str, bytes]) -> bool:
12
- """
13
- Function checks if the file is a zip file.
14
- :param file_object: can be two types:
15
- string, full path to the file.
16
- bytes or BytesIO, the bytes of the file.
17
- :return: boolean.
18
- """
19
-
20
- try:
21
- if isinstance(file_object, bytes):
22
- with BytesIO(file_object) as file_object:
23
- with zipfile.ZipFile(file_object) as zip_object:
24
- zip_object.testzip()
25
- return True
26
- elif isinstance(file_object, str):
27
- with zipfile.ZipFile(file_object) as zip_object:
28
- zip_object.testzip()
29
- return True
30
- except zipfile.BadZipFile:
31
- return False
32
-
33
-
34
- def is_zip_magic_number(file_path: str) -> bool:
35
- """
36
- Function checks if the file is a zip file using magic number.
37
- :param file_path: string, full path to the file.
38
- :return: boolean.
39
-
40
- 50 4B 03 04: This is the most common signature, found at the beginning of a ZIP file.
41
- It signifies the start of a file within the ZIP archive and is present in almost all ZIP files.
42
- Each file within the ZIP archive starts with this signature.
43
- 50 4B 05 06: This is the end of central directory record signature.
44
- It's found at the end of a ZIP file and is essential for identifying the structure of the ZIP archive,
45
- especially in cases where the file is split or is a multi-part archive.
46
- 50 4B 07 08: This signature is used for spanned ZIP archives (also known as split or multi-volume ZIP archives).
47
- It's found in the end of central directory locator for ZIP files that are split across multiple volumes.
48
- """
49
-
50
- with open(file_path, 'rb') as file:
51
- # Read the first 4 bytes of the file
52
- signature = file.read(4)
53
-
54
- # Check if the signature matches any of the ZIP signatures
55
- return signature in [b'PK\x03\x04', b'PK\x05\x06', b'PK\x07\x08']
56
-
57
-
58
- def extract_archive_with_zipfile(
59
- archive_path: str,
60
- extract_directory: str = None,
61
- files_without_directories: bool = False,
62
- remove_first_directory: bool = False,
63
- print_kwargs: dict = None
64
- ) -> str:
65
- """
66
- Function will extract the archive using standard library 'zipfile'.
67
- This method preserves original date and time of the files inside the archive.
68
-
69
- :param archive_path: string, full path to archived file.
70
- :param extract_directory: string, full path to directory that the files will be extracted to.
71
- If not specified, the files will be extracted to the same directory as the archived file, using the file name
72
- without extension as the directory name.
73
- :param files_without_directories: boolean, default 'False'.
74
- 'True': All the files in the archive will be extracted without subdirectories hierarchy.
75
- Meaning, that if there are duplicate file names, the latest file with the same file name will overwrite
76
- all the rest of the files with the same name.
77
- 'False': Subdirectory hierarchy will be preserved as it is currently in the archived file.
78
- :param remove_first_directory: boolean, default is 'False'.
79
- 'True': all the files will be extracted without first directory in the hierarchy.
80
- Example: package_some_name_1.1.1_build/subdir1/file.exe
81
- Will be extracted as: subdir/file.exe
82
- :param print_kwargs: dict, kwargs for print_api.
83
-
84
- :return: string, full path to directory that the files were extracted to.
85
- """
86
-
87
- if print_kwargs is None:
88
- print_kwargs = dict()
89
-
90
- # If 'extract_directory' is not specified, extract to the same directory as the archived file.
91
- if extract_directory is None:
92
- extract_directory = (
93
- filesystem.get_file_directory(archive_path) + os.sep +
94
- filesystem.get_file_name_without_extension(archive_path))
95
-
96
- print_api(f'Extracting to directory: {extract_directory}', **print_kwargs)
97
-
98
- # initiating the archived file path as 'zipfile.ZipFile' object.
99
- with zipfile.ZipFile(archive_path) as zip_object:
100
- # '.infolist()' method of the object contains all the directories and files that are in the archive including
101
- # information about each one, like date and time of archiving.
102
- for zip_info in zip_object.infolist():
103
- # '.filename' attribute of the 'infolist()' method is relative path to each directory and file.
104
- # If 'filename' ends with '/' it is a directory (it doesn't matter if it is windows or *nix)
105
- # If so, skip current iteration.
106
- if zip_info.filename[-1] == '/':
107
- continue
108
-
109
- if files_without_directories:
110
- # Put into 'filename' the string that contains only the filename without subdirectories.
111
- zip_info.filename = os.path.basename(zip_info.filename)
112
- elif remove_first_directory:
113
- # Cut the first directory from the filename.
114
- zip_info.filename = zip_info.filename.split('/', maxsplit=1)[1]
115
-
116
- print_api(f'Extracting: {zip_info.filename}', **print_kwargs)
117
-
118
- # Extract current file from the archive using 'zip_info' of the current file with 'filename' that we
119
- # updated under specified parameters to specified directory.
120
- zip_object.extract(zip_info, extract_directory)
121
-
122
- # === Change the date and time of extracted file from current time to the time specified in 'zip_info'.
123
- # Get full path to extracted file.
124
- extracted_file_path: str = extract_directory + os.sep + zip_info.filename
125
- # Create needed datetime object with original archived datetime from 'zip_info.date_time'.
126
- date_time = time.mktime(zip_info.date_time + (0, 0, -1))
127
- # Using 'os' library, changed the datetime of the file to the object created in previous step.
128
- os.utime(extracted_file_path, (date_time, date_time))
129
- print_api('Extraction done.', color="green", **print_kwargs)
130
-
131
- return extract_directory
132
-
133
-
134
- def get_file_list_from_zip(file_path: str) -> list:
135
- """
136
- Function returns the list of file names and their relative directories inside the zip file.
137
- :param file_path: string, full path to the zip file.
138
- :return: list of strings.
139
- """
140
-
141
- with zipfile.ZipFile(file_path, 'r') as zip_object:
142
- return zip_object.namelist()
143
-
144
-
145
- # def search_file_in_zip(
146
- # file_path: str = None,
147
- # file_bytes: bytes = None,
148
- # file_names_to_search: list[str] = None,
149
- # case_sensitive: bool = True,
150
- # return_first_only: bool = False,
151
- # return_empty_list_per_file_name: bool = False,
152
- # recursive: bool = False,
153
- # callback_functions: list = None,
154
- # extract_file_to_path: str = None
155
- # ) -> dict[str, list[bytes]]:
156
- # """
157
- # Function searches for the file names inside the zip file and returns a dictionary where the keys are the
158
- # names of the callback functions and the values are lists of found file bytes.
159
- # :param file_path: string, full path to the zip file.
160
- # :param file_bytes: bytes, the bytes of the zip file.
161
- # :param file_names_to_search: list of strings, the names of the files to search.
162
- # :param case_sensitive: boolean, default is 'True'. Determines if file name search should be case sensitive.
163
- # :param return_first_only: boolean, default is 'False'. Return only the first found file for each file name.
164
- # :param return_empty_list_per_file_name: boolean, default is 'False'.
165
- # True: Return empty list for each file name that wasn't found.
166
- # False: Don't return empty list for each file name that wasn't found.
167
- # :param recursive: boolean, default is 'False'. If True, search for file names recursively in nested zip files.
168
- # :param callback_functions: list of callables, default is None. Each function takes a file name and should return a
169
- # boolean that will tell the main function if this file is 'found' or not.
170
- # :param extract_file_to_path: string, full path to the directory where the found files should be extracted.
171
- # :return: dictionary of lists of bytes.
172
- # """
173
- #
174
- # def get_unique_filename(directory, filename):
175
- # """
176
- # Generates a unique filename by appending a number if the file already exists.
177
- # """
178
- # name, ext = os.path.splitext(filename)
179
- # counter = 1
180
- # unique_filename = filename
181
- # while os.path.exists(os.path.join(directory, unique_filename)):
182
- # unique_filename = f"{name}_{counter}{ext}"
183
- # counter += 1
184
- # return unique_filename
185
- #
186
- # def is_zip_file(file, zip_obj):
187
- # try:
188
- # with zip_obj.open(file) as file_data:
189
- # with zipfile.ZipFile(BytesIO(file_data.read())) as zip_file:
190
- # if zip_file.testzip() is None: # No errors found
191
- # return True
192
- # except zipfile.BadZipFile:
193
- # return False
194
- # return False
195
- #
196
- # def match_file_name(target, current):
197
- # if case_sensitive:
198
- # return current.endswith(target)
199
- # else:
200
- # return current.lower().endswith(target.lower())
201
- #
202
- # def search_in_zip(zip_obj, file_names, results, found_set):
203
- # for item in zip_obj.infolist():
204
- # if item.filename.endswith('/'): # Skip directories
205
- # continue
206
- # is_nested_zip = recursive and is_zip_file(item.filename, zip_obj)
207
- #
208
- # with zip_obj.open(item) as file_data:
209
- # archived_file_bytes = file_data.read()
210
- #
211
- # # This is needed to know if the file should be extracted to directory or not.
212
- # should_extract = False
213
- #
214
- # name_matched = False
215
- # if file_names is not None:
216
- # name_matched = any(match_file_name(file_name, item.filename) for file_name in file_names)
217
- # if name_matched:
218
- # should_extract = True
219
- #
220
- # callback_matched = False
221
- # if callback_functions:
222
- # for callback in callback_functions:
223
- # callback_result = callback(archived_file_bytes)
224
- # if callback_result:
225
- # callback_matched = True
226
- # # Initialize key for callback function name if not present
227
- # if callback.__name__ not in results:
228
- # results[callback.__name__] = []
229
- # file_info = {
230
- # 'bytes': archived_file_bytes,
231
- # 'name': item.filename,
232
- # 'size': item.file_size,
233
- # 'modified_time': item.date_time
234
- # }
235
- # results[callback.__name__].append(file_info)
236
- # if return_first_only:
237
- # found_set.add(item.filename)
238
- #
239
- # should_extract = True
240
- # break # Stop checking other callbacks if one has found it
241
- #
242
- # if should_extract and extract_file_to_path:
243
- # unique_filename = get_unique_filename(extract_file_to_path, os.path.basename(item.filename))
244
- # with open(os.path.join(extract_file_to_path, unique_filename), 'wb') as f:
245
- # f.write(archived_file_bytes)
246
- #
247
- # if not callback_matched:
248
- # if is_nested_zip:
249
- # # If the file is a nested ZIP and hasn't matched a callback, search recursively
250
- # nested_zip_bytes = BytesIO(archived_file_bytes)
251
- # with zipfile.ZipFile(nested_zip_bytes) as nested_zip:
252
- # search_in_zip(nested_zip, file_names, results, found_set)
253
- # elif name_matched:
254
- # # Handle name match when no callbacks are provided or no callback matched
255
- # if item.filename not in results:
256
- # results[item.filename] = []
257
- # file_info = {
258
- # 'bytes': archived_file_bytes,
259
- # 'name': item.filename,
260
- # 'size': item.file_size,
261
- # 'modified_time': item.date_time
262
- # }
263
- # results[item.filename].append(file_info)
264
- # if return_first_only:
265
- # found_set.add(item.filename) # Mark as found
266
- #
267
- # if file_names is not None and len(found_set) == len(file_names):
268
- # return # All files found, stop searching
269
- #
270
- # if file_names_to_search is None and callback_functions is None:
271
- # raise ValueError("Either file_names_to_search or callback_functions must be provided.")
272
- #
273
- # # Initialize results dictionary.
274
- # if callback_functions:
275
- # results = {callback.__name__: [] for callback in callback_functions}
276
- # else:
277
- # results = {}
278
- #
279
- # found_set = set()
280
- # if file_bytes is not None:
281
- # with zipfile.ZipFile(BytesIO(file_bytes), 'r') as zip_ref:
282
- # search_in_zip(zip_ref, file_names_to_search, results, found_set)
283
- # elif file_path is not None:
284
- # with zipfile.ZipFile(file_path, 'r') as zip_ref:
285
- # search_in_zip(zip_ref, file_names_to_search, results, found_set)
286
- # else:
287
- # raise ValueError("Either file_path or file_bytes must be provided.")
288
- #
289
- # if not return_empty_list_per_file_name:
290
- # # Filter out keys with empty lists
291
- # results = {key: value for key, value in results.items() if value}
292
- #
293
- # return results
@@ -1,118 +0,0 @@
1
- from . import etw
2
- from .. import dns
3
- from ..wrappers.psutilw import psutilw
4
- from ..basics import dicts
5
- from ..process_poller import ProcessPollerPool
6
-
7
-
8
- class DnsTrace:
9
- def __init__(self, enable_process_poller: bool = False, attrs: list = None):
10
- """
11
- DnsTrace class use to trace DNS events from Windows Event Tracing for EventId 3008.
12
-
13
- :param enable_process_poller: Boolean to enable process poller. Gets the process PID, Name and CommandLine,
14
- every 100 ms. Since the DNS events doesn't contain the process name and command line, only PID.
15
- Then DNS events will be enriched with the process name and command line from the process poller.
16
- :param attrs: List of attributes to return. If None, all attributes will be returned.
17
- """
18
-
19
- self.enable_process_poller = enable_process_poller
20
- self.attrs = attrs
21
-
22
- self.event_trace = etw.EventTrace(
23
- [(dns.ETW_DNS_INFO['provider_name'], dns.ETW_DNS_INFO['provider_guid'])],
24
- # lambda x: self.event_queue.put(x),
25
- event_id_filters=[dns.ETW_DNS_INFO['event_id']]
26
- )
27
-
28
- if self.enable_process_poller:
29
- self.process_poller = ProcessPollerPool(store_cycles=200, operation='process', poller_method='process_dll')
30
-
31
- def start(self):
32
- if self.enable_process_poller:
33
- self.process_poller.start()
34
-
35
- self.event_trace.start()
36
-
37
- def stop(self):
38
- self.event_trace.stop()
39
-
40
- if self.enable_process_poller:
41
- self.process_poller.stop()
42
-
43
- def emit(self):
44
- """
45
- Function that will return the next event from the queue.
46
- The queue is blocking, so if there is no event in the queue, the function will wait until there is one.
47
-
48
- Usage Example:
49
- while True:
50
- dns_dict = dns_trace.emit()
51
- print(dns_dict)
52
-
53
- :return: Dictionary with the event data.
54
- """
55
-
56
- event = self.event_trace.emit()
57
-
58
- event_dict: dict = {
59
- 'pid': event[1]['EventHeader']['ProcessId'],
60
- 'etw_id': event[0],
61
- 'domain': event[1]['QueryName'],
62
- 'query_type_id': str(event[1]['QueryType']),
63
- 'query_type': dns.TYPES_DICT[str(event[1]['QueryType'])]
64
- }
65
-
66
- # # Get process name only from psutil, just in case.
67
- # try:
68
- # process_name = psutilw.get_process_name_by_pid(event_dict['pid'])
69
- # except psutil.NoSuchProcess:
70
- # process_name = str(event_dict['pid'])
71
-
72
- # Defining list if ips and other answers, which aren't IPs.
73
- list_of_ips = list()
74
- list_of_other_domains = list()
75
- # Parse DNS results, only if 'QueryResults' key isn't empty, since many of the events are, mostly due errors.
76
- if event[1]['QueryResults']:
77
- # 'QueryResults' key contains a string with all the 'Answers' divided by type and ';' character.
78
- # Basically, we can parse each type out of string, but we need only IPs and other answers.
79
- list_of_parameters = event[1]['QueryResults'].split(';')
80
-
81
- # Iterating through all the parameters that we got from 'QueryResults' key.
82
- for parameter in list_of_parameters:
83
- # If 'type' string is present it means that entry is a domain;
84
- if 'type' in parameter:
85
- # Remove the 'type' string and get the domain name.
86
- current_iteration_parameter = parameter.rsplit(' ', maxsplit=1)[1]
87
- # Add the variable to the list of other answers.
88
- list_of_other_domains.append(current_iteration_parameter)
89
- # If 'type' string is not present it means that entry is an IP.
90
- else:
91
- # Sometimes the last parameter in the 'QueryResults' key after ';' character will be empty, skip it.
92
- if parameter:
93
- list_of_ips.append(parameter)
94
-
95
- event_dict['ips'] = list_of_ips
96
- event_dict['other_domains'] = list_of_other_domains
97
-
98
- # Getting the 'QueryStatus' key.
99
- event_dict['status_id'] = event[1]['QueryStatus']
100
-
101
- # Getting the 'QueryStatus' key. If DNS Query Status is '0' then it was executed successfully.
102
- # And if not, it means there was an error. The 'QueryStatus' indicate what number of an error it is.
103
- if event[1]['QueryStatus'] == '0':
104
- event_dict['status'] = 'Success'
105
- else:
106
- event_dict['status'] = 'Error'
107
-
108
- if self.enable_process_poller:
109
- event_dict = psutilw.cross_single_connection_with_processes(event_dict, self.process_poller.processes)
110
- # If it was impossible to get the process name from the process poller, get it from psutil.
111
- # if event_dict['name'].isnumeric():
112
- # event_dict['name'] = process_name
113
-
114
- if self.attrs:
115
- event_dict = dicts.reorder_keys(
116
- event_dict, self.attrs, skip_keys_not_in_list=True)
117
-
118
- return event_dict
atomicshop/etw/etw.py DELETED
@@ -1,61 +0,0 @@
1
- import queue
2
-
3
- # Import FireEye Event Tracing library.
4
- import etw
5
-
6
-
7
- class EventTrace(etw.ETW):
8
- def __init__(self, providers: list, event_callback=None, event_id_filters: list = None):
9
- """
10
- :param providers: List of tuples with provider name and provider GUID.
11
- tuple[0] = provider name
12
- tuple[1] = provider GUID
13
- :param event_callback: Reference to the callable callback function that will be called for each occurring event.
14
- :param event_id_filters: List of event IDs that we want to filter. If not provided, all events will be returned.
15
- The default in the 'etw.ETW' method is 'None'.
16
- """
17
- self.event_queue = queue.Queue()
18
-
19
- # If no callback function is provided, we will use the default one, which will put the event in the queue.
20
- if not event_callback:
21
- function_callable = lambda x: self.event_queue.put(x)
22
- # If a callback function is provided, we will use it.
23
- else:
24
- function_callable = lambda x: event_callback(x)
25
-
26
- # Defining the list of specified ETW providers in 'etw' library format.
27
- etw_format_providers: list = list()
28
- for provider in providers:
29
- etw_format_providers.append(etw.ProviderInfo(provider[0], etw.GUID(provider[1])))
30
-
31
- super().__init__(
32
- providers=etw_format_providers, event_callback=function_callable, event_id_filters=event_id_filters)
33
-
34
- def start(self):
35
- try:
36
- super().start()
37
- except OSError as e:
38
- raise OSError(f"PyWinTrace Error: {e}\n"
39
- f"PyWinTrace crashed, didn't find solution to this, RESTART computer.")
40
-
41
- def stop(self):
42
- super().stop()
43
-
44
- def emit(self):
45
- """
46
- The Function will return the next event from the queue.
47
- The queue is blocking, so if there is no event in the queue, the function will wait until there is one.
48
-
49
- Usage Example:
50
- while True:
51
- dns_dict = dns_trace.emit()
52
- print(dns_dict)
53
-
54
- event object:
55
- event[0]: is the event ID. Example: for DNS Tracing, it is event id 3008.
56
- event[1]: contains a dictionary with all the event's parameters.
57
-
58
- :return: etw event object.
59
- """
60
-
61
- return self.event_queue.get()
atomicshop/file_types.py DELETED
@@ -1,24 +0,0 @@
1
- from typing import Union
2
-
3
- import magic
4
-
5
-
6
- def get_mime_type(file_object: Union[str, bytes]):
7
- """
8
- Determine the MIME type of the given input.
9
- The input can be a file path (string) or a bytes object.
10
-
11
- :param file_object: File path as a string or bytes object.
12
- :return: MIME type as a string.
13
- """
14
- mime = magic.Magic(mime=True)
15
-
16
- # Check if input is a file path (str) or bytes
17
- if isinstance(file_object, str):
18
- # Assuming input_data is a file path
19
- return mime.from_file(file_object)
20
- elif isinstance(file_object, bytes):
21
- # Assuming input_data is bytes
22
- return mime.from_buffer(file_object)
23
- else:
24
- raise TypeError("Input must be a file path (str) or bytes object.")
@@ -1,13 +0,0 @@
1
- engine_name = '_example'
2
- domains = ['example.com']
3
- # This script should be in 'engines' folder.
4
-
5
-
6
- # === Create template from above settings. ===
7
- # Get current file directory, should be the 'engines' directory.
8
- # noinspection PyPep8
9
- from atomicshop import filesystem
10
- engines_path = filesystem.get_working_directory()
11
- # Create the template.
12
- from atomicshop.mitm.engines.create_module_template import CreateModuleTemplate
13
- CreateModuleTemplate(engine_name, domains, engines_path)