I am working on a faculty project. I need to replicate Wordpress CSRF vulnerability on my localhost wordpress. I am trying to do this: https://wpvulndb.com/vulnerabilities/7691 I couldn't find any useful tutorials. I am thinking about using a Metasploit moduleon Kali Linux. Can someone guide me ?
1 Answers
A Wordpress user can go to this URL and request a password reset link via email:
https://yourwordpress.example/wp-login.php?action=lostpassword
The reset link will look similar to this:
https://yourwordpress.example/wp-login.php?action=rp&key=dDnnToiqjYtsa9KdfVZl&login=admin
The key
parameter in the URL ensures that only the reciever of the email is able to reset the password. After visiting the reset link you will be presented with a form to enter the new password.
Prior to Wordpress 4.0.1, this form didn't supply an anti-CSRF token. Instead, the key
GET parameter is saved into a cookie and after submitting the new password the cookie value is verified.
This means that a user is vulnerable in the time between clicking on the password reset link and entering the new password. In that timeframe, and only then, an attacker could potentially launch a CSRF attack to change the password to an arbitrary value. (But because of this small window of opportunity the bug has limited value in a real-life attack.)
So to reproduce the vulnerability, you could do this:
- Request a password reset link. (e.g. for user
admin
) - Visit the reset link (but don't enter a new password).
- Simulate a CSRF attack by submitting this form from an attacker-controlled domain with an arbitrary password:
<form action="https://yourwordpress.example/wp-login.php?action=resetpass" method="post"> <input type="hidden" name="user_login" value="admin"> <input type="password" name="pass1"> <input type="password" name="pass2"> <input type="submit" name="wp-submit" value="Reset Password"> </form>
The issue was fixed by adding the reset token to the form (in addition to the cookie):
<input type="hidden" name="rp_key" value="<?php echo esc_attr( $rp_key ); ?>" />
And the reset attempt is invalidated when rp_key
doesn't match:
if ( isset( $_POST['pass1'] ) && ! hash_equals( $rp_key, $_POST['rp_key'] ) ) {
$user = false;
}