secator 0.13.0__tar.gz → 0.14.0__tar.gz

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 secator might be problematic. Click here for more details.

Files changed (207) hide show
  1. {secator-0.13.0 → secator-0.14.0}/CHANGELOG.md +12 -0
  2. {secator-0.13.0 → secator-0.14.0}/PKG-INFO +1 -1
  3. {secator-0.13.0 → secator-0.14.0}/pyproject.toml +1 -1
  4. {secator-0.13.0 → secator-0.14.0}/secator/cli.py +32 -8
  5. secator-0.14.0/secator/configs/profiles/aggressive.yaml +8 -0
  6. secator-0.14.0/secator/configs/profiles/default.yaml +8 -0
  7. secator-0.14.0/secator/configs/profiles/insane.yaml +8 -0
  8. secator-0.14.0/secator/configs/profiles/paranoid.yaml +8 -0
  9. secator-0.14.0/secator/configs/profiles/polite.yaml +8 -0
  10. secator-0.14.0/secator/configs/profiles/sneaky.yaml +8 -0
  11. secator-0.14.0/secator/configs/profiles/tor.yaml +5 -0
  12. {secator-0.13.0 → secator-0.14.0}/secator/decorators.py +1 -0
  13. {secator-0.13.0 → secator-0.14.0}/secator/report.py +2 -2
  14. {secator-0.13.0 → secator-0.14.0}/secator/runners/_base.py +30 -0
  15. {secator-0.13.0 → secator-0.14.0}/secator/runners/scan.py +1 -0
  16. {secator-0.13.0 → secator-0.14.0}/secator/runners/task.py +1 -0
  17. {secator-0.13.0 → secator-0.14.0}/secator/template.py +1 -1
  18. secator-0.13.0/secator/configs/profiles/aggressive.yaml +0 -7
  19. secator-0.13.0/secator/configs/profiles/default.yaml +0 -9
  20. secator-0.13.0/secator/configs/profiles/stealth.yaml +0 -7
  21. secator-0.13.0/secator/configs/workflows/port_scan.yaml +0 -39
  22. {secator-0.13.0 → secator-0.14.0}/.docker/Dockerfile.alpine +0 -0
  23. {secator-0.13.0 → secator-0.14.0}/.docker/Dockerfile.arch +0 -0
  24. {secator-0.13.0 → secator-0.14.0}/.docker/Dockerfile.debian +0 -0
  25. {secator-0.13.0 → secator-0.14.0}/.docker/Dockerfile.kali +0 -0
  26. {secator-0.13.0 → secator-0.14.0}/.docker/Dockerfile.osx +0 -0
  27. {secator-0.13.0 → secator-0.14.0}/.docker/Dockerfile.ubuntu +0 -0
  28. {secator-0.13.0 → secator-0.14.0}/.docker/build_all.sh +0 -0
  29. {secator-0.13.0 → secator-0.14.0}/.dockerignore +0 -0
  30. {secator-0.13.0 → secator-0.14.0}/.flake8 +0 -0
  31. {secator-0.13.0 → secator-0.14.0}/.gitignore +0 -0
  32. {secator-0.13.0 → secator-0.14.0}/CONTRIBUTING.md +0 -0
  33. {secator-0.13.0 → secator-0.14.0}/Dockerfile +0 -0
  34. {secator-0.13.0 → secator-0.14.0}/LICENSE +0 -0
  35. {secator-0.13.0 → secator-0.14.0}/README.md +0 -0
  36. {secator-0.13.0 → secator-0.14.0}/SECURITY.md +0 -0
  37. {secator-0.13.0 → secator-0.14.0}/cloudbuild.yaml +0 -0
  38. {secator-0.13.0 → secator-0.14.0}/helm/.helmignore +0 -0
  39. {secator-0.13.0 → secator-0.14.0}/helm/Chart.yaml +0 -0
  40. {secator-0.13.0 → secator-0.14.0}/helm/templates/redis-service.yaml +0 -0
  41. {secator-0.13.0 → secator-0.14.0}/helm/templates/redis.yaml +0 -0
  42. {secator-0.13.0 → secator-0.14.0}/helm/templates/secator-manager.yaml +0 -0
  43. {secator-0.13.0 → secator-0.14.0}/helm/templates/secator-worker.yaml +0 -0
  44. {secator-0.13.0 → secator-0.14.0}/helm/values.yaml +0 -0
  45. {secator-0.13.0 → secator-0.14.0}/scripts/download_cves.sh +0 -0
  46. {secator-0.13.0 → secator-0.14.0}/scripts/install.sh +0 -0
  47. {secator-0.13.0 → secator-0.14.0}/scripts/install_asciinema.sh +0 -0
  48. {secator-0.13.0 → secator-0.14.0}/scripts/install_go.sh +0 -0
  49. {secator-0.13.0 → secator-0.14.0}/scripts/install_ruby.sh +0 -0
  50. {secator-0.13.0 → secator-0.14.0}/scripts/msf/exploit_cve.rc +0 -0
  51. {secator-0.13.0 → secator-0.14.0}/scripts/msf/ftp_anonymous.rc +0 -0
  52. {secator-0.13.0 → secator-0.14.0}/scripts/msf/ftp_version.rc +0 -0
  53. {secator-0.13.0 → secator-0.14.0}/scripts/msf/ftp_vsftpd_234_backdoor.rc +0 -0
  54. {secator-0.13.0 → secator-0.14.0}/scripts/msf/redis.rc +0 -0
  55. {secator-0.13.0 → secator-0.14.0}/scripts/stories/STORY.md +0 -0
  56. {secator-0.13.0 → secator-0.14.0}/scripts/stories/aliases.sh +0 -0
  57. {secator-0.13.0 → secator-0.14.0}/scripts/stories/demo.sh +0 -0
  58. {secator-0.13.0 → secator-0.14.0}/scripts/stories/fmt.sh +0 -0
  59. {secator-0.13.0 → secator-0.14.0}/scripts/stories/input.sh +0 -0
  60. {secator-0.13.0 → secator-0.14.0}/scripts/stories/pipe.sh +0 -0
  61. {secator-0.13.0 → secator-0.14.0}/scripts/stories/short_demo.sh +0 -0
  62. {secator-0.13.0 → secator-0.14.0}/secator/.gitignore +0 -0
  63. {secator-0.13.0 → secator-0.14.0}/secator/__init__.py +0 -0
  64. {secator-0.13.0 → secator-0.14.0}/secator/celery.py +0 -0
  65. {secator-0.13.0 → secator-0.14.0}/secator/celery_signals.py +0 -0
  66. {secator-0.13.0 → secator-0.14.0}/secator/celery_utils.py +0 -0
  67. {secator-0.13.0 → secator-0.14.0}/secator/config.py +0 -0
  68. {secator-0.13.0 → secator-0.14.0}/secator/configs/__init__.py +0 -0
  69. {secator-0.13.0 → secator-0.14.0}/secator/configs/profiles/__init__.py +0 -0
  70. {secator-0.13.0 → secator-0.14.0}/secator/configs/scans/__init__.py +0 -0
  71. {secator-0.13.0 → secator-0.14.0}/secator/configs/scans/domain.yaml +0 -0
  72. {secator-0.13.0 → secator-0.14.0}/secator/configs/scans/host.yaml +0 -0
  73. {secator-0.13.0 → secator-0.14.0}/secator/configs/scans/network.yaml +0 -0
  74. {secator-0.13.0 → secator-0.14.0}/secator/configs/scans/subdomain.yaml +0 -0
  75. {secator-0.13.0 → secator-0.14.0}/secator/configs/scans/url.yaml +0 -0
  76. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/__init__.py +0 -0
  77. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/cidr_recon.yaml +0 -0
  78. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/code_scan.yaml +0 -0
  79. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/host_recon.yaml +0 -0
  80. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/subdomain_recon.yaml +0 -0
  81. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/url_bypass.yaml +0 -0
  82. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/url_crawl.yaml +0 -0
  83. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/url_dirsearch.yaml +0 -0
  84. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/url_fuzz.yaml +0 -0
  85. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/url_nuclei.yaml +0 -0
  86. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/url_params_fuzz.yaml +0 -0
  87. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/url_vuln.yaml +0 -0
  88. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/user_hunt.yaml +0 -0
  89. {secator-0.13.0 → secator-0.14.0}/secator/configs/workflows/wordpress.yaml +0 -0
  90. {secator-0.13.0 → secator-0.14.0}/secator/definitions.py +0 -0
  91. {secator-0.13.0 → secator-0.14.0}/secator/exporters/__init__.py +0 -0
  92. {secator-0.13.0 → secator-0.14.0}/secator/exporters/_base.py +0 -0
  93. {secator-0.13.0 → secator-0.14.0}/secator/exporters/console.py +0 -0
  94. {secator-0.13.0 → secator-0.14.0}/secator/exporters/csv.py +0 -0
  95. {secator-0.13.0 → secator-0.14.0}/secator/exporters/gdrive.py +0 -0
  96. {secator-0.13.0 → secator-0.14.0}/secator/exporters/json.py +0 -0
  97. {secator-0.13.0 → secator-0.14.0}/secator/exporters/table.py +0 -0
  98. {secator-0.13.0 → secator-0.14.0}/secator/exporters/txt.py +0 -0
  99. {secator-0.13.0 → secator-0.14.0}/secator/hooks/__init__.py +0 -0
  100. {secator-0.13.0 → secator-0.14.0}/secator/hooks/gcs.py +0 -0
  101. {secator-0.13.0 → secator-0.14.0}/secator/hooks/mongodb.py +0 -0
  102. {secator-0.13.0 → secator-0.14.0}/secator/installer.py +0 -0
  103. {secator-0.13.0 → secator-0.14.0}/secator/output_types/__init__.py +0 -0
  104. {secator-0.13.0 → secator-0.14.0}/secator/output_types/_base.py +0 -0
  105. {secator-0.13.0 → secator-0.14.0}/secator/output_types/certificate.py +0 -0
  106. {secator-0.13.0 → secator-0.14.0}/secator/output_types/error.py +0 -0
  107. {secator-0.13.0 → secator-0.14.0}/secator/output_types/exploit.py +0 -0
  108. {secator-0.13.0 → secator-0.14.0}/secator/output_types/info.py +0 -0
  109. {secator-0.13.0 → secator-0.14.0}/secator/output_types/ip.py +0 -0
  110. {secator-0.13.0 → secator-0.14.0}/secator/output_types/port.py +0 -0
  111. {secator-0.13.0 → secator-0.14.0}/secator/output_types/progress.py +0 -0
  112. {secator-0.13.0 → secator-0.14.0}/secator/output_types/record.py +0 -0
  113. {secator-0.13.0 → secator-0.14.0}/secator/output_types/stat.py +0 -0
  114. {secator-0.13.0 → secator-0.14.0}/secator/output_types/state.py +0 -0
  115. {secator-0.13.0 → secator-0.14.0}/secator/output_types/subdomain.py +0 -0
  116. {secator-0.13.0 → secator-0.14.0}/secator/output_types/tag.py +0 -0
  117. {secator-0.13.0 → secator-0.14.0}/secator/output_types/target.py +0 -0
  118. {secator-0.13.0 → secator-0.14.0}/secator/output_types/url.py +0 -0
  119. {secator-0.13.0 → secator-0.14.0}/secator/output_types/user_account.py +0 -0
  120. {secator-0.13.0 → secator-0.14.0}/secator/output_types/vulnerability.py +0 -0
  121. {secator-0.13.0 → secator-0.14.0}/secator/output_types/warning.py +0 -0
  122. {secator-0.13.0 → secator-0.14.0}/secator/rich.py +0 -0
  123. {secator-0.13.0 → secator-0.14.0}/secator/runners/__init__.py +0 -0
  124. {secator-0.13.0 → secator-0.14.0}/secator/runners/_helpers.py +0 -0
  125. {secator-0.13.0 → secator-0.14.0}/secator/runners/celery.py +0 -0
  126. {secator-0.13.0 → secator-0.14.0}/secator/runners/command.py +0 -0
  127. {secator-0.13.0 → secator-0.14.0}/secator/runners/workflow.py +0 -0
  128. {secator-0.13.0 → secator-0.14.0}/secator/scans/__init__.py +0 -0
  129. {secator-0.13.0 → secator-0.14.0}/secator/serializers/__init__.py +0 -0
  130. {secator-0.13.0 → secator-0.14.0}/secator/serializers/dataclass.py +0 -0
  131. {secator-0.13.0 → secator-0.14.0}/secator/serializers/json.py +0 -0
  132. {secator-0.13.0 → secator-0.14.0}/secator/serializers/regex.py +0 -0
  133. {secator-0.13.0 → secator-0.14.0}/secator/tasks/__init__.py +0 -0
  134. {secator-0.13.0 → secator-0.14.0}/secator/tasks/_categories.py +0 -0
  135. {secator-0.13.0 → secator-0.14.0}/secator/tasks/arjun.py +0 -0
  136. {secator-0.13.0 → secator-0.14.0}/secator/tasks/bbot.py +0 -0
  137. {secator-0.13.0 → secator-0.14.0}/secator/tasks/bup.py +0 -0
  138. {secator-0.13.0 → secator-0.14.0}/secator/tasks/cariddi.py +0 -0
  139. {secator-0.13.0 → secator-0.14.0}/secator/tasks/dalfox.py +0 -0
  140. {secator-0.13.0 → secator-0.14.0}/secator/tasks/dirsearch.py +0 -0
  141. {secator-0.13.0 → secator-0.14.0}/secator/tasks/dnsx.py +0 -0
  142. {secator-0.13.0 → secator-0.14.0}/secator/tasks/dnsxbrute.py +0 -0
  143. {secator-0.13.0 → secator-0.14.0}/secator/tasks/feroxbuster.py +0 -0
  144. {secator-0.13.0 → secator-0.14.0}/secator/tasks/ffuf.py +0 -0
  145. {secator-0.13.0 → secator-0.14.0}/secator/tasks/fping.py +0 -0
  146. {secator-0.13.0 → secator-0.14.0}/secator/tasks/gau.py +0 -0
  147. {secator-0.13.0 → secator-0.14.0}/secator/tasks/gf.py +0 -0
  148. {secator-0.13.0 → secator-0.14.0}/secator/tasks/gitleaks.py +0 -0
  149. {secator-0.13.0 → secator-0.14.0}/secator/tasks/gospider.py +0 -0
  150. {secator-0.13.0 → secator-0.14.0}/secator/tasks/grype.py +0 -0
  151. {secator-0.13.0 → secator-0.14.0}/secator/tasks/h8mail.py +0 -0
  152. {secator-0.13.0 → secator-0.14.0}/secator/tasks/httpx.py +0 -0
  153. {secator-0.13.0 → secator-0.14.0}/secator/tasks/katana.py +0 -0
  154. {secator-0.13.0 → secator-0.14.0}/secator/tasks/maigret.py +0 -0
  155. {secator-0.13.0 → secator-0.14.0}/secator/tasks/mapcidr.py +0 -0
  156. {secator-0.13.0 → secator-0.14.0}/secator/tasks/msfconsole.py +0 -0
  157. {secator-0.13.0 → secator-0.14.0}/secator/tasks/naabu.py +0 -0
  158. {secator-0.13.0 → secator-0.14.0}/secator/tasks/nmap.py +0 -0
  159. {secator-0.13.0 → secator-0.14.0}/secator/tasks/nuclei.py +0 -0
  160. {secator-0.13.0 → secator-0.14.0}/secator/tasks/searchsploit.py +0 -0
  161. {secator-0.13.0 → secator-0.14.0}/secator/tasks/subfinder.py +0 -0
  162. {secator-0.13.0 → secator-0.14.0}/secator/tasks/testssl.py +0 -0
  163. {secator-0.13.0 → secator-0.14.0}/secator/tasks/trivy.py +0 -0
  164. {secator-0.13.0 → secator-0.14.0}/secator/tasks/wafw00f.py +0 -0
  165. {secator-0.13.0 → secator-0.14.0}/secator/tasks/wpprobe.py +0 -0
  166. {secator-0.13.0 → secator-0.14.0}/secator/tasks/wpscan.py +0 -0
  167. {secator-0.13.0 → secator-0.14.0}/secator/thread.py +0 -0
  168. {secator-0.13.0 → secator-0.14.0}/secator/utils.py +0 -0
  169. {secator-0.13.0 → secator-0.14.0}/secator/utils_test.py +0 -0
  170. {secator-0.13.0 → secator-0.14.0}/secator/workflows/__init__.py +0 -0
  171. {secator-0.13.0 → secator-0.14.0}/tests/__init__.py +0 -0
  172. {secator-0.13.0 → secator-0.14.0}/tests/fixtures/h8mail_breach.txt +0 -0
  173. {secator-0.13.0 → secator-0.14.0}/tests/fixtures/ls.py +0 -0
  174. {secator-0.13.0 → secator-0.14.0}/tests/fixtures/msfconsole_input.rc +0 -0
  175. {secator-0.13.0 → secator-0.14.0}/tests/fixtures/nmap_output.xml +0 -0
  176. {secator-0.13.0 → secator-0.14.0}/tests/integration/__init__.py +0 -0
  177. {secator-0.13.0 → secator-0.14.0}/tests/integration/inputs.py +0 -0
  178. {secator-0.13.0 → secator-0.14.0}/tests/integration/outputs.py +0 -0
  179. {secator-0.13.0 → secator-0.14.0}/tests/integration/setup.sh +0 -0
  180. {secator-0.13.0 → secator-0.14.0}/tests/integration/teardown.sh +0 -0
  181. {secator-0.13.0 → secator-0.14.0}/tests/integration/test_addons.py +0 -0
  182. {secator-0.13.0 → secator-0.14.0}/tests/integration/test_celery.py +0 -0
  183. {secator-0.13.0 → secator-0.14.0}/tests/integration/test_helpers.py +0 -0
  184. {secator-0.13.0 → secator-0.14.0}/tests/integration/test_scans.py +0 -0
  185. {secator-0.13.0 → secator-0.14.0}/tests/integration/test_tasks.py +0 -0
  186. {secator-0.13.0 → secator-0.14.0}/tests/integration/test_worker.py +0 -0
  187. {secator-0.13.0 → secator-0.14.0}/tests/integration/test_workflows.py +0 -0
  188. {secator-0.13.0 → secator-0.14.0}/tests/integration/wordlist.txt +0 -0
  189. {secator-0.13.0 → secator-0.14.0}/tests/integration/wordlist_dns.txt +0 -0
  190. {secator-0.13.0 → secator-0.14.0}/tests/integration/wordpress_toolbox/Dockerfile +0 -0
  191. {secator-0.13.0 → secator-0.14.0}/tests/integration/wordpress_toolbox/Makefile +0 -0
  192. {secator-0.13.0 → secator-0.14.0}/tests/performance/__init__.py +0 -0
  193. {secator-0.13.0 → secator-0.14.0}/tests/performance/loadtester.py +0 -0
  194. {secator-0.13.0 → secator-0.14.0}/tests/performance/test_worker.py +0 -0
  195. {secator-0.13.0 → secator-0.14.0}/tests/unit/__init__.py +0 -0
  196. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_celery.py +0 -0
  197. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_cli.py +0 -0
  198. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_command.py +0 -0
  199. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_config.py +0 -0
  200. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_offline.py +0 -0
  201. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_runners.py +0 -0
  202. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_scans.py +0 -0
  203. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_serializers.py +0 -0
  204. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_tasks.py +0 -0
  205. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_tasks_categories.py +0 -0
  206. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_template.py +0 -0
  207. {secator-0.13.0 → secator-0.14.0}/tests/unit/test_utils.py +0 -0
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.14.0](https://github.com/freelabz/secator/compare/v0.13.0...v0.14.0) (2025-04-30)
4
+
5
+
6
+ ### Features
7
+
8
+ * add support for profiles ([#532](https://github.com/freelabz/secator/issues/532)) ([6f499b7](https://github.com/freelabz/secator/commit/6f499b72ec18dddde717e00318be4e2b53cc0478))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **cli:** restore --unified option, delete port_scan workflow ([#606](https://github.com/freelabz/secator/issues/606)) ([6dc647d](https://github.com/freelabz/secator/commit/6dc647d7205d15faa1c675485af441549d798118))
14
+
3
15
  ## [0.13.0](https://github.com/freelabz/secator/compare/v0.12.0...v0.13.0) (2025-04-29)
4
16
 
5
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: secator
3
- Version: 0.13.0
3
+ Version: 0.14.0
4
4
  Summary: The pentester's swiss knife.
5
5
  Project-URL: Homepage, https://github.com/freelabz/secator
6
6
  Project-URL: Issues, https://github.com/freelabz/secator/issues
@@ -4,7 +4,7 @@ build-backend = 'hatchling.build'
4
4
 
5
5
  [project]
6
6
  name = 'secator'
7
- version = "0.13.0"
7
+ version = "0.14.0"
8
8
  authors = [{ name = 'FreeLabz', email = 'sales@freelabz.com' }]
9
9
  readme = 'README.md'
10
10
  description = "The pentester's swiss knife."
@@ -36,6 +36,7 @@ click.rich_click.USE_RICH_MARKUP = True
36
36
  ALL_TASKS = discover_tasks()
37
37
  ALL_WORKFLOWS = [t for t in TEMPLATES if t.type == 'workflow']
38
38
  ALL_SCANS = [t for t in TEMPLATES if t.type == 'scan']
39
+ ALL_PROFILES = [t for t in TEMPLATES if t.type == 'profile']
39
40
  FINDING_TYPES_LOWER = [c.__name__.lower() for c in FINDING_TYPES]
40
41
  CONTEXT_SETTINGS = dict(help_option_names=['-h', '-help', '--help'])
41
42
 
@@ -125,6 +126,25 @@ for config in sorted(ALL_SCANS, key=lambda x: x['name']):
125
126
  register_runner(scan, config)
126
127
 
127
128
 
129
+ @cli.group(aliases=['p'])
130
+ @click.pass_context
131
+ def profile(ctx):
132
+ """Show profiles"""
133
+ pass
134
+
135
+
136
+ @profile.command('list')
137
+ def profile_list():
138
+ table = Table()
139
+ table.add_column("Profile name", style="bold gold3")
140
+ table.add_column("Description", overflow='fold')
141
+ table.add_column("Options", overflow='fold')
142
+ for profile in ALL_PROFILES:
143
+ opts_str = ','.join(f'{k}={v}' for k, v in profile.opts.items())
144
+ table.add_row(profile.name, profile.description, opts_str)
145
+ console.print(table)
146
+
147
+
128
148
  #--------#
129
149
  # WORKER #
130
150
  #--------#
@@ -685,7 +705,7 @@ def report_show(report_query, output, runner_type, time_delta, type, query, work
685
705
  all_results.extend(runner.results)
686
706
  continue
687
707
  report = Report(runner, title=f"Consolidated report - {current}", exporters=exporters)
688
- report.build(extractors=extractors if not unified else [])
708
+ report.build(extractors=extractors if not unified else [], dedupe=unified)
689
709
  file_date = get_file_date(path)
690
710
  runner_name = data['info']['name']
691
711
  console.print(
@@ -1423,6 +1443,16 @@ def task(name, verbose, check):
1423
1443
  task = task[0]
1424
1444
  task_name = task.__name__
1425
1445
 
1446
+ # Check task command is set
1447
+ check_test(
1448
+ task.cmd,
1449
+ 'Check task command is set (cls.cmd)',
1450
+ 'Task has no cmd attribute.',
1451
+ errors
1452
+ )
1453
+ if errors:
1454
+ sys.exit(0)
1455
+
1426
1456
  # Run install
1427
1457
  cmd = f'secator install tools {task_name}'
1428
1458
  ret_code = Command.execute(cmd, name='install', quiet=not verbose, cwd=ROOT_FOLDER)
@@ -1437,7 +1467,7 @@ def task(name, verbose, check):
1437
1467
  errors
1438
1468
  )
1439
1469
  check_test(
1440
- any(cmd for cmd in [task.install_cmd, task.install_github_handle]),
1470
+ any(cmd for cmd in [task.install_pre, task.install_cmd, task.install_github_handle]),
1441
1471
  'Check task installation command is defined',
1442
1472
  'Task has no installation command. Please define one or more of the following class attributes: `install_pre`, `install_cmd`, `install_post`, `install_github_handle`.', # noqa: E501
1443
1473
  errors
@@ -1471,12 +1501,6 @@ def task(name, verbose, check):
1471
1501
  'Task has no description (class docstring).',
1472
1502
  errors
1473
1503
  )
1474
- check_test(
1475
- task.cmd,
1476
- 'Check task command is set (cls.cmd)',
1477
- 'Task has no cmd attribute.',
1478
- errors
1479
- )
1480
1504
  check_test(
1481
1505
  task.input_type,
1482
1506
  'Check task input type is set (cls.input_type)',
@@ -0,0 +1,8 @@
1
+ type: profile
2
+ name: aggressive
3
+ description: "Internal networks or time-sensitive scans"
4
+ opts:
5
+ rate_limit: 10000
6
+ delay: 0
7
+ timeout: 1
8
+ retries: 1
@@ -0,0 +1,8 @@
1
+ type: profile
2
+ name: default
3
+ description: "General scanning"
4
+ opts:
5
+ rate_limit: 1000
6
+ delay: 0
7
+ timeout: 5
8
+ retries: 3
@@ -0,0 +1,8 @@
1
+ type: profile
2
+ name: insane
3
+ description: "Local LAN scanning or stress scanning"
4
+ opts:
5
+ rate_limit: 100000
6
+ delay: 0
7
+ timeout: 1
8
+ retries: 0
@@ -0,0 +1,8 @@
1
+ type: profile
2
+ name: paranoid
3
+ description: "Maximum stealth"
4
+ opts:
5
+ rate_limit: 5
6
+ delay: 5
7
+ timeout: 15
8
+ retries: 5
@@ -0,0 +1,8 @@
1
+ type: profile
2
+ name: polite
3
+ description: "Avoid overloading network"
4
+ opts:
5
+ rate_limit: 100
6
+ delay: 0
7
+ timeout: 10
8
+ retries: 5
@@ -0,0 +1,8 @@
1
+ type: profile
2
+ name: sneaky
3
+ description: "IDS/IPS evasion, sensitive networks"
4
+ opts:
5
+ rate_limit: 10
6
+ delay: 2
7
+ timeout: 15
8
+ retries: 5
@@ -0,0 +1,5 @@
1
+ type: profile
2
+ name: tor
3
+ description: "Anonymous scan using Tor network"
4
+ opts:
5
+ proxy: tor
@@ -13,6 +13,7 @@ from secator.utils import (deduplicate, expand_input, get_command_category)
13
13
 
14
14
  RUNNER_OPTS = {
15
15
  'output': {'type': str, 'default': None, 'help': 'Output options (-o table,json,csv,gdrive)', 'short': 'o'},
16
+ 'profiles': {'type': str, 'default': 'default', 'help': 'Profiles', 'short': 'pf'},
16
17
  'workspace': {'type': str, 'default': 'default', 'help': 'Workspace', 'short': 'ws'},
17
18
  'print_json': {'is_flag': True, 'short': 'json', 'default': False, 'help': 'Print items as JSON lines'},
18
19
  'print_raw': {'is_flag': True, 'short': 'raw', 'default': False, 'help': 'Print items in raw format'},
@@ -55,7 +55,7 @@ class Report:
55
55
  f'{str(e)}[/]\n[dim]{traceback_as_string(e)}[/]',
56
56
  )
57
57
 
58
- def build(self, extractors=[], dedupe=False):
58
+ def build(self, extractors=[], dedupe=CONFIG.runners.remove_duplicates):
59
59
  # Trim options
60
60
  from secator.decorators import DEFAULT_CLI_OPTIONS
61
61
  opts = merge_opts(self.runner.config.options, self.runner.run_opts)
@@ -97,7 +97,7 @@ class Report:
97
97
  if items:
98
98
  if sort_by and all(sort_by):
99
99
  items = sorted(items, key=operator.attrgetter(*sort_by))
100
- if dedupe and CONFIG.runners.remove_duplicates:
100
+ if dedupe:
101
101
  items = remove_duplicates(items)
102
102
  # items = [item for item in items if not item._duplicate and item not in dedupe_from]
103
103
  for extractor in extractors:
@@ -138,6 +138,10 @@ class Runner:
138
138
  self.debug('Run opts', obj={k: v for k, v in self.run_opts.items() if v is not None}, sub='init')
139
139
  self.debug('Print opts', obj={k: v for k, v in self.print_opts.items() if v is not None}, sub='init')
140
140
 
141
+ # Load profiles
142
+ profiles_str = run_opts.get('profiles', [])
143
+ self.load_profiles(profiles_str)
144
+
141
145
  # Determine exporters
142
146
  exporters_str = self.run_opts.get('output') or self.default_exporters
143
147
  self.exporters = self.resolve_exporters(exporters_str)
@@ -953,6 +957,32 @@ class Runner:
953
957
  ]
954
958
  return [cls for cls in classes if cls]
955
959
 
960
+ def load_profiles(self, profiles):
961
+ """Load profiles and update run options.
962
+
963
+ Args:
964
+ profiles (list[str]): List of profile names to resolve.
965
+
966
+ Returns:
967
+ list: List of profiles.
968
+ """
969
+ from secator.cli import ALL_PROFILES
970
+ if isinstance(profiles, str):
971
+ profiles = profiles.split(',')
972
+ templates = []
973
+ for pname in profiles:
974
+ matches = [p for p in ALL_PROFILES if p.name == pname]
975
+ if not matches:
976
+ self._print(Warning(message=f'Profile "{pname}" was not found'), rich=True)
977
+ else:
978
+ templates.append(matches[0])
979
+ opts = {}
980
+ for profile in templates:
981
+ self._print(Info(message=f'Loaded profile {profile.name} ({profile.description})'), rich=True)
982
+ opts.update(profile.opts)
983
+ opts = {k: v for k, v in opts.items() if k not in self.run_opts}
984
+ self.run_opts.update(opts)
985
+
956
986
  @classmethod
957
987
  def get_func_path(cls, func):
958
988
  """Get the full symbolic path of a function or method, including staticmethods, using function and method
@@ -33,6 +33,7 @@ class Scan(Runner):
33
33
  sigs = []
34
34
  for name, workflow_opts in self.config.workflows.items():
35
35
  run_opts = self.run_opts.copy()
36
+ run_opts.pop('profiles', None)
36
37
  run_opts['no_poll'] = True
37
38
  run_opts['caller'] = 'Scan'
38
39
  opts = merge_opts(scan_opts, workflow_opts, run_opts)
@@ -32,6 +32,7 @@ class Task(Runner):
32
32
  # Run opts
33
33
  opts = self.run_opts.copy()
34
34
  opts.pop('output', None)
35
+ opts.pop('profiles', None)
35
36
  opts.pop('no_poll', False)
36
37
 
37
38
  # Set output types
@@ -64,7 +64,7 @@ class TemplateLoader(DotMap):
64
64
  _path = config.pop('_path', None)
65
65
  if _path:
66
66
  console.print(f'[italic green]{_path}[/]\n')
67
- yaml_str = yaml.dump(config, indent=4)
67
+ yaml_str = yaml.dump(config, indent=4, sort_keys=False)
68
68
  from rich.syntax import Syntax
69
69
  yaml_highlight = Syntax(yaml_str, 'yaml', line_numbers=True)
70
70
  console.print(yaml_highlight)
@@ -1,7 +0,0 @@
1
- type: profile
2
- name: aggressive
3
- options:
4
- rate_limit: 100000
5
- delay: 0
6
- proxy: random
7
- user_agent: random
@@ -1,9 +0,0 @@
1
- type: profile
2
- name: default
3
- options:
4
- rate_limit: 1000
5
- delay: 1
6
- proxy: null
7
- user_agent: 'Mozilla ...'
8
- nuclei.retries: 5
9
- nuclei.timeout: 15
@@ -1,7 +0,0 @@
1
- type: profile
2
- name: stealth
3
- options:
4
- rate_limit: 100
5
- delay: 1
6
- proxy: proxychains
7
- user_agent: random
@@ -1,39 +0,0 @@
1
- type: workflow
2
- name: port_scan
3
- alias: pscan
4
- description: Port scan
5
- tags: [recon, network, http, vuln]
6
- input_types:
7
- - host
8
- - cidr_range
9
- tasks:
10
- naabu:
11
- description: Find open ports
12
- skip_host_discovery: True
13
- ports: "-" # scan all ports
14
- nmap:
15
- description: Search for vulnerabilities on open ports
16
- skip_host_discovery: True
17
- version_detection: True
18
- targets_: port.host
19
- ports_: port.port
20
- _group:
21
- searchsploit:
22
- description: Search for related exploits
23
- targets_:
24
- - type: port
25
- field: '{host}~{service_name}'
26
- condition: item._source.startswith('nmap') and len(item.service_name.split('/')) > 1
27
- httpx:
28
- description: Probe HTTP services on open ports
29
- targets_:
30
- - type: port
31
- field: '{host}:{port}'
32
- condition: item._source.startswith('nmap')
33
- results:
34
- - type: port
35
-
36
- - type: url
37
- condition: item.status_code != 0
38
-
39
- - type: vulnerability
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes