Tales of SugarCRM Security Horrors

SugarCRM is a pretty popular Customer Relationship Management (CRM) application written in PHP code. It was born in 2004 as an open source project hosted on SourceForge, a development repository for free software. By June of the same year, the rapid success of the project allowed the original developers to found SugarCRM Inc. and raise $2 million in venture capital. A month later, on July 3, Sugar Open Source version 1.0 was released. In October 2004, more than 35.000 people had downloaded the software which had been upgraded to version 2.0, and it was named “Project of the Month” on SourceForge. Since then, the company has become one of the most popular CRM vendors in the world, and this growing popularity has provided SugarCRM with sixteen consecutive quarters of revenue growth, namely a 80% year-to-year growth reported at the end of 2013. Up until that moment, the project has been developed by the company working close to the development community and releasing both open source (Community Edition) and commercial versions. However, a blog post published in February 2014 provoked angry reactions from the development community, because it was announced that the company would no longer be releasing new open source versions of their Community Edition, and this would have become a bug-fix-only application…

According to the official website, SugarCRM is currently deployed by more than two million end users (a large portion of which, many industry analysts assume, are using the free Community Edition) in over 120 countries and 26 languages all over the world. Among their customers, which are using the enterprise solutions of SugarCRM, there are companies like IBM, Mitsubishi, Audi AG, HTC, Agfa Healthcare, Sherwin-Williams, Sennheiser Electronic, Live Nation, Rebook, T-Mobile, and Zurich Insurance Group. Starting from Sugar 7, which is not available as Community Edition releases, it can be considered a Software as a Service (SaaS) product, whose customers can choose to use an on-premises product, SugarCRM’s Sugar Cloud, one of SugarCRM’s partners, or public cloud services such as Amazon Web Services, Windows Azure, Rackspace Cloud, or IBM Cloud.

My relationship with SugarCRM began back in November 2011, when I discovered my first ever PHP Object Injection vulnerability (CVE-2012-0694), which made me fall in love with this esoteric and (at that time) pretty unknown class of vulnerabilities. Since then I’ve been in contact with them, working on a sort of private bug bounty program which resulted in a Virtual Internship, in which I performed a security code review of SugarCRM Community Edition as part of my thesis work. As a result, I discovered around fifty different security issues which have been solved in SugarCRM Community Edition versions 6.4.0, 6.4.3, and other commercial versions. From this experience, I learned a lot of new things, and eventually managed to prove my thesis assumptions: too often security is not incorporated within the Software Development Life Cycle (SDLC). One of the most important lessons I learned is related to a quote from Edsger W. Dijkstra which is placed in the first page of my thesis: “Program testing may convincingly demonstrate the presence of bugs, but can never demonstrate their absence!”. This is also linked to another key concept described in my thesis, summed up by another well-known quote: “Security is a process, not a product!”… I would say this is something not really well understood at SugarCRM, especially considering the sequels I’m going to recount in this blog post…

Part 1 – The never-ending vulnerabilities…

So, let’s start taking a look at their very first attempt to fix CVE-2012-0694, which are PHP Object Injection vulnerabilities located in multiple scripts within the application, and they require an user account in order to be exploited. The following __wakeup method has been added in version 6.4.0 CE into certain classes considered harmful because might be abused for object injection attacks, such as SugarCacheFile, SugarLogger, or SugarTheme. Such a magic method is automatically invoked every time an object is being unserialized, and it’s meant to destroy all of the object’s properties upon deserialization in order to avoid object injection attacks:

   /**
   * This is needed to prevent unserialize vulnerability
   */
   public function __wakeup()
   {
       // clean all properties
       foreach(get_object_vars($this) as $k => $v) {
           $this->$k = null;
       }
       throw new Exception("Not a serializable object");
   }

All of the classes which implement this method have a “dangerous” destructor method, so I guess they thought abusing destructor methods is the only way to exploit this kind of vulnerabilities… But what about other classes and magic methods which might be abused as well (for example, to build a “POP chain”)? Anyway, the point is they were still using the unserialize() function with user input thinking to be safe from object injection attacks, but I always told them that this solution should be considered just a workaround for specific attack vectors and not an effective patch for the vulnerabilities. In fact, after a couple of years, in the summer of 2014, I came back to them saying that CVE-2012-0694 was not completely fixed yet, and the vulnerabilities could still be exploited by abusing other classes, like PHP’s built-in classes, or exploit memory corruption vulnerabilities like these type confusion bugs. I tried to suggest once again to switch to json_encode() and json_decode() functions and never use unserialize() with user supplied input, but my advice was rejected because JSON functions might have some negative effects on performance.

In October 2014, I sent them another email describing two new attack vectors that work with SugarCRM CE versions up to 6.5.18. Both of the attack vectors, which may result in SSRF (or XXE in old PHP versions) and LFI, can be performed with “POP chains” fired by the __toString method from the Zend_Oauth_Token class, which might trigger the __call magic method of the object stored into the _httpUtility property. In my opinion, this was just another proof to show them that the root cause of the vulnerabilities – using unserialize() with unsanitized user input – was still there, and that is what should be properly fixed. However, they decided once again to address just my new attack vectors by using the following __wakeup method within the Zend_Oauth_Token class:

    /**
     * After serialisation, re-instantiate a HTTP utility class for use
     */
    public function __wakeup() 
    {
        $this->_httpUtility = new Zend_Oauth_Http_Utility;
    }

Once again, I’ve been in contact with them for some months with regards to few other security vulnerabilities. Up until June 2015, when I noticed I missed another PHP Object Injection vulnerability (KIS-2016-07) which can be exploited by unauthenticated attackers, as opposed to CVE-2012-0694. Therefore, this one is even worse, because the attacker doesn’t need valid credentials in order to exploit the vulnerability. Nevertheless, it took several months before releasing their first official fix which should solve both CVE-2012-0694 and KIS-2016-07 by using an input validation approach. The new fix has been included in SugarCRM Community Edition version 6.5.23 and other commercial versions released on March 2016 along with this security advisory. Basically, they replaced every “dangerous” call to the unserialize() function with a call to the following wrapper function:

   /**
    * Performs unserialization. Accepts all types except Objects
    *
    * @param string $value Serialized value of any type except Object
    * @return mixed False if Object, converted value for other cases
    */
   function sugar_unserialize($value)
   {
       preg_match('/[oc]:\d+:/i', $value, $matches);

       if (count($matches)) {
           return false;
       }

       return unserialize($value);
   }

Yet another epic fail… On May 13, 2016, I sent an email to secure@sugarcrm.com stating the following:

I’ve been thinking of publishing some advisories on my website about the vulnerabilities I discovered and reported to SugarCRM over the last year, including the incomplete fix for CVE-2012-0694 and the new Object Injection within the REST interface, which is exploitable without authentication credentials. I thought to publish these two as “non-fixed”, because I noticed only now that you rolled out a security update for these vulnerabilities: http://www.sugarcrm.com/security/sugarcrm-sa-2016-001

“Because of backward compatibility, PHP serialized input is still accepted. To mitigate this issue input validation is performed on user supplied serialized string rejecting requests if they contain any object declarations as this is not expected by SugarCRM.”

So, I was digging into the new CE version (6.5.23), which should solve my vulnerabilities, and unfortunately I found out that the fix you’ve used could be easily bypassed, as you can see here: https://3v4l.org/oc2cY. This means that CVE-2012-0694 is still not completely fixed in the latest SugarCRM versions, as well as the most recent REST vulnerability, which means that unauthenticated attackers might be able to inject arbitrary objects into the application scope, potentially leading to execution of arbitrary PHP code (or shellcode when exploiting PHP internal vulnerabilities).

Two days later, something really weird and curious (at least for me) happened… This guy posted the following Tweet, which was exactly what I needed to show them how insecure and ineffective is their first prevention mechanism for object injection attacks:

As a consequence, I sent them another email:

There are some really bad news: getting inspired by these Tweets, I’ve been playing with some unserialize() quirks, and it really looks like all PHP versions always destructed broken unserialized objects. In other words, this means that the __wakeup method will not be called on such broken objects, as opposed to their __destruct methods, as you can see here: https://3v4l.org/QqeAD

