How to use WPScan to Find Security Vulnerability on WordPress Sites?

Millions of websites are powered by WordPress and holding the number one position, with 62% of the market share in the CMS world.

A recent web application vulnerability report by Acunetix shows that around 30% of WordPress sites found vulnerable.

There is plenty of online security scanner to scan your website. However, if you are looking for software to install and scan from your server, then WPScan is your friend. It is useful if your website is on a private network or Intranet where the Internet is not available. Or, want to test multiple sites at multiple times.

WPScan is free software, helps you to identify the security-related problems on your WordPress site. It does several things like:

and a lot more…

There is several ways to use WPScan.

Using on CentOS

The following are tested on CentOS 7.x.

yum update -y
yum -y install curl gpg gcc gcc-c++ make patch autoconf automake bison libffi-devel libtool patch readline-devel sqlite-devel zlib-devel openssl-devel && gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB && curl -sSL https://get.rvm.io | bash -s stable --ruby 
yum -y install rubygem-nokogiri 
gem install wpscan

It will take few seconds to install, and once done; you should see something like this.

Done installing documentation for ffi, get_process_mem, mini_portile2, nokogiri, concurrent-ruby, i18n, thread_safe, tzinfo, zeitwerk, activesupport, public_suffix, addressable, opt_parse_validator, ruby-progressbar, ethon, typhoeus, yajl-ruby, sys-proctable, cms_scanner, wpscan after 32 seconds 20 gems installed 

WPScan is installed and ready to use now. Execute wpscan and you should see it returns below.

[[email protected] ~]# wpscan One of the following options is required: url, update, help, hh, version  Please use --help/-h for the list of available options. [[email protected] ~]#

Here is the output of one of the site's test.

[[email protected] ~]# wpscan --url https://geekflaresg.com _______________________________________________________________          __          _______   _____          \ \        / /  __ \ / ____|           \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®            \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \             \  /\  /  | |     ____) | (__| (_| | | | |              \/  \/   |_|    |_____/ \___|\__,_|_| |_|           WordPress Security Scanner by the WPScan Team                          Version 3.7.6        Sponsored by Automattic - https://automattic.com/        @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart _______________________________________________________________  [+] URL: https://geekflaresg.com/ [+] Started: Wed Jan  8 21:14:16 2020  Interesting Finding(s):  [+] https://geekflaresg.com/  | Interesting Entries:  |  - Server: nginx  |  - X-Cache-Enabled: True  |  - Host-Header: 5d77dd967d63c3104bced1db0cace49c  |  - X-Proxy-Cache: MISS  | Found By: Headers (Passive Detection)  | Confidence: 100%  [+] https://geekflaresg.com/robots.txt  | Interesting Entries:  |  - /wp-admin/  |  - /wp-admin/admin-ajax.php  | Found By: Robots Txt (Aggressive Detection)  | Confidence: 100%  [+] https://geekflaresg.com/xmlrpc.php  | Found By: Direct Access (Aggressive Detection)  | Confidence: 100%  | References:  |  - http://codex.wordpress.org/XML-RPC_Pingback_API  |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner  |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos  |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login  |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access  [+] https://geekflaresg.com/readme.html  | Found By: Direct Access (Aggressive Detection)  | Confidence: 100%  [+] https://geekflaresg.com/wp-cron.php  | Found By: Direct Access (Aggressive Detection)  | Confidence: 60%  | References:  |  - https://www.iplocation.net/defend-wordpress-from-ddos  |  - https://github.com/wpscanteam/wpscan/issues/1299  [+] WordPress version 5.3.2 identified (Latest, released on 2019-12-18).  | Found By: Rss Generator (Passive Detection)  |  - https://geekflaresg.com/feed/, https://wordpress.org/?v=5.3.2  |  - https://geekflaresg.com/comments/feed/, https://wordpress.org/?v=5.3.2  [+] WordPress theme in use: twentyseventeen  | Location: https://geekflaresg.com/wp-content/themes/twentyseventeen/  | Last Updated: 2019-05-07T00:00:00.000Z  | Readme: https://geekflaresg.com/wp-content/themes/twentyseventeen/README.txt  | [!] The version is out of date, the latest version is 2.2  | Style URL: https://geekflaresg.com/wp-content/themes/twentyseventeen/style.css  | Style Name: Twenty Seventeen  | Style URI: https://wordpress.org/themes/twentyseventeen/  | Description: Twenty Seventeen brings your site to life with header video and immersive featured images. With a fo...  | Author: the WordPress team  | Author URI: https://wordpress.org/  |  | Found By: Urls In Homepage (Passive Detection)  | Confirmed By: Urls In 404 Page (Passive Detection)  |  | Version: 2.1 (80% confidence)  | Found By: Style (Passive Detection)  |  - https://geekflaresg.com/wp-content/themes/twentyseventeen/style.css, Match: 'Version: 2.1'  [+] Enumerating All Plugins (via Passive Methods)  [i] No plugins Found.  [+] Enumerating Config Backups (via Passive and Aggressive Methods)  Checking Config Backups - Time: 00:00:01 <===================================================================================================> (21 / 21) 100.00% Time: 00:00:01  [i] No Config Backups Found.  [!] No WPVulnDB API Token given, as a result vulnerability data has not been output. [!] You can get a free API token with 50 daily requests by registering at https://wpvulndb.com/users/sign_up  [+] Finished: Wed Jan  8 21:14:28 2020 [+] Requests Done: 51 [+] Cached Requests: 7 [+] Data Sent: 9.52 KB [+] Data Received: 369.97 KB [+] Memory used: 202.898 MB [+] Elapsed time: 00:00:12 [[email protected] ~]#  

