souleyez 2.43.29__py3-none-any.whl → 2.43.34__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 souleyez might be problematic. Click here for more details.

Files changed (358) hide show
  1. souleyez/__init__.py +1 -2
  2. souleyez/ai/__init__.py +21 -15
  3. souleyez/ai/action_mapper.py +249 -150
  4. souleyez/ai/chain_advisor.py +116 -100
  5. souleyez/ai/claude_provider.py +29 -28
  6. souleyez/ai/context_builder.py +80 -62
  7. souleyez/ai/executor.py +158 -117
  8. souleyez/ai/feedback_handler.py +136 -121
  9. souleyez/ai/llm_factory.py +27 -20
  10. souleyez/ai/llm_provider.py +4 -2
  11. souleyez/ai/ollama_provider.py +6 -9
  12. souleyez/ai/ollama_service.py +44 -37
  13. souleyez/ai/path_scorer.py +91 -76
  14. souleyez/ai/recommender.py +176 -144
  15. souleyez/ai/report_context.py +74 -73
  16. souleyez/ai/report_service.py +84 -66
  17. souleyez/ai/result_parser.py +222 -229
  18. souleyez/ai/safety.py +67 -44
  19. souleyez/auth/__init__.py +23 -22
  20. souleyez/auth/audit.py +36 -26
  21. souleyez/auth/engagement_access.py +65 -48
  22. souleyez/auth/permissions.py +14 -3
  23. souleyez/auth/session_manager.py +54 -37
  24. souleyez/auth/user_manager.py +109 -64
  25. souleyez/commands/audit.py +40 -43
  26. souleyez/commands/auth.py +35 -15
  27. souleyez/commands/deliverables.py +55 -50
  28. souleyez/commands/engagement.py +47 -28
  29. souleyez/commands/license.py +32 -23
  30. souleyez/commands/screenshots.py +36 -32
  31. souleyez/commands/user.py +82 -36
  32. souleyez/config.py +52 -44
  33. souleyez/core/credential_tester.py +87 -81
  34. souleyez/core/cve_mappings.py +179 -192
  35. souleyez/core/cve_matcher.py +162 -148
  36. souleyez/core/msf_auto_mapper.py +100 -83
  37. souleyez/core/msf_chain_engine.py +294 -256
  38. souleyez/core/msf_database.py +153 -70
  39. souleyez/core/msf_integration.py +679 -673
  40. souleyez/core/msf_rpc_client.py +40 -42
  41. souleyez/core/msf_rpc_manager.py +77 -79
  42. souleyez/core/msf_sync_manager.py +241 -181
  43. souleyez/core/network_utils.py +22 -15
  44. souleyez/core/parser_handler.py +34 -25
  45. souleyez/core/pending_chains.py +114 -63
  46. souleyez/core/templates.py +158 -107
  47. souleyez/core/tool_chaining.py +9526 -2879
  48. souleyez/core/version_utils.py +79 -94
  49. souleyez/core/vuln_correlation.py +136 -89
  50. souleyez/core/web_utils.py +33 -32
  51. souleyez/data/wordlists/ad_users.txt +378 -0
  52. souleyez/data/wordlists/api_endpoints_large.txt +769 -0
  53. souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
  54. souleyez/data/wordlists/lfi_payloads.txt +82 -0
  55. souleyez/data/wordlists/passwords_brute.txt +1548 -0
  56. souleyez/data/wordlists/passwords_crack.txt +2479 -0
  57. souleyez/data/wordlists/passwords_spray.txt +386 -0
  58. souleyez/data/wordlists/subdomains_large.txt +5057 -0
  59. souleyez/data/wordlists/usernames_common.txt +694 -0
  60. souleyez/data/wordlists/web_dirs_large.txt +4769 -0
  61. souleyez/detection/__init__.py +1 -1
  62. souleyez/detection/attack_signatures.py +12 -17
  63. souleyez/detection/mitre_mappings.py +61 -55
  64. souleyez/detection/validator.py +97 -86
  65. souleyez/devtools.py +23 -10
  66. souleyez/docs/README.md +4 -4
  67. souleyez/docs/api-reference/cli-commands.md +2 -2
  68. souleyez/docs/developer-guide/adding-new-tools.md +562 -0
  69. souleyez/docs/user-guide/auto-chaining.md +30 -8
  70. souleyez/docs/user-guide/getting-started.md +1 -1
  71. souleyez/docs/user-guide/installation.md +26 -3
  72. souleyez/docs/user-guide/metasploit-integration.md +2 -2
  73. souleyez/docs/user-guide/rbac.md +1 -1
  74. souleyez/docs/user-guide/scope-management.md +1 -1
  75. souleyez/docs/user-guide/siem-integration.md +1 -1
  76. souleyez/docs/user-guide/tools-reference.md +1 -8
  77. souleyez/docs/user-guide/worker-management.md +1 -1
  78. souleyez/engine/background.py +1239 -535
  79. souleyez/engine/base.py +4 -1
  80. souleyez/engine/job_status.py +17 -49
  81. souleyez/engine/log_sanitizer.py +103 -77
  82. souleyez/engine/manager.py +38 -7
  83. souleyez/engine/result_handler.py +2200 -1550
  84. souleyez/engine/worker_manager.py +50 -41
  85. souleyez/export/evidence_bundle.py +72 -62
  86. souleyez/feature_flags/features.py +16 -20
  87. souleyez/feature_flags.py +5 -9
  88. souleyez/handlers/__init__.py +11 -0
  89. souleyez/handlers/base.py +188 -0
  90. souleyez/handlers/bash_handler.py +277 -0
  91. souleyez/handlers/bloodhound_handler.py +243 -0
  92. souleyez/handlers/certipy_handler.py +311 -0
  93. souleyez/handlers/crackmapexec_handler.py +486 -0
  94. souleyez/handlers/dnsrecon_handler.py +344 -0
  95. souleyez/handlers/enum4linux_handler.py +400 -0
  96. souleyez/handlers/evil_winrm_handler.py +493 -0
  97. souleyez/handlers/ffuf_handler.py +815 -0
  98. souleyez/handlers/gobuster_handler.py +1114 -0
  99. souleyez/handlers/gpp_extract_handler.py +334 -0
  100. souleyez/handlers/hashcat_handler.py +444 -0
  101. souleyez/handlers/hydra_handler.py +563 -0
  102. souleyez/handlers/impacket_getuserspns_handler.py +343 -0
  103. souleyez/handlers/impacket_psexec_handler.py +222 -0
  104. souleyez/handlers/impacket_secretsdump_handler.py +426 -0
  105. souleyez/handlers/john_handler.py +286 -0
  106. souleyez/handlers/katana_handler.py +425 -0
  107. souleyez/handlers/kerbrute_handler.py +298 -0
  108. souleyez/handlers/ldapsearch_handler.py +636 -0
  109. souleyez/handlers/lfi_extract_handler.py +464 -0
  110. souleyez/handlers/msf_auxiliary_handler.py +408 -0
  111. souleyez/handlers/msf_exploit_handler.py +380 -0
  112. souleyez/handlers/nikto_handler.py +413 -0
  113. souleyez/handlers/nmap_handler.py +821 -0
  114. souleyez/handlers/nuclei_handler.py +359 -0
  115. souleyez/handlers/nxc_handler.py +371 -0
  116. souleyez/handlers/rdp_sec_check_handler.py +353 -0
  117. souleyez/handlers/registry.py +292 -0
  118. souleyez/handlers/responder_handler.py +232 -0
  119. souleyez/handlers/service_explorer_handler.py +434 -0
  120. souleyez/handlers/smbclient_handler.py +344 -0
  121. souleyez/handlers/smbmap_handler.py +510 -0
  122. souleyez/handlers/smbpasswd_handler.py +296 -0
  123. souleyez/handlers/sqlmap_handler.py +1116 -0
  124. souleyez/handlers/theharvester_handler.py +601 -0
  125. souleyez/handlers/web_login_test_handler.py +327 -0
  126. souleyez/handlers/whois_handler.py +277 -0
  127. souleyez/handlers/wpscan_handler.py +554 -0
  128. souleyez/history.py +32 -16
  129. souleyez/importers/msf_importer.py +106 -75
  130. souleyez/importers/smart_importer.py +208 -147
  131. souleyez/integrations/siem/__init__.py +10 -10
  132. souleyez/integrations/siem/base.py +17 -18
  133. souleyez/integrations/siem/elastic.py +108 -122
  134. souleyez/integrations/siem/factory.py +207 -80
  135. souleyez/integrations/siem/googlesecops.py +146 -154
  136. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  137. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  138. souleyez/integrations/siem/sentinel.py +107 -109
  139. souleyez/integrations/siem/splunk.py +246 -212
  140. souleyez/integrations/siem/wazuh.py +65 -71
  141. souleyez/integrations/wazuh/__init__.py +5 -5
  142. souleyez/integrations/wazuh/client.py +70 -93
  143. souleyez/integrations/wazuh/config.py +85 -57
  144. souleyez/integrations/wazuh/host_mapper.py +28 -36
  145. souleyez/integrations/wazuh/sync.py +78 -68
  146. souleyez/intelligence/__init__.py +4 -5
  147. souleyez/intelligence/correlation_analyzer.py +309 -295
  148. souleyez/intelligence/exploit_knowledge.py +661 -623
  149. souleyez/intelligence/exploit_suggestions.py +159 -139
  150. souleyez/intelligence/gap_analyzer.py +132 -97
  151. souleyez/intelligence/gap_detector.py +251 -214
  152. souleyez/intelligence/sensitive_tables.py +266 -129
  153. souleyez/intelligence/service_parser.py +137 -123
  154. souleyez/intelligence/surface_analyzer.py +407 -268
  155. souleyez/intelligence/target_parser.py +159 -162
  156. souleyez/licensing/__init__.py +6 -6
  157. souleyez/licensing/validator.py +17 -19
  158. souleyez/log_config.py +79 -54
  159. souleyez/main.py +1505 -687
  160. souleyez/migrations/fix_job_counter.py +16 -14
  161. souleyez/parsers/bloodhound_parser.py +41 -39
  162. souleyez/parsers/crackmapexec_parser.py +178 -111
  163. souleyez/parsers/dalfox_parser.py +72 -77
  164. souleyez/parsers/dnsrecon_parser.py +103 -91
  165. souleyez/parsers/enum4linux_parser.py +183 -153
  166. souleyez/parsers/ffuf_parser.py +29 -25
  167. souleyez/parsers/gobuster_parser.py +301 -41
  168. souleyez/parsers/hashcat_parser.py +324 -79
  169. souleyez/parsers/http_fingerprint_parser.py +350 -103
  170. souleyez/parsers/hydra_parser.py +131 -111
  171. souleyez/parsers/impacket_parser.py +231 -178
  172. souleyez/parsers/john_parser.py +98 -86
  173. souleyez/parsers/katana_parser.py +316 -0
  174. souleyez/parsers/msf_parser.py +943 -498
  175. souleyez/parsers/nikto_parser.py +346 -65
  176. souleyez/parsers/nmap_parser.py +262 -174
  177. souleyez/parsers/nuclei_parser.py +40 -44
  178. souleyez/parsers/responder_parser.py +26 -26
  179. souleyez/parsers/searchsploit_parser.py +74 -74
  180. souleyez/parsers/service_explorer_parser.py +279 -0
  181. souleyez/parsers/smbmap_parser.py +180 -124
  182. souleyez/parsers/sqlmap_parser.py +434 -308
  183. souleyez/parsers/theharvester_parser.py +75 -57
  184. souleyez/parsers/whois_parser.py +135 -94
  185. souleyez/parsers/wpscan_parser.py +278 -190
  186. souleyez/plugins/afp.py +44 -36
  187. souleyez/plugins/afp_brute.py +114 -46
  188. souleyez/plugins/ard.py +48 -37
  189. souleyez/plugins/bloodhound.py +95 -61
  190. souleyez/plugins/certipy.py +303 -0
  191. souleyez/plugins/crackmapexec.py +186 -85
  192. souleyez/plugins/dalfox.py +120 -59
  193. souleyez/plugins/dns_hijack.py +146 -41
  194. souleyez/plugins/dnsrecon.py +97 -61
  195. souleyez/plugins/enum4linux.py +91 -66
  196. souleyez/plugins/evil_winrm.py +291 -0
  197. souleyez/plugins/ffuf.py +166 -90
  198. souleyez/plugins/firmware_extract.py +133 -29
  199. souleyez/plugins/gobuster.py +387 -190
  200. souleyez/plugins/gpp_extract.py +393 -0
  201. souleyez/plugins/hashcat.py +100 -73
  202. souleyez/plugins/http_fingerprint.py +854 -267
  203. souleyez/plugins/hydra.py +566 -200
  204. souleyez/plugins/impacket_getnpusers.py +117 -69
  205. souleyez/plugins/impacket_psexec.py +84 -64
  206. souleyez/plugins/impacket_secretsdump.py +103 -69
  207. souleyez/plugins/impacket_smbclient.py +89 -75
  208. souleyez/plugins/john.py +86 -69
  209. souleyez/plugins/katana.py +313 -0
  210. souleyez/plugins/kerbrute.py +237 -0
  211. souleyez/plugins/lfi_extract.py +541 -0
  212. souleyez/plugins/macos_ssh.py +117 -48
  213. souleyez/plugins/mdns.py +35 -30
  214. souleyez/plugins/msf_auxiliary.py +253 -130
  215. souleyez/plugins/msf_exploit.py +239 -161
  216. souleyez/plugins/nikto.py +134 -78
  217. souleyez/plugins/nmap.py +275 -91
  218. souleyez/plugins/nuclei.py +180 -89
  219. souleyez/plugins/nxc.py +285 -0
  220. souleyez/plugins/plugin_base.py +35 -36
  221. souleyez/plugins/plugin_template.py +13 -5
  222. souleyez/plugins/rdp_sec_check.py +130 -0
  223. souleyez/plugins/responder.py +112 -71
  224. souleyez/plugins/router_http_brute.py +76 -65
  225. souleyez/plugins/router_ssh_brute.py +118 -41
  226. souleyez/plugins/router_telnet_brute.py +124 -42
  227. souleyez/plugins/routersploit.py +91 -59
  228. souleyez/plugins/routersploit_exploit.py +77 -55
  229. souleyez/plugins/searchsploit.py +91 -77
  230. souleyez/plugins/service_explorer.py +1160 -0
  231. souleyez/plugins/smbmap.py +122 -72
  232. souleyez/plugins/smbpasswd.py +215 -0
  233. souleyez/plugins/sqlmap.py +301 -113
  234. souleyez/plugins/theharvester.py +127 -75
  235. souleyez/plugins/tr069.py +79 -57
  236. souleyez/plugins/upnp.py +65 -47
  237. souleyez/plugins/upnp_abuse.py +73 -55
  238. souleyez/plugins/vnc_access.py +129 -42
  239. souleyez/plugins/vnc_brute.py +109 -38
  240. souleyez/plugins/web_login_test.py +417 -0
  241. souleyez/plugins/whois.py +77 -58
  242. souleyez/plugins/wpscan.py +173 -69
  243. souleyez/reporting/__init__.py +2 -1
  244. souleyez/reporting/attack_chain.py +411 -346
  245. souleyez/reporting/charts.py +436 -501
  246. souleyez/reporting/compliance_mappings.py +334 -201
  247. souleyez/reporting/detection_report.py +126 -125
  248. souleyez/reporting/formatters.py +828 -591
  249. souleyez/reporting/generator.py +386 -302
  250. souleyez/reporting/metrics.py +72 -75
  251. souleyez/scanner.py +35 -29
  252. souleyez/security/__init__.py +37 -11
  253. souleyez/security/scope_validator.py +175 -106
  254. souleyez/security/validation.py +223 -149
  255. souleyez/security.py +22 -6
  256. souleyez/storage/credentials.py +247 -186
  257. souleyez/storage/crypto.py +296 -129
  258. souleyez/storage/database.py +73 -50
  259. souleyez/storage/db.py +58 -36
  260. souleyez/storage/deliverable_evidence.py +177 -128
  261. souleyez/storage/deliverable_exporter.py +282 -246
  262. souleyez/storage/deliverable_templates.py +134 -116
  263. souleyez/storage/deliverables.py +135 -130
  264. souleyez/storage/engagements.py +109 -56
  265. souleyez/storage/evidence.py +181 -152
  266. souleyez/storage/execution_log.py +31 -17
  267. souleyez/storage/exploit_attempts.py +93 -57
  268. souleyez/storage/exploits.py +67 -36
  269. souleyez/storage/findings.py +48 -61
  270. souleyez/storage/hosts.py +176 -144
  271. souleyez/storage/migrate_to_engagements.py +43 -19
  272. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  273. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  274. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  275. souleyez/storage/migrations/_005_screenshots.py +13 -5
  276. souleyez/storage/migrations/_006_deliverables.py +13 -5
  277. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  278. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  279. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  280. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  281. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  282. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  283. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  284. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  285. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  286. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  287. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  288. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  289. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  290. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  291. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  292. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  293. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  294. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  295. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  296. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  297. souleyez/storage/migrations/__init__.py +26 -26
  298. souleyez/storage/migrations/migration_manager.py +19 -19
  299. souleyez/storage/msf_sessions.py +100 -65
  300. souleyez/storage/osint.py +17 -24
  301. souleyez/storage/recommendation_engine.py +269 -235
  302. souleyez/storage/screenshots.py +33 -32
  303. souleyez/storage/smb_shares.py +136 -92
  304. souleyez/storage/sqlmap_data.py +183 -128
  305. souleyez/storage/team_collaboration.py +135 -141
  306. souleyez/storage/timeline_tracker.py +122 -94
  307. souleyez/storage/wazuh_vulns.py +64 -66
  308. souleyez/storage/web_paths.py +33 -37
  309. souleyez/testing/credential_tester.py +221 -205
  310. souleyez/ui/__init__.py +1 -1
  311. souleyez/ui/ai_quotes.py +12 -12
  312. souleyez/ui/attack_surface.py +2439 -1516
  313. souleyez/ui/chain_rules_view.py +914 -382
  314. souleyez/ui/correlation_view.py +312 -230
  315. souleyez/ui/dashboard.py +2382 -1130
  316. souleyez/ui/deliverables_view.py +148 -62
  317. souleyez/ui/design_system.py +13 -13
  318. souleyez/ui/errors.py +49 -49
  319. souleyez/ui/evidence_linking_view.py +284 -179
  320. souleyez/ui/evidence_vault.py +393 -285
  321. souleyez/ui/exploit_suggestions_view.py +555 -349
  322. souleyez/ui/export_view.py +100 -66
  323. souleyez/ui/gap_analysis_view.py +315 -171
  324. souleyez/ui/help_system.py +105 -97
  325. souleyez/ui/intelligence_view.py +436 -293
  326. souleyez/ui/interactive.py +22827 -10678
  327. souleyez/ui/interactive_selector.py +75 -68
  328. souleyez/ui/log_formatter.py +47 -39
  329. souleyez/ui/menu_components.py +22 -13
  330. souleyez/ui/msf_auxiliary_menu.py +184 -133
  331. souleyez/ui/pending_chains_view.py +336 -172
  332. souleyez/ui/progress_indicators.py +5 -3
  333. souleyez/ui/recommendations_view.py +195 -137
  334. souleyez/ui/rule_builder.py +343 -225
  335. souleyez/ui/setup_wizard.py +678 -284
  336. souleyez/ui/shortcuts.py +217 -165
  337. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  338. souleyez/ui/splunk_vulns_view.py +139 -86
  339. souleyez/ui/team_dashboard.py +498 -335
  340. souleyez/ui/template_selector.py +196 -105
  341. souleyez/ui/terminal.py +6 -6
  342. souleyez/ui/timeline_view.py +198 -127
  343. souleyez/ui/tool_setup.py +264 -164
  344. souleyez/ui/tutorial.py +202 -72
  345. souleyez/ui/tutorial_state.py +40 -40
  346. souleyez/ui/wazuh_vulns_view.py +235 -141
  347. souleyez/ui/wordlist_browser.py +260 -107
  348. souleyez/ui.py +464 -312
  349. souleyez/utils/tool_checker.py +427 -367
  350. souleyez/utils.py +33 -29
  351. souleyez/wordlists.py +134 -167
  352. {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/METADATA +1 -1
  353. souleyez-2.43.34.dist-info/RECORD +443 -0
  354. {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/WHEEL +1 -1
  355. souleyez-2.43.29.dist-info/RECORD +0 -379
  356. {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/entry_points.txt +0 -0
  357. {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/licenses/LICENSE +0 -0
  358. {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,417 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ souleyez.plugins.web_login_test - Web login credential testing
4
+
5
+ Tests cracked credentials against web login endpoints.
6
+ Supports both JSON REST APIs and traditional HTML form logins.
7
+ """
8
+ import json
9
+ import re
10
+ import ssl
11
+ import time
12
+ import urllib.error
13
+ import urllib.parse
14
+ import urllib.request
15
+ from typing import Any, Dict, List, Optional
16
+
17
+ from .plugin_base import PluginBase
18
+
19
+ HELP = {
20
+ "name": "Web Login Test - Credential Validation",
21
+ "description": (
22
+ "Tests credentials against web login endpoints to validate "
23
+ "that cracked passwords actually work.\n\n"
24
+ "Supports:\n"
25
+ "- JSON REST APIs (Content-Type: application/json)\n"
26
+ "- HTML form submissions\n"
27
+ "- Custom field names via --username-field and --password-field\n"
28
+ ),
29
+ "usage": 'souleyez jobs enqueue web_login_test <login_url> --args "--username <user> --password <pass>"',
30
+ "examples": [
31
+ 'souleyez jobs enqueue web_login_test http://target/api/login --args "--username admin --password secret"',
32
+ 'souleyez jobs enqueue web_login_test http://target/login.php --args "--username admin --password secret --form"',
33
+ ],
34
+ "flags": [
35
+ ["--username <user>", "Username to test"],
36
+ ["--password <pass>", "Password to test"],
37
+ ["--form", "Use form POST instead of JSON (default: JSON)"],
38
+ ["--username-field <name>", "Custom username field name (default: email)"],
39
+ ["--password-field <name>", "Custom password field name (default: password)"],
40
+ ],
41
+ "presets": [
42
+ {
43
+ "name": "JSON API Login",
44
+ "args": ["--username", "<username>", "--password", "<password>"],
45
+ "desc": "Test JSON API login endpoint",
46
+ },
47
+ {
48
+ "name": "Form Login",
49
+ "args": ["--username", "<username>", "--password", "<password>", "--form"],
50
+ "desc": "Test HTML form login",
51
+ },
52
+ ],
53
+ "help_sections": [
54
+ {
55
+ "title": "How It Works",
56
+ "color": "cyan",
57
+ "content": [
58
+ (
59
+ "Overview",
60
+ [
61
+ "Sends POST request with credentials to login endpoint",
62
+ "Analyzes response for success/failure indicators",
63
+ "Supports JSON APIs and form-based authentication",
64
+ ],
65
+ ),
66
+ (
67
+ "Success Detection",
68
+ [
69
+ "Looks for: token, success, authenticated in response",
70
+ "HTTP 200/201 with positive indicators = success",
71
+ "HTTP 401/403 or error messages = failure",
72
+ ],
73
+ ),
74
+ ],
75
+ },
76
+ {
77
+ "title": "Usage & Examples",
78
+ "color": "green",
79
+ "content": [
80
+ (
81
+ "JSON API Login (default)",
82
+ [
83
+ "souleyez jobs enqueue web_login_test http://target/api/login \\",
84
+ ' --args "--username admin --password secret"',
85
+ ' → Sends JSON: {"email": "admin", "password": "secret"}',
86
+ ],
87
+ ),
88
+ (
89
+ "HTML Form Login",
90
+ [
91
+ "souleyez jobs enqueue web_login_test http://target/login.php \\",
92
+ ' --args "--username admin --password secret --form"',
93
+ " → Sends form data: email=admin&password=secret",
94
+ ],
95
+ ),
96
+ (
97
+ "Custom Field Names",
98
+ [
99
+ "souleyez jobs enqueue web_login_test http://target/login \\",
100
+ ' --args "--username admin --password secret --username-field user --password-field pass"',
101
+ " → Uses custom field names instead of email/password",
102
+ ],
103
+ ),
104
+ ],
105
+ },
106
+ {
107
+ "title": "Automatic Chaining",
108
+ "color": "yellow",
109
+ "content": [
110
+ (
111
+ "When This Tool Runs Automatically",
112
+ [
113
+ "After hashcat cracks passwords from SQLMap dumps",
114
+ "Validates cracked credentials against the original login endpoint",
115
+ "Auto-detects JSON vs form format from URL patterns",
116
+ ],
117
+ ),
118
+ (
119
+ "Chain Flow",
120
+ [
121
+ "SQLMap extracts hashed passwords from database",
122
+ "Hashcat cracks the hashes to plaintext",
123
+ "Web Login Test validates: do these credentials work?",
124
+ "Validated credentials are stored for reporting",
125
+ ],
126
+ ),
127
+ ],
128
+ },
129
+ ],
130
+ }
131
+
132
+
133
+ class WebLoginTestPlugin(PluginBase):
134
+ """Plugin for testing web login credentials."""
135
+
136
+ name = "Web Login Test"
137
+ tool = "web_login_test"
138
+ category = "credential_access"
139
+ HELP = HELP
140
+
141
+ # Success indicators in response body
142
+ SUCCESS_INDICATORS = [
143
+ "token",
144
+ "access_token",
145
+ "jwt",
146
+ "session",
147
+ "authenticated",
148
+ "success",
149
+ "welcome",
150
+ "dashboard",
151
+ "logged in",
152
+ ]
153
+
154
+ # Failure indicators in response body
155
+ FAILURE_INDICATORS = [
156
+ "invalid",
157
+ "incorrect",
158
+ "failed",
159
+ "error",
160
+ "unauthorized",
161
+ "denied",
162
+ "wrong password",
163
+ "bad credentials",
164
+ "authentication failed",
165
+ ]
166
+
167
+ def build_command(
168
+ self,
169
+ target: str,
170
+ args: List[str] = None,
171
+ label: str = "",
172
+ log_path: str = None,
173
+ ) -> Optional[Dict[str, Any]]:
174
+ """
175
+ Web login test runs in Python, not via external command.
176
+ Return None to use run() method instead.
177
+ """
178
+ return None
179
+
180
+ def run(
181
+ self,
182
+ target: str,
183
+ args: List[str] = None,
184
+ label: str = "",
185
+ log_path: str = None,
186
+ ) -> int:
187
+ """Execute web login credential test."""
188
+ args = args or []
189
+
190
+ # Parse arguments
191
+ username = None
192
+ password = None
193
+ use_form = False
194
+ username_field = "email"
195
+ password_field = "password"
196
+
197
+ i = 0
198
+ while i < len(args):
199
+ arg = args[i]
200
+ if arg == "--username" and i + 1 < len(args):
201
+ username = args[i + 1]
202
+ i += 2
203
+ elif arg == "--password" and i + 1 < len(args):
204
+ password = args[i + 1]
205
+ i += 2
206
+ elif arg == "--form":
207
+ use_form = True
208
+ i += 1
209
+ elif arg == "--username-field" and i + 1 < len(args):
210
+ username_field = args[i + 1]
211
+ i += 2
212
+ elif arg == "--password-field" and i + 1 < len(args):
213
+ password_field = args[i + 1]
214
+ i += 2
215
+ else:
216
+ i += 1
217
+
218
+ if not username or not password:
219
+ self._write_log(
220
+ log_path,
221
+ target,
222
+ username,
223
+ error="Missing --username or --password argument",
224
+ )
225
+ return 1
226
+
227
+ # Ensure target has scheme
228
+ if not target.startswith(("http://", "https://")):
229
+ target = f"http://{target}"
230
+
231
+ try:
232
+ result = self._test_login(
233
+ url=target,
234
+ username=username,
235
+ password=password,
236
+ use_form=use_form,
237
+ username_field=username_field,
238
+ password_field=password_field,
239
+ )
240
+
241
+ self._write_log(log_path, target, username, result=result)
242
+
243
+ # Return 0 for success, 1 for failure
244
+ return 0 if result.get("success") else 1
245
+
246
+ except Exception as e:
247
+ self._write_log(log_path, target, username, error=str(e))
248
+ return 1
249
+
250
+ def _test_login(
251
+ self,
252
+ url: str,
253
+ username: str,
254
+ password: str,
255
+ use_form: bool = False,
256
+ username_field: str = "email",
257
+ password_field: str = "password",
258
+ timeout: int = 15,
259
+ ) -> Dict[str, Any]:
260
+ """
261
+ Test login credentials against a web endpoint.
262
+
263
+ Returns dict with:
264
+ - success: bool
265
+ - http_code: int
266
+ - response: str (truncated)
267
+ - reason: str (why success/failure was determined)
268
+ """
269
+ result = {
270
+ "success": False,
271
+ "http_code": None,
272
+ "response": None,
273
+ "reason": None,
274
+ }
275
+
276
+ # Create SSL context that accepts self-signed certs
277
+ ctx = ssl.create_default_context()
278
+ ctx.check_hostname = False
279
+ ctx.verify_mode = ssl.CERT_NONE
280
+
281
+ # Build request data
282
+ if use_form:
283
+ # Form-encoded POST
284
+ data = urllib.parse.urlencode(
285
+ {username_field: username, password_field: password}
286
+ ).encode("utf-8")
287
+ content_type = "application/x-www-form-urlencoded"
288
+ else:
289
+ # JSON POST
290
+ data = json.dumps(
291
+ {username_field: username, password_field: password}
292
+ ).encode("utf-8")
293
+ content_type = "application/json"
294
+
295
+ # Create request
296
+ req = urllib.request.Request(
297
+ url,
298
+ data=data,
299
+ headers={
300
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
301
+ "Content-Type": content_type,
302
+ "Accept": "application/json, text/html, */*",
303
+ },
304
+ method="POST",
305
+ )
306
+
307
+ try:
308
+ response = urllib.request.urlopen(req, timeout=timeout, context=ctx)
309
+ result["http_code"] = response.getcode()
310
+ body = response.read().decode("utf-8", errors="replace")
311
+ result["response"] = body[:500] if body else ""
312
+
313
+ # Analyze response
314
+ body_lower = body.lower()
315
+
316
+ # Check for success indicators
317
+ for indicator in self.SUCCESS_INDICATORS:
318
+ if indicator in body_lower:
319
+ result["success"] = True
320
+ result["reason"] = f"Found success indicator: '{indicator}'"
321
+ return result
322
+
323
+ # HTTP 200/201 without explicit failure = possible success
324
+ if result["http_code"] in (200, 201):
325
+ # Check for failure indicators
326
+ for indicator in self.FAILURE_INDICATORS:
327
+ if indicator in body_lower:
328
+ result["success"] = False
329
+ result["reason"] = f"Found failure indicator: '{indicator}'"
330
+ return result
331
+
332
+ # No failure indicators, consider it possible success
333
+ result["success"] = True
334
+ result["reason"] = (
335
+ f"HTTP {result['http_code']} with no failure indicators"
336
+ )
337
+ return result
338
+
339
+ # Other status codes
340
+ result["reason"] = f"HTTP {result['http_code']} - unclear result"
341
+ return result
342
+
343
+ except urllib.error.HTTPError as e:
344
+ result["http_code"] = e.code
345
+ try:
346
+ body = e.read().decode("utf-8", errors="replace")
347
+ result["response"] = body[:500] if body else ""
348
+ except Exception:
349
+ result["response"] = ""
350
+
351
+ # 401/403 = auth failed
352
+ if e.code in (401, 403):
353
+ result["reason"] = f"HTTP {e.code} - Authentication failed"
354
+ else:
355
+ result["reason"] = f"HTTP {e.code} - Request failed"
356
+ return result
357
+
358
+ except urllib.error.URLError as e:
359
+ result["reason"] = f"Connection error: {e.reason}"
360
+ return result
361
+
362
+ except Exception as e:
363
+ result["reason"] = f"Error: {type(e).__name__}: {e}"
364
+ return result
365
+
366
+ def _write_log(
367
+ self,
368
+ log_path: str,
369
+ target: str,
370
+ username: str,
371
+ result: Dict[str, Any] = None,
372
+ error: str = None,
373
+ ) -> None:
374
+ """Write test results to log file."""
375
+ if not log_path:
376
+ return
377
+
378
+ try:
379
+ with open(log_path, "w", encoding="utf-8", errors="replace") as fh:
380
+ fh.write("=== Plugin: Web Login Test ===\n")
381
+ fh.write(f"Target: {target}\n")
382
+ fh.write(f"Username: {username}\n")
383
+ fh.write(
384
+ f"Started: {time.strftime('%Y-%m-%d %H:%M:%S UTC', time.gmtime())}\n"
385
+ )
386
+ fh.write("=" * 60 + "\n\n")
387
+
388
+ if error:
389
+ fh.write(f"ERROR: {error}\n")
390
+ fh.write("\n=== JSON_RESULT ===\n")
391
+ fh.write(json.dumps({"error": error}, indent=2))
392
+ fh.write("\n=== END_JSON_RESULT ===\n")
393
+ return
394
+
395
+ if result:
396
+ if result.get("success"):
397
+ fh.write("[+] LOGIN SUCCESS\n")
398
+ else:
399
+ fh.write("[-] LOGIN FAILED\n")
400
+
401
+ fh.write(f"\nHTTP Code: {result.get('http_code', 'N/A')}\n")
402
+ fh.write(f"Reason: {result.get('reason', 'Unknown')}\n")
403
+
404
+ if result.get("response"):
405
+ fh.write(
406
+ f"\nResponse (truncated):\n{result['response'][:200]}\n"
407
+ )
408
+
409
+ fh.write("\n=== JSON_RESULT ===\n")
410
+ fh.write(json.dumps(result, indent=2))
411
+ fh.write("\n=== END_JSON_RESULT ===\n")
412
+
413
+ except Exception:
414
+ pass
415
+
416
+
417
+ plugin = WebLoginTestPlugin()
souleyez/plugins/whois.py CHANGED
@@ -37,56 +37,80 @@ HELP = {
37
37
  ["-p <port>", "Connect to specific port (default: 43)"],
38
38
  ],
39
39
  "presets": [
40
- {"name": "Standard Lookup", "args": [], "desc": "Basic WHOIS query for domain information"},
40
+ {
41
+ "name": "Standard Lookup",
42
+ "args": [],
43
+ "desc": "Basic WHOIS query for domain information",
44
+ },
41
45
  ],
42
46
  "help_sections": [
43
47
  {
44
48
  "title": "What is WHOIS?",
45
49
  "color": "cyan",
46
50
  "content": [
47
- {"title": "Overview", "desc": "WHOIS queries domain registration databases to retrieve registrant information, registrar details, creation/expiration dates, nameservers, and technical contacts."},
48
- {"title": "Use Cases", "desc": "Essential for reconnaissance to understand domain ownership and gather contact information.", "tips": [
49
- "Identify domain owner and organization",
50
- "Find registration and expiration dates",
51
- "Discover nameservers and DNS configuration",
52
- "Gather email addresses and phone numbers for social engineering",
53
- "Identify related domains by registrant"
54
- ]}
55
- ]
51
+ {
52
+ "title": "Overview",
53
+ "desc": "WHOIS queries domain registration databases to retrieve registrant information, registrar details, creation/expiration dates, nameservers, and technical contacts.",
54
+ },
55
+ {
56
+ "title": "Use Cases",
57
+ "desc": "Essential for reconnaissance to understand domain ownership and gather contact information.",
58
+ "tips": [
59
+ "Identify domain owner and organization",
60
+ "Find registration and expiration dates",
61
+ "Discover nameservers and DNS configuration",
62
+ "Gather email addresses and phone numbers for social engineering",
63
+ "Identify related domains by registrant",
64
+ ],
65
+ },
66
+ ],
56
67
  },
57
68
  {
58
69
  "title": "How to Use",
59
70
  "color": "green",
60
71
  "content": [
61
- {"title": "Basic Workflow", "desc": "1. Enter target domain name\n 2. Review registration information\n 3. Note nameservers for DNS enumeration\n 4. Save contact information for later use"},
62
- {"title": "What to Look For", "desc": "Key information in WHOIS results", "tips": [
63
- "Registrant name and organization",
64
- "Creation/expiration dates (helps identify abandoned domains)",
65
- "Nameserver configuration",
66
- "Technical/admin contact emails",
67
- "Registrar information"
68
- ]}
69
- ]
72
+ {
73
+ "title": "Basic Workflow",
74
+ "desc": "1. Enter target domain name\n 2. Review registration information\n 3. Note nameservers for DNS enumeration\n 4. Save contact information for later use",
75
+ },
76
+ {
77
+ "title": "What to Look For",
78
+ "desc": "Key information in WHOIS results",
79
+ "tips": [
80
+ "Registrant name and organization",
81
+ "Creation/expiration dates (helps identify abandoned domains)",
82
+ "Nameserver configuration",
83
+ "Technical/admin contact emails",
84
+ "Registrar information",
85
+ ],
86
+ },
87
+ ],
70
88
  },
71
89
  {
72
90
  "title": "Tips & Best Practices",
73
91
  "color": "yellow",
74
92
  "content": [
75
- ("Best Practices:", [
76
- "Query early in reconnaissance phase",
77
- "Cross-reference with theHarvester results",
78
- "Note privacy-protected domains (limited info)",
79
- "Check related TLDs (.com, .net, .org, etc.)",
80
- "Document contact information for reporting"
81
- ]),
82
- ("Common Issues:", [
83
- "Privacy protection: Many domains hide owner details",
84
- "Rate limiting: WHOIS servers may throttle queries",
85
- "Different formats: Each TLD registry has different output format"
86
- ])
87
- ]
88
- }
89
- ]
93
+ (
94
+ "Best Practices:",
95
+ [
96
+ "Query early in reconnaissance phase",
97
+ "Cross-reference with theHarvester results",
98
+ "Note privacy-protected domains (limited info)",
99
+ "Check related TLDs (.com, .net, .org, etc.)",
100
+ "Document contact information for reporting",
101
+ ],
102
+ ),
103
+ (
104
+ "Common Issues:",
105
+ [
106
+ "Privacy protection: Many domains hide owner details",
107
+ "Rate limiting: WHOIS servers may throttle queries",
108
+ "Different formats: Each TLD registry has different output format",
109
+ ],
110
+ ),
111
+ ],
112
+ },
113
+ ],
90
114
  }
91
115
 
92
116
 
@@ -96,35 +120,35 @@ class WhoisPlugin(PluginBase):
96
120
  category = "reconnaissance"
97
121
  HELP = HELP
98
122
 
99
-
100
- def build_command(self, target: str, args: List[str] = None, label: str = "", log_path: str = None):
123
+ def build_command(
124
+ self, target: str, args: List[str] = None, label: str = "", log_path: str = None
125
+ ):
101
126
  """Build command for background execution with PID tracking."""
102
127
  if not target:
103
128
  if log_path:
104
- with open(log_path, 'w') as f:
129
+ with open(log_path, "w") as f:
105
130
  f.write("ERROR: Target domain is required\n")
106
131
  return None
107
-
132
+
108
133
  # Validate target
109
134
  try:
110
135
  target = validate_target(target)
111
136
  except ValidationError as e:
112
137
  if log_path:
113
- with open(log_path, 'w') as f:
138
+ with open(log_path, "w") as f:
114
139
  f.write(f"ERROR: Invalid target: {e}\n")
115
140
  return None
116
-
141
+
117
142
  args = args or []
118
-
143
+
119
144
  # whois syntax: whois target [args]
120
145
  cmd = ["whois", target] + args
121
-
122
- return {
123
- 'cmd': cmd,
124
- 'timeout': 300
125
- }
126
146
 
127
- def run(self, target: str, args: List[str] = None, label: str = "", log_path: str = None) -> int:
147
+ return {"cmd": cmd, "timeout": 300}
148
+
149
+ def run(
150
+ self, target: str, args: List[str] = None, label: str = "", log_path: str = None
151
+ ) -> int:
128
152
  """
129
153
  Execute WHOIS lookup and write output to log_path.
130
154
  """
@@ -136,7 +160,7 @@ class WhoisPlugin(PluginBase):
136
160
  target = validate_target(target)
137
161
  except ValidationError as e:
138
162
  if log_path:
139
- with open(log_path, 'w') as f:
163
+ with open(log_path, "w") as f:
140
164
  f.write(f"ERROR: Invalid target: {e}\n")
141
165
  return 1
142
166
  raise ValueError(f"Invalid target: {e}")
@@ -147,21 +171,16 @@ class WhoisPlugin(PluginBase):
147
171
  cmd = ["whois", target] + args
148
172
 
149
173
  if log_path:
150
- with open(log_path, 'w') as f:
174
+ with open(log_path, "w") as f:
151
175
  f.write(f"# WHOIS Lookup for {target}\n")
152
176
  f.write(f"# Command: {' '.join(cmd)}\n")
153
177
  f.write(f"# Started: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n")
154
178
 
155
179
  try:
156
- result = subprocess.run(
157
- cmd,
158
- capture_output=True,
159
- text=True,
160
- timeout=60
161
- )
180
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
162
181
 
163
182
  if log_path:
164
- with open(log_path, 'a') as f:
183
+ with open(log_path, "a") as f:
165
184
  f.write(result.stdout)
166
185
  if result.stderr:
167
186
  f.write(f"\n\n# Errors:\n{result.stderr}\n")
@@ -170,12 +189,12 @@ class WhoisPlugin(PluginBase):
170
189
 
171
190
  except subprocess.TimeoutExpired:
172
191
  if log_path:
173
- with open(log_path, 'a') as f:
192
+ with open(log_path, "a") as f:
174
193
  f.write("\n\n# ERROR: Command timed out after 60 seconds\n")
175
194
  return 124
176
195
  except Exception as e:
177
196
  if log_path:
178
- with open(log_path, 'a') as f:
197
+ with open(log_path, "a") as f:
179
198
  f.write(f"\n\n# ERROR: {str(e)}\n")
180
199
  return 1
181
200