Basically, this means that my 4+ years old vulnerability (CVE-2012-0694) has never been fixed actually. By sending a specially crafted serialized string with broken data, the resulting unserialized object’s __wakeup method will not be called, bypassing what you’ve been using to “prevent unserialize vulnerabilities”. Considering also the other bypass which concerns your incorrect input validation fix, this means that all current versions of SugarCRM are vulnerable to my old Object Injection vulnerabilities, which can be exploited by authenticated attackers only, as well as to the REST Object Injection vulnerability, and this one can be exploited by unauthenticated attackers. In other words, all of the SugarCRM instances out there are vulnerable to unauthenticated Remote Code Execution (RCE) attacks. I hope you understand how this is critical and dangerous, and so I believe you should communicate this incident to your customers ASAP, providing a working patch in a timely manner!

According to this Tweet, the broken objects issue has been reported to the official PHP bug tracker in May, but it looks like they had no intention to fix it at that time. Strangely enough, after a couple of days from the release of SugarCRM Community Edition version 6.5.24 and other commercial versions – which should finally solve both CVE-2012-0694 and KIS-2016-07 – in July, someone else reported a very similar bug, also providing SugarCRM as a real-world example for exploitation of the issue. What a surprise, this time the bug has been accepted and fixed in PHP versions 5.6.25 and 7.0.10, and today it is also known as CVE-2016-7124.

Now you might say something like: “Is this the end for these vulnerabilities?! SugarCRM now “properly” validates user input before using the unserialize() function, and PHP has released fixed versions to avoid the __wakeup method bypass… I’m using updated versions of both SugarCRM and PHP, what could possibly go wrong there?” Firstly, while SugarCRM is now validating user input not to allowing arbitrary PHP objects to be unserialized, the fact is that the unserialize() function is still being used with user input, so there are still chances for both authenticated (CVE-2012-0694) and unauthenticated (KIS-2016-07) attackers to exploit PHP internal memory corruption vulnerabilities which do not require objects declarations, like this ten years old vulnerability which requires just an array definition or this one which relies on references and arrays declarations. Secondly, the CVE-2016-7124 bug is not the only way to bypass protections which rely on the __wakeup magic method. For instance, another way to bypass the __wakeup method is by leveraging the “classmap” option for a PHP’s built-in SoapClient object, which might allow an attacker to inject arbitrary PHP objects without invoking neither the __construct nor the __wakeup method.

Part 2 – The Month of SugarCRM Security Bugs?

This story is full of strange coincidences: on July 24, 2016 – the same day that the CVE-2016-7124 bug has been reported to the official PHP bug tracker for the second time – I decided to take a look at the new SugarCRM Community Edition version 6.5.24, and almost immediately discovered what I called a “Bean Injection” vulnerability, which I promptly reported to secure@sugarcrm.com:

Getting inspired by the vulnerability described in sugarcrm-sa-2016-007, I started looking for similar vulnerabilities in the latest SugarCRM CE version (namely 6.5.24), and I think I discovered a different vulnerability within the MergeRecords module, file /modules/MergeRecords/SaveMerge.php [...] I did manage to create a new administrator user while being authenticated with a non-admin user account by sending the following HTTP request [...] Please note that this kind of vulnerability could be abused to create an arbitrary SugarBean, so the admin user creation is not the only possible attack vector. For instance, this can also be exploited to achieve arbitrary PHP code execution (RCE) by injecting arbitrary serialized PHP objects into the “user_preferences” table (specifically, into the “contents” field), and probably by other means too.

Even though it was midsummer, those days I was getting a bit bored… I didn’t have lots to do, so I spent some days at the end of July looking for new security bugs in the latest SugarCRM Community Edition version. The hunting has started pretty well, after the sweet fruit found a few days before – I believe these “Bean Injection” vulnerabilities are quite fascinating – I had the feeling I could have find something new, and that’s what actually happened: in three days, starting from the beginning of August, I reported one vulnerability per day to secure@sugarcrm.com, for a total of three different new vulnerabilities – actually four, without even notice the second Blind SQL Injection vulnerability accidentally used in my Proof of Concept while I’ve been thinking to exploit the code path for the first one… So, this is the complete list of the vulnerabilities:

  • Bean Injection Vulnerability in MergeRecords module – reported on July 24, 2016
  • Blind SQL Injection Vulnerability in InboundEmail::importOneEmail – reported on August 1, 2016
  • Blind SQL Injection Vulnerability in InboundEmail::deleteMessageFromCache – reported on August 1, 2016
  • Local File Inclusion Vulnerability in InboundEmail::setEmailForDisplay – reported on August 2, 2016
  • Second-Order PHP Object Injection through “Emails” User Preferences – reported on August 3, 2016