Note: if you need vulnerability data in output, then you need to use their API.

If you are interested in testing specific metrics, then check out the help by executing wpscan with --help syntax.

[[email protected] ~]# wpscan --hh _______________________________________________________________          __          _______   _____          \ \        / /  __ \ / ____|           \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®            \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \             \  /\  /  | |     ____) | (__| (_| | | | |              \/  \/   |_|    |_____/ \___|\__,_|_| |_|           WordPress Security Scanner by the WPScan Team                          Version 3.7.6        Sponsored by Automattic - https://automattic.com/        @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart _______________________________________________________________  Usage: wpscan [options]         --url URL                                 The URL of the blog to scan                                                   Allowed Protocols: http, https                                                   Default Protocol if none provided: http                                                   This option is mandatory unless update or help or hh or version is/are supplied     -h, --help                                    Display the simple help and exit         --hh                                      Display the full help and exit         --version                                 Display the version and exit         --ignore-main-redirect                    Ignore the main redirect (if any) and scan the target url     -v, --verbose                                 Verbose mode         --[no-]banner                             Whether or not to display the banner                                                   Default: true         --max-scan-duration SECONDS               Abort the scan if it exceeds the time provided in seconds     -o, --output FILE                             Output to FILE     -f, --format FORMAT                           Output results in the format supplied                                                   Available choices: cli-no-colour, cli-no-color, cli, json         --detection-mode MODE                     Default: mixed                                                   Available choices: mixed, passive, aggressive         --scope DOMAINS                           Comma separated (sub-)domains to consider in scope.                                                    Wildcard(s) allowed in the trd of valid domains, e.g: *.target.tld                                                   Separator to use between the values: ','         --user-agent, --ua VALUE         --headers HEADERS                         Additional headers to append in requests                                                   Separator to use between the headers: '; '                                                   Examples: 'X-Forwarded-For: 127.0.0.1', 'X-Forwarded-For: 127.0.0.1; Another: aaa'         --vhost VALUE                             The virtual host (Host header) to use in requests         --random-user-agent, --rua                Use a random user-agent for each scan         --user-agents-list FILE-PATH              List of agents to use with --random-user-agent                                                   Default: /usr/local/rvm/gems/ruby-2.6.3/gems/cms_scanner-0.8.1/app/user_agents.txt         --http-auth login:password     -t, --max-threads VALUE                       The max threads to use                                                   Default: 5         --throttle MilliSeconds                   Milliseconds to wait before doing another web request. If used, the max threads will be set to 1.         --request-timeout SECONDS                 The request timeout in seconds                                                   Default: 60         --connect-timeout SECONDS                 The connection timeout in seconds                                                   Default: 30         --disable-tls-checks                      Disables SSL/TLS certificate verification, and downgrade to TLS1.0+ (requires cURL 7.66 for the latter)         --proxy protocol://IP:port                Supported protocols depend on the cURL installed         --proxy-auth login:password         --cookie-string COOKIE                    Cookie string to use in requests, format: cookie1=value1[; cookie2=value2]         --cookie-jar FILE-PATH                    File to read and write cookies                                                   Default: /tmp/wpscan/cookie_jar.txt         --cache-ttl TIME_TO_LIVE                  The cache time to live in seconds                                                   Default: 600         --clear-cache                             Clear the cache before the scan         --cache-dir PATH                          Default: /tmp/wpscan/cache         --server SERVER                           Force the supplied server module to be loaded                                                   Available choices: apache, iis, nginx         --force                                   Do not check if the target is running WordPress         --[no-]update                             Whether or not to update the Database         --api-token TOKEN                         The WPVulnDB API Token to display vulnerability data         --wp-content-dir DIR                      The wp-content directory if custom or not detected, such as "wp-content"         --wp-plugins-dir DIR                      The plugins directory if custom or not detected, such as "wp-content/plugins"         --interesting-findings-detection MODE     Use the supplied mode for the interesting findings detection.                                                    Available choices: mixed, passive, aggressive         --wp-version-all                          Check all the version locations         --wp-version-detection MODE               Use the supplied mode for the WordPress version detection, instead of the global (--detection-mode) mode.                                                   Available choices: mixed, passive, aggressive         --main-theme-detection MODE               Use the supplied mode for the Main theme detection, instead of the global (--detection-mode) mode.                                                   Available choices: mixed, passive, aggressive     -e, --enumerate [OPTS]                        Enumeration Process                                                   Available Choices:                                                    vp   Vulnerable plugins                                                    ap   All plugins                                                    p    Popular plugins                                                    vt   Vulnerable themes                                                    at   All themes                                                    t    Popular themes                                                    tt   Timthumbs                                                    cb   Config backups                                                    dbe  Db exports                                                    u    User IDs range. e.g: u1-5                                                         Range separator to use: '-'                                                         Value if no argument supplied: 1-10                                                    m    Media IDs range. e.g m1-15                                                         Note: Permalink setting must be set to "Plain" for those to be detected                                                         Range separator to use: '-'                                                         Value if no argument supplied: 1-100                                                   Separator to use between the values: ','                                                   Default: All Plugins, Config Backups                                                   Value if no argument supplied: vp,vt,tt,cb,dbe,u,m                                                   Incompatible choices (only one of each group/s can be used):                                                    - vp, ap, p                                                    - vt, at, t         --exclude-content-based REGEXP_OR_STRING  Exclude all responses matching the Regexp (case insensitive) during parts of the enumeration.                                                   Both the headers and body are checked. Regexp delimiters are not required.         --plugins-list LIST                       List of plugins to enumerate                                                   Examples: 'a1', 'a1,a2,a3', '/tmp/a.txt'         --plugins-detection MODE                  Use the supplied mode to enumerate Plugins, instead of the global (--detection-mode) mode.                                                   Default: passive                                                   Available choices: mixed, passive, aggressive         --plugins-version-all                     Check all the plugins version locations according to the choosen mode (--detection-mode, --plugins-detection and --plugins-version-detection)         --plugins-version-detection MODE          Use the supplied mode to check plugins versions instead of the --detection-mode or --plugins-detection modes.                                                   Default: mixed                                                   Available choices: mixed, passive, aggressive         --plugins-threshold THRESHOLD             Raise an error when the number of detected plugins via known locations reaches the threshold. Set to 0 to ignore the threshold.                                                   Default: 100         --themes-list LIST                        List of themes to enumerate                                                   Examples: 'a1', 'a1,a2,a3', '/tmp/a.txt'         --themes-detection MODE                   Use the supplied mode to enumerate Themes, instead of the global (--detection-mode) mode.                                                   Available choices: mixed, passive, aggressive         --themes-version-all                      Check all the themes version locations according to the choosen mode (--detection-mode, --themes-detection and --themes-version-detection)         --themes-version-detection MODE           Use the supplied mode to check themes versions instead of the --detection-mode or --themes-detection modes.                                                   Available choices: mixed, passive, aggressive         --themes-threshold THRESHOLD              Raise an error when the number of detected themes via known locations reaches the threshold. Set to 0 to ignore the threshold.                                                   Default: 20         --timthumbs-list FILE-PATH                List of timthumbs' location to use                                                   Default: /root/.wpscan/db/timthumbs-v3.txt         --timthumbs-detection MODE                Use the supplied mode to enumerate Timthumbs, instead of the global (--detection-mode) mode.                                                   Available choices: mixed, passive, aggressive         --config-backups-list FILE-PATH           List of config backups' filenames to use                                                   Default: /root/.wpscan/db/config_backups.txt         --config-backups-detection MODE           Use the supplied mode to enumerate Config Backups, instead of the global (--detection-mode) mode.                                                   Available choices: mixed, passive, aggressive         --db-exports-list FILE-PATH               List of DB exports' paths to use                                                   Default: /root/.wpscan/db/db_exports.txt         --db-exports-detection MODE               Use the supplied mode to enumerate DB Exports, instead of the global (--detection-mode) mode.                                                   Available choices: mixed, passive, aggressive         --medias-detection MODE                   Use the supplied mode to enumerate Medias, instead of the global (--detection-mode) mode.                                                   Available choices: mixed, passive, aggressive         --users-list LIST                         List of users to check during the users enumeration from the Login Error Messages                                                   Examples: 'a1', 'a1,a2,a3', '/tmp/a.txt'         --users-detection MODE                    Use the supplied mode to enumerate Users, instead of the global (--detection-mode) mode.                                                   Available choices: mixed, passive, aggressive     -P, --passwords FILE-PATH                     List of passwords to use during the password attack.                                                   If no --username/s option supplied, user enumeration will be run.     -U, --usernames LIST                          List of usernames to use during the password attack.                                                   Examples: 'a1', 'a1,a2,a3', '/tmp/a.txt'         --multicall-max-passwords MAX_PWD         Maximum number of passwords to send by request with XMLRPC multicall                                                   Default: 500         --password-attack ATTACK                  Force the supplied attack to be used rather than automatically determining one.                                                   Available choices: wp-login, xmlrpc, xmlrpc-multicall         --stealthy                                Alias for --random-user-agent --detection-mode passive --plugins-version-detection passive  [[email protected] ~]#  

Using WPScan on Kali Linux

The beauty of using Kali Linux is you don’t have to install anything. WPScan is pre-installed.

Let’s find out how to run the scanner.

wpscan --url https://mysite.com

Using Docker

A Docker fan?

Why not, it is easy to get it started. Ensure you have Docker installed.

docker pull wpscanteam/wpscan
docker run -it --rm wpscanteam/wpscan --url https://example.com

Easy?

WPScan powered Online Scanner

You can leverage the following tools powered by WPScan.

Geekflare

Geekflare WordPress Security Scanner let you quickly find out if given WordPress site is having vulnerable core version, theme, plugin, etc.

On top of WPScan metrics, it also checks the following.

You don't need to register an account; you can run the test on-demand in FREE.

Pentest-Tools

A tool by Pentest-Tools lets you test the WP site on-demand and produce the report.

What's next?

Well done! If your site is not vulnerable. However, if it does, then work on those risk items. If you are not sure how to mitigate them, then take professional help.