daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

wpscan.md (16711B)


      1 ---
      2 title: "WPScan"
      3 description: "WPScan WordPress enumeration: plugins/themes/users, vuln API tokens and password attacks."
      4 category: enumeration
      5 tags: [enumeration, web, wordpress]
      6 tools: [WPScan]
      7 difficulty: intermediate
      8 updated: "2026-08-09"
      9 source: "vault:Enumeration/WPScan.md"
     10 ---
     11 
     12 # WPScan
     13 
     14 WordPress security scanner. Enumerates core version, plugins, themes, users and other components, and (with an API token) reports known vulnerabilities. Pre-installed on Kali, Parrot, BlackArch, etc.
     15 
     16 ## Basic Scanning
     17 
     18 Initial WordPress scan with default enumeration.
     19 
     20 ```bash
     21 wpscan --url https://target.com
     22 wpscan --url https://target.com --api-token YOUR_TOKEN
     23 wpscan --url https://target.com --api-token YOUR_TOKEN --no-update
     24 ```
     25 
     26 **Key options:**
     27 - `--url` (required): Target WordPress URL
     28 - `--api-token TOKEN`: WPScan API token for vulnerability data (25 free requests/day)
     29 - `--no-update`: Skip database update check at scan start
     30 - `--force`: Ignore robots.txt disallow rules
     31 - `--verbose` / `-v`: Debug output
     32 - `--no-banner`: Suppress banner
     33 - `--random-user-agent` / `--rua`: Randomize User-Agent
     34 - `--disable-tls-checks`: Ignore TLS/SSL errors (lab/testing only)
     35 
     36 ```bash
     37 # Basic scan with API token
     38 wpscan --url https://example.com --api-token abcd1234efgh5678
     39 
     40 # Scan without updating database (faster)
     41 wpscan --url https://example.com --api-token abcd1234efgh5678 --no-update
     42 
     43 # Force scan even if robots.txt disallows
     44 wpscan --url https://example.com --force
     45 
     46 # Use environment variable for API token
     47 export WPSCAN_API_TOKEN=abcd1234efgh5678
     48 wpscan --url https://example.com
     49 ```
     50 
     51 Default enumeration runs: vulnerable plugins (`vp`), vulnerable themes (`vt`), timthumbs (`tt`), config backups (`cb`), database exports (`dbe`), users (`u1-10`), media (`m1-10`). Vulnerabilities are only shown if an API token is provided. Output colours: green = low, yellow = medium, red = high/critical.
     52 
     53 > **Note — Common errors.** `does not seem to be running WordPress` → try `--random-user-agent` or `--disable-tls-checks`. `403`/timeout on DB update → firewall blocking `data.wpscan.org`. No vulns shown → token missing or daily limit (25) exceeded.
     54 
     55 **OPSEC:** default User-Agent `WPScan vX.X.X (...)` is logged; default scans generate 50-200+ HTTP requests (many 404s); rapid `wp-content/plugins/*` enumeration may trip IDS/IPS.
     56 
     57 ## Plugin Enumeration
     58 
     59 Enumerate installed plugins (popular, all, or vulnerable only).
     60 
     61 ```bash
     62 wpscan --url https://target.com -e vp    # vulnerable plugins only (default)
     63 wpscan --url https://target.com -e p     # popular plugins (~6000 in DB)
     64 wpscan --url https://target.com -e ap    # ALL plugins (aggressive, slow)
     65 wpscan --url https://target.com -e vp,ap --plugins-detection mixed
     66 ```
     67 
     68 **Options:**
     69 - `--plugins-detection MODE`: passive (default), mixed, aggressive
     70 - `--plugins-version-detection MODE`: mixed (default), passive, aggressive
     71 - `--plugins-list FILE`: Custom plugin list to check
     72 - `--exclude-content-based 'REGEX'`: Filter false positives (use when 100+ plugins detected)
     73 
     74 ```bash
     75 # Enumerate vulnerable plugins only (default)
     76 wpscan --url https://example.com -e vp --api-token TOKEN
     77 
     78 # Enumerate all plugins aggressively (noisy)
     79 wpscan --url https://example.com -e ap --plugins-detection aggressive --plugins-version-detection aggressive
     80 
     81 # Combine with other enumerations
     82 wpscan --url https://example.com -e vp,u1-20 --api-token TOKEN
     83 
     84 # Filter false positives when 100+ plugins detected
     85 wpscan --url https://example.com -e ap --exclude-content-based 'Error 404'
     86 
     87 # Stealthy plugin enumeration
     88 wpscan --url https://example.com -e p --plugins-detection passive --random-user-agent --throttle 2000
     89 ```
     90 
     91 Detection modes: **passive** checks `readme.txt`/`changelog.txt` (~1-3 req/plugin, lowest noise); **mixed** adds Last-Modified header checks (~2-5 req/plugin); **aggressive** checks multiple version files (10+ req/plugin, many 404s). A full `-e ap` scan can generate tens of thousands of requests; WAFs may block aggressive enumeration ("no plugins found").
     92 
     93 ## Theme Enumeration
     94 
     95 ```bash
     96 wpscan --url https://target.com -e vt    # vulnerable themes only (default)
     97 wpscan --url https://target.com -e t     # popular themes (~2000 in DB)
     98 wpscan --url https://target.com -e at     # ALL themes (aggressive)
     99 wpscan --url https://target.com -e vt,at --themes-detection mixed
    100 ```
    101 
    102 **Options:** `--themes-detection MODE` (passive default), `--themes-version-detection MODE`, `--themes-list FILE`.
    103 
    104 ```bash
    105 # Popular themes with mixed detection
    106 wpscan --url https://example.com -e t --themes-detection mixed
    107 
    108 # Stealthy theme enumeration
    109 wpscan --url https://example.com -e t --themes-detection passive --random-user-agent
    110 
    111 # Combine theme and plugin enumeration
    112 wpscan --url https://example.com -e vt,vp,u --api-token TOKEN
    113 ```
    114 
    115 The active theme is usually detected automatically in a basic scan; inactive themes require `-e t`/`-e at`. Enumeration pattern: `wp-content/themes/THEME/style.css`, `readme.txt`.
    116 
    117 ## User Enumeration
    118 
    119 ```bash
    120 wpscan --url https://target.com -e u          # default range 1-10
    121 wpscan --url https://target.com -e u1-100
    122 wpscan --url https://target.com -e u1-5,10,15-20
    123 wpscan --url https://target.com -e u --users-detection mixed
    124 ```
    125 
    126 **Options:** `--users-detection MODE` (passive default), `--users-list FILE`.
    127 
    128 ```bash
    129 # Enumerate specific users
    130 wpscan --url https://example.com -e u1,2,5,10
    131 
    132 # Stealthy user enumeration with throttling
    133 wpscan --url https://example.com -e u1-20 --users-detection passive --throttle 2000
    134 ```
    135 
    136 Output shows username, display name, user ID. User ID 1 is often the site administrator; display names may leak real names (OSINT value).
    137 
    138 **OPSEC:** passive mode queries `/wp-json/wp/v2/users` (REST API, single request); mixed adds `/?author=ID` archive enumeration; aggressive adds login error messages. WordPress ≥ 4.7.1 may restrict the REST API via plugins.
    139 
    140 ## Other Enumerations (timthumbs, config backups, DB exports, media)
    141 
    142 ```bash
    143 wpscan --url https://target.com -e tt        # timthumb files (vulnerable image resizer)
    144 wpscan --url https://target.com -e cb        # config backups (wp-config.php.bak, ~, .old)
    145 wpscan --url https://target.com -e dbe       # database exports (.sql in web root)
    146 wpscan --url https://target.com -e m1-15     # media files (requires Plain permalinks)
    147 wpscan --url https://target.com -e tt,cb,dbe,m1-10
    148 ```
    149 
    150 **Options:** `--timthumbs-detection`, `--config-backups-detection`, `--db-exports-detection`, `--medias-detection` (each passive/mixed/aggressive), plus matching `--*-list FILE` overrides.
    151 
    152 ```bash
    153 # Config backups (information disclosure)
    154 wpscan --url https://example.com -e cb --config-backups-detection aggressive
    155 
    156 # Database exports (critical if found)
    157 wpscan --url https://example.com -e dbe --db-exports-detection aggressive
    158 
    159 # Stealthy combined enumeration
    160 wpscan --url https://example.com -e tt,cb,dbe --throttle 1500
    161 ```
    162 
    163 - **Timthumbs:** old image resizer with known RCE (high severity if found; mostly pre-2014).
    164 - **Config backups:** `wp-config.php.bak`, `~`, `.old` — contain DB creds and salt keys (critical if accessible).
    165 - **Database exports:** `.sql`, `.sql.gz`, `.sql.bak` — full site compromise if accessible.
    166 - **Media:** uploaded files via `/?attachment_id=N` (needs Plain permalinks).
    167 
    168 ## Vulnerability Detection
    169 
    170 Identify known vulnerabilities in core, plugins, and themes. Requires a WPScan API token.
    171 
    172 ```bash
    173 wpscan --url https://target.com --api-token TOKEN
    174 wpscan --url https://target.com --api-token TOKEN -e vp,vt
    175 wpscan --url https://target.com --api-token TOKEN -e ap,at
    176 export WPSCAN_API_TOKEN=TOKEN && wpscan --url https://target.com
    177 ```
    178 
    179 **Options:** `--api-token TOKEN` (25 req/day free, 250/day paid), `--wp-version-all` (check all known core versions).
    180 
    181 ```bash
    182 # Vulnerability scan with all plugins/themes and users
    183 wpscan --url https://example.com --api-token TOKEN -e ap,at,u
    184 
    185 # Check specific WordPress version vulnerabilities
    186 wpscan --url https://example.com --api-token TOKEN --wp-version-all
    187 ```
    188 
    189 Each vulnerability includes CVE/reference ID, description, affected/`Fixed in:` versions and a link. Vulnerability lookups are DB queries against WPScan's servers — **no extra HTTP requests to the target** (no OPSEC impact on the target). Token registration: register at wpscan.com, confirm email, retrieve the token from your profile.
    190 
    191 ## Password Attacks
    192 
    193 Brute-force WordPress user passwords (authorized testing only).
    194 
    195 ```bash
    196 wpscan --url https://target.com -U userlist.txt -P passwords.txt
    197 wpscan --url https://target.com -U admin -P rockyou.txt --password-attack xmlrpc
    198 wpscan --url https://target.com -P passwords.txt --password-attack wp-login
    199 wpscan --url https://target.com -U admin,editor -P passwords.txt --password-attack xmlrpc-multicall
    200 ```
    201 
    202 **Options:**
    203 - `-U LIST`: Username(s) — single, comma-separated, or file path (auto-enumerates u1-10 if omitted)
    204 - `-P FILE`: Password wordlist (required)
    205 - `--password-attack MODE`: `wp-login` (default), `xmlrpc`, `xmlrpc-multicall`
    206 - `--multicall-max-passwords N`: Max passwords per xmlrpc multicall (default 500)
    207 - `--login-uri PATH`: Custom login URI (default `/wp-login.php`)
    208 
    209 ```bash
    210 # Brute-force single user with wordlist
    211 wpscan --url https://example.com -U admin -P /usr/share/wordlists/rockyou.txt
    212 
    213 # Force xmlrpc-multicall (fastest, WP <4.4 only)
    214 wpscan --url https://example.com -U admin -P passwords.txt --password-attack xmlrpc-multicall --multicall-max-passwords 1000
    215 
    216 # Force wp-login mode (always works, slower)
    217 wpscan --url https://example.com -U admin -P passwords.txt --password-attack wp-login
    218 
    219 # Stealthy password attack
    220 wpscan --url https://example.com -U admin -P short-list.txt --throttle 5000 --random-user-agent
    221 ```
    222 
    223 Attack modes by speed: **xmlrpc-multicall** (500 passwords per POST, WP <4.4 only, removed in 4.4+) → **xmlrpc** (1/POST to `/xmlrpc.php`, often disabled) → **wp-login** (1/POST to `/wp-login.php`, always available). Valid creds print as `[+] Valid Credentials Found`.
    224 
    225 > **Warning — OPSEC.** Failed logins are recorded in the WP dashboard and server auth logs. WAF/security plugins (Wordfence, iThemes) block xmlrpc by default; lockout plugins block after N failures. High-volume attacks leave large log evidence.
    226 
    227 ## Stealth Scanning
    228 
    229 Minimize detection footprint during recon.
    230 
    231 ```bash
    232 wpscan --url https://target.com --stealthy
    233 wpscan --url https://target.com --random-user-agent --detection-mode passive --plugins-version-detection passive
    234 wpscan --url https://target.com --stealthy --throttle 2000 --max-threads 1
    235 wpscan --url https://target.com --stealthy -e p,u1-10 --throttle 3000 --no-banner
    236 ```
    237 
    238 `--stealthy` is an alias for `--random-user-agent --detection-mode passive --plugins-version-detection passive`.
    239 
    240 **Options:** `--user-agent VALUE`, `--user-agents-list FILE`, `--detection-mode passive`, `--throttle MILLISECONDS` (auto-sets `--max-threads 1`), `--max-threads 1`, `--no-banner`.
    241 
    242 ```bash
    243 # Maximum stealth configuration
    244 wpscan --url https://example.com --random-user-agent --detection-mode passive --plugins-detection passive --plugins-version-detection passive --themes-detection passive --throttle 5000 --max-threads 1 --no-banner
    245 
    246 # Stealthy over Tor
    247 wpscan --url https://example.com --stealthy --proxy socks5h://127.0.0.1:9050 --throttle 2000
    248 ```
    249 
    250 Throttle guide: `--throttle 1000` ≈ 60 req/min, `--throttle 5000` ≈ 12 req/min. Stealthy mode drops a scan from 100-200 to ~20-50 requests but passive detection may fail to identify component versions. All requests are still logged even with stealth.
    251 
    252 ## Authentication, Cookies & Headers
    253 
    254 Scan authenticated areas or pass custom HTTP headers/cookies.
    255 
    256 ```bash
    257 wpscan --url https://target.com --http-auth username:password
    258 wpscan --url https://target.com --cookie-string "wordpress_logged_in=value; wp_session=value"
    259 wpscan --url https://target.com --cookie-jar /path/to/cookies.txt
    260 wpscan --url https://target.com --headers "Authorization: Bearer TOKEN; X-Custom: value"
    261 ```
    262 
    263 **Options:** `--http-auth username:password` (Basic/Digest), `--cookie-string "n=v; n2=v2"`, `--cookie-jar FILE` (Netscape/Mozilla format), `--headers "H1: v1; H2: v2"` (semicolon-separated).
    264 
    265 ```bash
    266 # HTTP Basic auth with special characters (single-quote to prevent shell expansion)
    267 wpscan --url https://example.com --http-auth 'user:p@$$w0rd!'
    268 
    269 # Scan with WordPress session cookies (logged-in user)
    270 wpscan --url https://example.com --cookie-string "wordpress_logged_in_abc123=admin%7C123456%7Chash"
    271 
    272 # Authenticated enumeration
    273 wpscan --url https://example.com --cookie-string "wordpress_logged_in=value" -e ap,at,u1-100
    274 ```
    275 
    276 > **Note —** HTTP Basic auth bypasses web-server restrictions, not WordPress auth. Use a low-privilege account for OPSEC. Cookie strings use `;` separators (not commas). `--http-auth` credentials are base64-encoded and visible in logs.
    277 
    278 ## Proxy Configuration
    279 
    280 ```bash
    281 wpscan --url https://target.com --proxy http://proxy.example.com:8080
    282 wpscan --url https://target.com --proxy socks5://127.0.0.1:9050
    283 wpscan --url https://target.com --proxy socks5h://127.0.0.1:9050
    284 wpscan --url https://target.com --proxy http://user:pass@proxy.example.com:8080
    285 ```
    286 
    287 Supported protocols: `http://`, `socks4://`, `socks5://`, `socks5h://`. Use **`socks5h://`** for remote DNS resolution (prevents DNS leaks — recommended for Tor). Adjust `--request-timeout SECONDS` (default 60) and `--connect-timeout SECONDS` (default 30) for slow proxies.
    288 
    289 ```bash
    290 # HTTP proxy (Burp/ZAP interception)
    291 wpscan --url https://example.com --proxy http://127.0.0.1:8080
    292 
    293 # SOCKS5 with remote DNS (Tor), increased timeout
    294 wpscan --url https://example.com --proxy socks5h://127.0.0.1:9050 --request-timeout 120 --connect-timeout 60
    295 ```
    296 
    297 > **Note — Common errors.** `407 Proxy Authentication Required` → add `http://user:pass@proxy:port`. DNS leak with Tor → use `socks5h://` not `socks5://`. SSL errors through an intercepting proxy → `--disable-tls-checks` (trust implications). Ensure the proxy allows HTTPS to wpscan.com:443 for API lookups.
    298 
    299 ## Custom WordPress Paths
    300 
    301 Scan installs with non-standard directory structure.
    302 
    303 ```bash
    304 wpscan --url https://target.com --wp-content-dir custom-content
    305 wpscan --url https://target.com --wp-plugins-dir custom-content/extensions
    306 wpscan --url https://target.com --wp-content-dir wp-core/content --wp-plugins-dir wp-core/content/plugins
    307 ```
    308 
    309 `--wp-content-dir DIR` and `--wp-plugins-dir DIR` are relative to the WordPress root. Discover the real paths from page source, e.g. `<link rel='stylesheet' href='/custom-wp/content/themes/twentytwentyone/style.css'>` → `--wp-content-dir custom-wp/content --wp-plugins-dir custom-wp/content/plugins`. Set in wp-config.php via the `WP_CONTENT_DIR` / `WP_PLUGIN_DIR` constants.
    310 
    311 ## Output Formats
    312 
    313 ```bash
    314 wpscan --url https://target.com -o report.txt
    315 wpscan --url https://target.com -f json -o report.json
    316 wpscan --url https://target.com -f cli-no-colour -o report.txt
    317 wpscan --url https://target.com --format json --output results.json
    318 ```
    319 
    320 **Formats:** `cli` (colored, default), `cli-no-colour`/`cli-no-color` (plain text), `json` (machine-readable).
    321 
    322 ```bash
    323 # JSON output + parse with jq (WordPress version)
    324 wpscan --url https://example.com -f json -o report.json && jq '.version.number' report.json
    325 
    326 # JSON output + parse vulnerabilities
    327 wpscan --url https://example.com --api-token TOKEN -f json -o report.json && jq '.plugins[].vulnerabilities' report.json
    328 ```
    329 
    330 JSON top-level keys (v3.8.x): `target_url`, `version`, `interesting_findings`, `plugins`, `themes`, `users`, `vulnerabilities`. Each plugin/theme entry carries `slug`, `location`, `version`, `vulnerabilities[]`.
    331 
    332 ## Installation
    333 
    334 ```bash
    335 # Kali / Debian / Ubuntu (apt)
    336 sudo apt update && sudo apt install wpscan
    337 wpscan --version
    338 
    339 # Ruby gem (Debian/Ubuntu) — needs Ruby 3.x+
    340 sudo apt install ruby-full ruby-dev libcurl4-openssl-dev build-essential
    341 sudo gem install wpscan
    342 
    343 # Fix nokogiri dependency error (common on Debian/Ubuntu)
    344 sudo apt install ruby-dev build-essential libxml2-dev libxslt1-dev zlib1g-dev
    345 sudo gem install nokogiri --platform=ruby
    346 sudo gem install wpscan
    347 
    348 # Docker (no local Ruby needed)
    349 docker pull wpscanteam/wpscan
    350 docker run -it --rm wpscanteam/wpscan --url https://example.com --api-token TOKEN
    351 
    352 # Docker with output file (mount volume)
    353 docker run -it --rm -v /tmp:/output wpscanteam/wpscan --url https://example.com -o /output/report.txt
    354 
    355 # Git clone (development version)
    356 git clone https://github.com/wpscanteam/wpscan.git && cd wpscan
    357 bundle install
    358 ./bin/wpscan --url https://example.com
    359 ```
    360 
    361 ## Sources
    362 
    363 - https://github.com/wpscanteam/wpscan
    364 - https://wpscan.com/docs/
    365 - https://wpscan.com/api
    366 - https://www.kali.org/tools/wpscan/