At this point, I decided to stop my hunting, especially due to a summer trip coming up, but also because I was pretty satisfied with my results: even though all of the vulnerabilities can be exploited by authenticated attackers only, three out of five might allow a malicious user to execute arbitrary PHP code (RCE) – well, actually also exploitation of the Blind SQL Injection vulnerabilities could indirectly lead to Remote Code Execution, but that’s another story… On the other hand, I think I could have keep going at the same rate, probably reporting one vulnerability/weakness per day throughout the month of August… That’s one of the reasons why I ironically wrote the following postscriptum when I reported the Second-Order PHP Object Injection vulnerability: don’t worry, for me August is not going to be the month of SugarCRM security bugs, I promise this is the last security report that I send! :)

They replied to my first report on July 28, firstly to say thank you for my responsible disclosure. Then kindly asked to give them the proper time to respond and communicate this incident to their customers, and once a fix is available and their customers have been notified, they will notify me with the release details so I can proceed disclosing this incident to the public. In the end, they said that at SugarCRM they value security as one of their top priorities, and I should not hesitate to reach out to secure@sugarcrm.com if I have any more questions. With regards to the Local File Inclusion vulnerability report I received no responses at all, while for all of the other reports they replied again with the same nursery rhyme, and then saying to be already aware of the issues (probably referring to the exploitation example I provided in the email I sent on July 24), some of which were already addressed in higher release (commercial only?) versions, while the remaining will be fixed in the next releases…

Well, almost nine months have gone by, and all of these vulnerabilities are still there (so they are 0-days), affecting also the latest SugarCRM Community Edition version, namely 6.5.25, which has been released some weeks ago! However, it looks like they probably – and silently! – fixed some of the vulnerabilities in certain commercial versions at some point between September and October, because I wasn’t able to reproduce the issues anymore with one of their free trial websites, which usually run the latest SugarCRM Enterprise Edition version. It’s just an assumption, I’m not sure whether and exactly which commercial versions include fixes for these vulnerabilities, also because there are no security advisories on the matter published on the SugarCRM website yet.

After a while, in mid-September, I decided to listen to the voices in my head, which were saying that these vulnerabilities would have probably been fixed after several months, particularly given my previous experience… Therefore, since the same security bugs affected SuiteCRM as well, which is a SugarCRM fork, I decided to report the issues also to this other open source project, and those guys have quickly solved the vulnerabilities with a couple of new releases of their software. By the way, I’ve already been in contact with these guys at the end of June 2016, when I sent them another report about the CVE-2012-0694 and KIS-2016-07 vulnerabilities, because both were affecting SuiteCRM as well, and considering also the “new” CVE-2016-7124 bug – and the fact that waiting for SugarCRM to release fixed CE versions was unacceptable, considering their timing with regards to security updates – I thought it was fair to alert them about the related critical risk. Indeed, they released new SuiteCRM versions just after a week from my report, which solved the vulnerabilities by removing the SugarRestSerialize.php file altogether, in order to fix KIS-2016-07, and switching to JSON functions to fix CVE-2012-0694, instead of keep using unserialize() with user input.

Part 3 – Entering the realm of SugarCRM customers…

On August 23, 2016, I received some sort of automated emails from SugarCRM Customer Support <support@sugarcrm.com> related to the security reports that I sent a few weeks before. All of the emails have the same content:

Thank you for contacting SugarCRM to report a potential security vulnerability. We take security and the protection of our customers’ systems and data very seriously, and we appreciate the time that you have taken to inform us of this vulnerability. We request that you register for an account on our website at www.sugarcrm.com and reply back to this email to inform us of the username that you have registered. A registered account will grant you access to our Support Portal, where you can track the status of this vulnerability report, in addition to providing an outlet for communication between you and the SugarCRM security team. We ask that you refrain from publicly disclosing this vulnerability until a remedy has been developed and released. We will ensure that you remain updated during the vulnerability identification and resolution process through the Support Portal.

