Understanding the Wordpress vulnerability
So $key is an array in the querystring with a single empty string ['']
http://DOMAIN_NAME.TLD/wp-login.php?action=rp&key[]=
reset_password gets called with an array, and then preg_replace gets called:
//$key = [''] $key = preg_replace('/[^a-z0-9]/i', '', $key); //$key = [''] still
because preg_replace accepts either a string or an array of strings. It regex replaces nothing and returns the same array. $key is not empty (it's an array of an empty string) so this happens:
$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_activation_key = %s", $key));
Now from here, I need to go read the wordpress source for how prepare behaves...
More:
So prepare calls vsprintf which produces an empty string
$a = array('');$b = array($a);vsprintf("%s", $b);//Does not produce anything
So the SQL is:
SELECT * FROM $wpdb->users WHERE user_activation_key = ''
Which will apparently match the admin user (and all users without activation_keys I suppose).
And that's how.
I have a related question on how to patch this vulnerability - line 190 on the wp-login.php should now look like this;
if ( empty( $key ) || is_array( $key ) )