SuperAPI AI Directory

hunt-wordpress

Frontend & websites

View repository

Updated 10-16 03:03

About this skill

WordPress Security Assessment

Map WordPress core, REST, XML-RPC, plugins, themes, authentication boundaries, and adjacent installations before selecting a vulnerability-specific test. WordPress presence, a public route, or a version match is not a finding by itself.

When to Use

  • HTML, headers, assets, cookies, or routes identify WordPress.
  • /wp-json/, /wp-login.php, /xmlrpc.php, or /wp-content/ is reachable.
  • JavaScript or source code references a WordPress backend.
  • A staging or subdirectory installation may differ from the main site.

Prerequisites

  • Explicit authorization and current target boundaries.
  • curl and jq; wpscan is optional.
  • Approved test identities for role or authorization checks.
  • A controlled callback service only when blind SSRF testing is authorized.
  • Explicit approval immediately before registration, upload, password, plugin, or other state-changing tests.

How to Run

Begin with a bounded, read-only map:

TARGET="https://www.example.test"
OUTPUT_DIR="${OUTPUT_DIR:-./output/wordpress}"
mkdir -p "$OUTPUT_DIR"

for path in \
  / \
  /wp-json/ \
  /wp-login.php \
  /xmlrpc.php \
  /readme.html \
  /author-sitemap.xml; do
  curl -sS --max-time 10 \
    -o /dev/null \
    -w '%{http_code} %{content_type} %{size_download} %{url_effective}\n' \
    "$TARGET$path"
  sleep 1
done

Procedure

1. Confirm WordPress

Use multiple signals:

curl -sS --max-time 10 "$TARGET/" \
  | grep -Eio 'wp-content|wp-includes|wp-json|wordpress' \
  | sort -u

curl -sS --max-time 10 "$TARGET/wp-json/" \
  -o "$OUTPUT_DIR/rest-index.json"

jq -r '.namespaces[]? // empty' "$OUTPUT_DIR/rest-index.json" \
  | sort -u \
  > "$OUTPUT_DIR/rest-namespaces.txt"

A generic 200 response is insufficient. Compare suspicious paths with a random nonexistent path to detect catch-all routing.

2. Map Core, Theme, and Plugin Assets

curl -sS --max-time 10 "$TARGET/" \
  | grep -Eo "wp-content/(plugins|themes)/[^/?\"']+" \
  | sort -u \
  > "$OUTPUT_DIR/components.txt"

Confirm a component with at least two signals when practical: an asset path, REST namespace, readme or changelog, HTML marker, or versioned file. Match CVEs only after establishing the exact affected version and prerequisite.

Use wordpress-plugin-hunt for plugin discovery and version validation.

3. Map REST Data and Authorization

for path in \
  /wp-json/ \
  /wp-json/wp/v2/types \
  /wp-json/wp/v2/posts?per_page=2 \
  /wp-json/wp/v2/pages?per_page=2 \
  /wp-json/wp/v2/users?per_page=2; do
  curl -sS --max-time 10 \
    -D "$OUTPUT_DIR/headers.tmp" \
    -o "$OUTPUT_DIR/body.tmp" \
    "$TARGET$path"
  printf '%s %s\n' "$path" "$(wc -c < "$OUTPUT_DIR/body.tmp")"
  sleep 1
done

Classify the response before assigning impact:

  • published posts and pages are usually public by design;
  • usernames may increase phishing or authentication risk but are not account takeover;
  • email addresses, roles, drafts, settings, form entries, orders, and logs need separate access-control review;
  • a plugin namespace may exist while every operation remains protected.

For authorization claims, compare anonymous, user A, user B, and an approved privileged identity against the same synthetic object.

4. Validate CORS in a Browser

curl -sS --max-time 10 \
  -D "$OUTPUT_DIR/cors-headers.txt" \
  -o "$OUTPUT_DIR/cors-body.txt" \
  -H 'Origin: https://attacker.example' \
  "$TARGET/wp-json/wp/v2/users?per_page=2"

Header reflection is only a lead. Credentialed CORS impact requires:

  1. an untrusted origin accepted by the response;
  2. Access-Control-Allow-Credentials: true when cookies are required;
  3. an approved authenticated browser session;
  4. browser JavaScript that can read non-public data;
  5. an anonymous or public-data negative control.

Use cors-credential-wordpress for the complete browser workflow.

5. Classify XML-RPC

curl -sS --max-time 15 \
  -X POST "$TARGET/xmlrpc.php" \
  -H 'Content-Type: text/xml' \
  --data-binary \
  '<methodCall><methodName>system.listMethods</methodName></methodCall>' \
  -o "$OUTPUT_DIR/xmlrpc-methods.xml"

grep -Eo '<string>[^<]+</string>' "$OUTPUT_DIR/xmlrpc-methods.xml" \
  | sed -E 's#</?string>##g' \
  | sort -u

Do not follow redirects during protocol classification. A valid methodResponse proves XML-RPC behavior; a status code alone does not. Credential testing, multicall amplification, uploads, and SSRF bypasses require their own authorization and safety limits. Use xmlrpc-exploitation only when the relevant method and prerequisites have been confirmed.

6. Check Staging and Secondary Installations

Certificate transparency, archives, and asset paths may reveal staging hosts or subdirectory installations. Compare:

  • WordPress and plugin versions;
  • authentication and WAF behavior;
  • REST and XML-RPC exposure;
  • debug configuration and source files;
  • shared cookies, credentials, storage, and deployment paths.

A weaker staging control matters only when the environment is in scope and its impact is demonstrated. Use staging-subdomain-hunt for a bounded comparison.

7. Check Source and Error Exposure

Probe only the paths justified by the observed stack. Validate content rather than status:

Candidate Required content
.git/HEAD Git ref such as ref: refs/heads/...
.env Configuration assignments, not generic HTML
debug.log or error_log Real application errors or sensitive runtime data
backup archive Correct file signature and meaningful contents
directory listing Directory index markers and actual entries

Use source-leak-hunt and error-log-mining; retain only the minimum sanitized sample needed to demonstrate exposure.

8. Build a Candidate Attack Path

Connect only verified prerequisites:

observed component
  -> exact version and configuration
  -> reachable vulnerable operation
  -> approved identity or synthetic object
  -> reproduced security impact

Registration, XML-RPC, an upload route, and an executable PHP configuration do not automatically form an RCE chain. Confirm the role capability, upload validation, storage path, and execution behavior independently.

Pitfalls

  • WordPress routes frequently sit behind CDN, cache, or catch-all behavior.
  • GET /xmlrpc.php returning 405 does not classify a valid POST method call.
  • A REST namespace does not prove that a plugin operation is unauthenticated.
  • Public author metadata is not automatically sensitive.
  • Plugin versions can be hidden, backported, or reported by stale assets.
  • Large logs, sitemaps, and REST collections can cause unnecessary data collection; request bounded samples.
  • Default credential attempts, password spraying, registration, uploads, and writes require explicit authorization and agreed lockout limits.

Verification

  • WordPress is confirmed from content, not only a status code.
  • Every component finding includes a second signal or explains why one is not available.
  • Every CVE association includes exact version and prerequisite evidence.
  • REST authorization uses approved identities and a negative control.
  • CORS impact is reproduced in a browser with non-public data.
  • XML-RPC behavior uses a protocol-valid response or controlled callback.
  • State-changing tests use synthetic records, preserve cleanup evidence, and remain within scope.