(Un)Fortunately, I was still in the middle of my summer trip at that time, so I had to postpone my user account registration on their Support Portal. That was completed on September 7, 2016, the day that I entered the “realm of SugarCRM customers”… After logging into the portal, I immediately felt the smell of security bugs, just a sensation… But that was a good one, because it took me just a couple of minutes to discover the first security issue: Stored XSS Vulnerability via Attachment Filename in Case’s Notes.

Well, at a first glance I thought that was a pretty cool bug, but maybe not really a so much serious vulnerability – even though later I realized I was wrong… However, I was pretty confident that I could have find something even more cool, so I kept looking for other security issues… The next day, I notified them about another vulnerability affecting their Support Portal, and this time it looked like a really “promising” one: I’ve been using Burp Suite while being authenticated and messing around with the portal, when I noticed a suspicious JSON response from one of the portal API endpoints… Such a response included a “query” field that seemed a sort of SQL query interpolated with some HTTP POST parameters. Well, it looks like I discovered a SQL Injection Vulnerability within the /api/v1/note/search API endpoint, even though I’m not completely sure about the nature of the vulnerability, as far as I know it could have been even an HQL Injection vunerability… Anyway, whatever it was, the point is that I just tried something pretty obvious and straightforward, the string SQLi' or ''=' and it worked out: the API endpoint returned the first 100 notes (a number that can be controlled through the “limit” POST parameter) stored in the Case Portal, including the ones of other users’ cases…

And so I found a security vulnerability that could give me read access to all of the notes within the Case Portal – and probably also to other tables in the underlying database – that’s pretty cool!! However, I’d never thought the content of the cases’ notes could include such “sensitive” information, with such catastrophic consequences if stolen by a malicious user… The first thing I did was to look for the string “password” within the JSON response shown above, and suddenly found out some notes like the following:

ID: 9b3357d8-8864-80e3-e407-57d31e9ec1f1
Name: Backup Upload
Date: 2016-09-09 20:40:22

Hello ██████,

Thank you for contacting SugarCRM Support.

I would be more than happy to help you with this. I have set up a FTP account for you to add the files for this. We would need both the Database (in the form of a .sql) and the files (in the form of either .tar.gz or .zip). Once you have added those two files let me know and we can use those files to refresh the dev instance you specified.

Host: ftp.sugarcrm.com
Username: virginmobile
Password: g9AEQNY3FX

Thank you,
████ ██████
SugarCRM Support

So it sounds like the SugarCRM Support Team often uses the following (bad security) practice to solve customers’ cases: they ask the client to backup their SugarCRM instance – often including a database dump too – and upload the backup to ftp.sugarcrm.com, fix the issues and then tell the customer they can download back their fixed SugarCRM instance to deploy it on their servers or cloud providers. Actually I was quite surprised to see those FTP credentials, and I’m too curious not to try if these credentials were valid… Well, they were valid, but I was even more surprised when I saw the actual backup files of their customers hosted on the SugarCRM FTP server, ready to be downloaded (and eventually re-uploaded) by any malicious user… In that moment I was like :shock:

Furthermore, as you can see in the screenshot above, I also tried to resend a new HTTP POST request without session cookies, and the server returned the very same response. So, apparently the /api/v1/note/search API endpoint does not properly check authentication cookies, in other words it looks like the endpoint is also affected by an Authentication Bypass Vulnerability. This means that a remote unauthenticated attacker could have used a PHP script like the following in order to download all of the cases’ notes stored within the SugarCRM Support Portal and disclose potentially sensitive information:

$post_params['parent_id'] = "' OR ''='";
$post_params['parent_type'] = "' OR ''='";
$post_params['limit'] = 1000;

for ($offset = 0; true; $offset += 1000)
{
    $post_params['offset'] = $offset;
    $response = http_post('https://web.sugarcrm.com/api/v1/note/search', $post_params);
    save_json_notes($response);
}

