2009-08-12 18 views
14

एक भेद्यता का हाल ही में खुलासा किया गया है जो वर्डप्रेस 2.8.3 को प्रभावित करता है और व्यवस्थापक को पासवर्ड बदलकर व्यवस्थापक खाते को लॉक कर देता है।वर्डप्रेस भेद्यता को समझना

This post पूर्ण प्रकटीकरण पर दोष का विवरण है, और इसमें प्रासंगिक कोड स्निपेट शामिल हैं। पोस्ट में उल्लेख किया गया है कि 'आप पासवर्ड रीसेट फ़ंक्शन का दुरुपयोग कर सकते हैं, और पहले चरण को बाईपास कर सकते हैं और फिर $ कुंजी चर में सरणी सबमिट करके व्यवस्थापक पासवर्ड रीसेट कर सकते हैं।'

मुझे किसी और विवरण में बग को समझाते हुए PHP से परिचित किसी में दिलचस्पी होगी।

प्रभावित लोगों को update को एक नई 2.8.4 रिलीज के लिए होना चाहिए जो स्पष्ट रूप से दोष को ठीक करता है।

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 ]... 
+1

मेरे शब्द प्रेस इंस्टॉल को अपडेट करने के लिए मुझे गलती से चेतावनी देने के लिए धन्यवाद। :-) –

उत्तर

17

तो $ कुंजी के साथ एक एकल रिक्त स्ट्रिंग [ '']

http://DOMAIN_NAME.TLD/wp-login.php?action=rp&key[]=

reset_password एक सरणी के साथ बुलाया जाता है क्वेरी स्ट्रिंग में एक सरणी है, और फिर preg_replace कहा जाता हो जाता है :

//$key = [''] 
$key = preg_replace('/[^a-z0-9]/i', '', $key); 
//$key = [''] still 

क्योंकि preg_replace eithe स्वीकार करता है एक स्ट्रिंग या तारों की एक सरणी है। यह regex कुछ भी बदलता है और एक ही सरणी देता है। $ कुंजी खाली नहीं है (इसे रिक्त स्ट्रिंग की एक सरणी है) तो ऐसा होता है:

$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users 
     WHERE user_activation_key = %s", $key)); 

अब यहाँ से, मैं कैसे बर्ताव करता है तैयार के लिए वर्डप्रेस स्रोत पढ़ा जाने की जरूरत है ...

अधिक :

तो कॉल vsprintf जो एक खाली स्ट्रिंग का उत्पादन तैयार

$a = array(''); 
$b = array($a); 
vsprintf("%s", $b); 
//Does not produce anything 

तो एसक्यूएल है:

चुनें * $ wpdb- से> उपयोगकर्ताओं कहां user_activation_key = ''

कौन सा होगा जाहिरा तौर पर मैच व्यवस्थापक उपयोगकर्ता (और ACTIVATION_KEYS बिना सभी उपयोगकर्ताओं मुझे लगता है)।

और इसी तरह।

+0

एक खाली सरणी खाली() चेक के लिए सच हो जाएगी, लेकिन कुंजी गुजरने से [] = आपको एक खाली स्ट्रिंग के साथ एक सरणी मिलती है जो इसके एकमात्र तत्व के रूप में होती है। vpsprintf() एक आउटपुट करने के बजाए एक मान देता है, इसलिए आपका नमूना कोड वास्तव में कुछ भी नहीं कह रहा है। दोनों मामलों में, आपकी तर्क ध्वनि है और अंतिम परिणाम वही है। – Greg

+0

आपके सुधारों को जोड़ा गया –

+0

आपके विश्लेषण के लिए धन्यवाद! – PaulG

0

मेरे पास how to patch this vulnerability पर एक संबंधित प्रश्न है - wp-login.php पर लाइन 190 अब इस तरह दिखना चाहिए;

if (empty($key) || is_array($key)) 
संबंधित मुद्दे