As you can imagine, a Customer Support Portal like this might store a lot of valuable information from an attacker’s perspective… Actually, by looking at some of the notes I realized that an attacker could have had access to Personally Identifiable Information (PII) of SugarCRM customers including but not limited to their full names, personal or corporate email addresses, and internal corporate phone numbers. Other “interesting” information include private and public corporate IP addresses and URLs, MySQL and MSSQL credentials, SSH credentials, VPN credentials and certificates for accessing internal corporate networks of SugarCRM customers (as you can see in the screenshot above, there’s also a “VPN” directory on the FTP server), etc… In a nutshell, this would be just like heaven for any cracker out there! However, because of the (bad security) practice described before – asking the customer to upload their backups to the SugarCRM FTP server – I believe the business impact of these vulnerabilities is even higher, because the combination of the issues might have allowed a remote unauthenticated attacker to do something really bad:

  • First obvious thing: an attacker could steal the source code of Professional, Corporate, or Enterprise editions for personal usage without paying for a license, as well as downloading the source code of customized and private SugarCRM modules. The attacker could also publicly release on the Internet the source code of commercial editions ⟹ Game Over!
  • An attacker could have had full access to the SugarCRM’s database of any customer that upload a backup to the FTP server. This could be exploited to disclose lots of sensitive information stored into the DB, as well as potentially gain access to the server where the instance is running by placing a backdoor into the source code ⟹ Sugar Instance Pwned!
  • In case a SugarCRM instance is hosted on an intranet server, not publicly exposed over the Internet, a motivated attacker might “follow” the case resolution process day by day, and when the Support Team will say “ok customer, you can download back your instance from the FTP server and deploy it, now it’s fixed”, she just has to login to the FTP server, download the backup, modify the source code to insert a backdoor and wait for the customer to deploy the infected package. At this point the backdoor may use a reverse-shell to connect back to the attacker’s machine ⟹ Intranet Sugar Instance Pwned!
  • I noticed that some on-premises instances are hosted on edge.sugarondemand.com (70.42.242.50), which is within the same subnet of the updates.sugarcrm.com server (70.42.242.54). This means that when a motivated and skilled attacker has full access to one of such instances, she could try to further penetrate the internal network trying to gain access to the updates server. In case she will succeed, every single SugarCRM instance out there (both on intranets and over the Internet) can be fully compromised by modifying ad-hoc the updater endpoint ⟹ All Sugar Instances “Automagically” Pwned!!

At this point I realized that a very similar impact might be achieved also by leveraging the first security issue I discovered on their Support Portal, the Stored XSS Vulnerability via Attachment Filename in Case’s Notes: even though the session cookies are being set with the “HttpOnly” attribute, not to allowing the XSS to be exploited to directly steal cookies and subsequently carry out Session Hijacking attacks, a motivated attacker could have injected a more sophisticated payload or a BeEF hook in order to impersonate the victim user as soon as they open the affected case page containing the XSS payload… I guess the SugarCRM Support Team has access to all of the cases within the Support Portal, so if an attacker manage to hijack their user session, she could have achieved the very same result: read all of the notes stored in the Case Portal with the aforementioned consequences!

Well, as of today I still don’t know if they fixed the Stored XSS Vulnerability, because my user account has been deactivated and starting from mid-September only SugarCRM customers are allowed to access the Case Portal – now you need to provide a valid subscription key within the registration form. On the other hand, I can safely say they have fixed the SQL Injection Vulnerability by using proper input validation for the affected parameters. Unfortunately, I can make this assumption because I’m still able to test the vulnerable API endpoint, which means the Authentication Bypass Vulnerability is still not fixed, as you can see in this screenshot:

This means that an attacker might still be able to download some cases’ notes by guessing their UUIDs without having an user account registered on the SugarCRM Support Portal. This is possible due to a missing “rate limiting” mechanism used to prevent clients from issuing too many requests over a short amount of time to a specific API endpoint. So, an attacker can use some sort of automated brute-force tool which might send multiple simultaneous HTTP requests trying to guess the ID of an existing note, which can be easier if the UUIDs are being generated with something like the “maybe-not-so-random” create_guid() SugarCRM’s core function. As a final note, I’d like you to notice what they replied to my Stored XSS Vulnerability report (see the screenshot above): “If you find additional security vulnerabilities in the future, you may also file those via the support portal. In doing so, please ensure that the support case is filed with a P3 priority level”… As described in their Knowledge Base website, they have three priority levels to handle issues on their Support Portal, and “P3″ is the lowest level used for non-critical issues or general questions on the application! That says a lot about how they handle and “promptly” resolve security issues in their products and services…

Part 4 – Pwn a server to rule them all!

In this final part I’d like to explain a bit more in details what I mean when I say All Sugar Instances “Automagically” Pwned. The point is that all SugarCRM versions are currently affected by a vulnerability similar to the WordPres auto-update flaw published in November 2016. In this case the vulnerability exists because of the check_now() function, which is called from time to time when an user logs into a SugarCRM instance or a SugarCRM administrator clicks on the “Check Now” button from within the Sugar Updates interface. This function will send a SOAP request to the endpoint located at https://updates.sugarcrm.com/heartbeat/soap.php and will pass data from the SOAP response to the unserialize() function:

		$encodedResult = $sclient->call('sugarHome', array('key'=>$key, 'data'=>$encoded));
	} else {
		$encodedResult = $response_data['data'];
		$key = $response_data['key'];
	}

	if ($response_data || !$sclient->getError()) {
		$serializedResultData = sugarDecode($key, $encodedResult);
		$resultData = unserialize($serializedResultData);

This means that if an attacker does manage to compromise the updates.sugarcrm.com server, then she might be able to “pwn” every SugarCRM instance out there by exploiting such an over-the-net PHP Object Injection vulnerability, resulting in a sort of “domino effect” in which more than two million SugarCRM instances all over the world might be simultaneously and automatically compromised by modifying ad-hoc the SOAP updater endpoint, such that the SOAP server will send back malicious serialized data which might result in arbitrary PHP code execution – for instance, by leveraging the __destruct method from the SugarCacheFile class to write arbitrary PHP files, like I did in my Metasploit module for KIS-2016-07.

However, there might be different ways to compromise and get a shell on the updates.sugarcrm.com server. For instance, it looks like the SOAP server located at https://updates.sugarcrm.com/heartbeat/soap.php is currently using the unserialize() function with user input taken from the SOAP request when handling calls to the “sugarHome” SOAP method, which means that an attacker could try to exploit PHP internal vulnerabilities – like this type confusion vulnerability published last January – in order to execute arbitrary code on the updates.sugarcrm.com server and consequently modify the SOAP server in a malicious fashion.

On the other hand, compromising the updates.sugarcrm.com server is not the only way for such an over-the-net PHP Object Injection attack to succeed: I’m not sure about commercial editions, but all Community Edition versions are using the NuSOAP library to send out the SOAP requests from within the check_now() function, and by default this library uses the cURL extension without setting the “CURLOPT_SSL_VERIFYPEER” option, which stops cURL from verifying the peer’s SSL certificate and therefore it will establish an SSL connection even with self-signed certificates. This means that certain SugarCRM instances might be compromised even by leveraging DNS cache poisoning attacks where the DNS resolution for the updates.sugarcrm.com host will be translated to the attacker’s computer IP address, in which she might host a malicious SOAP server (with a self-signed SSL certificate) that can compromise all of the SugarCRM instances that will send SOAP requests to it.

Conclusion

I’m not a CRM expert, not even a CRM user, so I can’t say anything about how good and effective SugarCRM is in doing its job. On the other hand, I can say that SugarCRM is one of the most insecure web applications I’ve ever seen in my life (and believe me, I tested and reviewed a lot of web applications): I’ve been quite lucky in choosing SugarCRM as target for my experimental thesis, it made me reach some successful results by discovering lots of security issues in it. However, I think there are still room for improvements with regards to SugarCRM security: I’m pretty sure there are still dozens of 0-day vulnerabilities probably affecting commercial versions as well, so I would say that SugarCRM could be the right choice for Capture the Flag (CTF) competitions – for instance, it has been used during HITCON CTF 2016 – or for training exercises in case you want to improve your code review, bug hunting and web exploitation skills… Furthermore, some recent rumors are saying that Apple is going to launch its own CRM system based on SugarCRM… Well, I reckon that Apple security engineers have done a good work reviewing their new system and fixing all of the security bugs inherited from SugarCRM, otherwise also Apple customers might be at risk when their new “Apple CRM” will be alive. So this is the end, I really hope this blog post will make improvements towards the security of the SugarCRM ecosystem.