Ecosyste.ms: Advisories

An open API service providing security vulnerability metadata for many open source software ecosystems.

Security Advisories: GSA_kwCzR0hTQS1jcDY4LXFyaHItZzloOM4AA5Zx

MeshCentral cross-site websocket hijacking (CSWSH) vulnerability

We have identified a cross-site websocket hijacking (CSWSH) vulnerability within the control.ashx endpoint of MeshCentral. This component is the primary mechanism used within MeshCentral to perform administrative actions on the server. To demonstrate the impact of the vulnerability we developed a proof-of-concept which leveraged the cross-site websocket hijacking vulnerability to read the server configuration file to leak the sessionKey variable, generating login tokens, and generating an authentication cookie.

The vulnerability is exploitable when an attacker is able to convince a victim end-user to click on a malicious link to a page hosting an attacker-controlled site. The attacker can then originate a cross-site websocket connection using client-side JavaScript code to connect to “control.ashx” as the victim user within MeshCentral. There are some caveats to exploiting this issue however as MeshCentral configures SameSite=Lax security setting on cookies which introduces some additional preconditions for exploitation which we cover in a subsequent section.

MeshCentral Version Tested

We performed testing against MeshCentral version 1.1.20 which appears to be the latest supported version of the application. This appears to have been the latest version of MeshCentral available at the time we performed testing of the application in January and February 2024 (see Figure 1 and Figure 2).

image
Figure 1: We determined that MeshCentral version 1.1.20 was the latest version available at the time we performed testing of the application.

image
Figure 2: We configured our test environment on an Ubuntu server running version 1.1.20 of the MeshCentral application server.

What about SameSite=Lax Cookie Settings?

One may make the counterpoint that the SameSite=Lax security setting (see Figure 4) effectively prevents cross-site websocket hijacking (CSWSH) issues as an attacker origin of attacker.com would not be within the same-site as the victim meshcentral server at say meshcentral.example.com. This means an attacker that is able to convince a user to click on a malicious link wouldn’t be able to successfully perform this attacker to the Lax setting with differing origins.

Unfortunately, this isn’t entirely correct as there is a core difference between same-site and same-origin policies within all modern browsers. In this case, while it’s valid to say that the attack wouldn’t work in the case of attacker.com targeting meshcentral.example.com when the SameSite setting is configured to Lax for session cookies, there are several other scenarios where an attacker could perform the attack successfully (see Figure 3).

image
Figure 3: A table from PortSwigger’s article on Bypassing SameSite Cookie Restrictions (source).

From our perspective, the most relevant scenario is when an attacker is able to compromise an adjacent subdomain either through a vector such as a system compromise, exploiting a subdomain takeover vulnerability, or through exploitation of a cross-site scripting vulnerability within an adjacent application running under the same domain. For example, if an attacker found a cross-site scripting issue on example.com or vulnerable.example.com they would then be able to leverage the cross-site scripting issues on those domains to target meshcentral.example.com. There are other factors which could also allow an attacker to bypass the SameSite=Lax setting to perform cross-site websocket hijacking. For a more comprehensive list please see Bypassing SameSite Cookie Restrictions from PortSwigger.

image
Figure 4: We observed that upon logging into MeshCentral the “xid” and “xid.sig” tokens were configured with the SameSite=Lax security settings.

Developing an Initial Proof-of-Concept Exploit

At this point we had a testing deployment of MeshCentral configured at meshcentral.example.com and simulated an attacker-compromised adjacent subdomain at evil.example.com. In this scenario, we assume the attacker exploited a subdomain takeover vulnerability to host malicious content on evil.example.com. Next, we developed a simple proof-of-concept payload which originated a cross-site websocket connection from the evil.example.com origin to meshcentral.example.com (see Figure 5).

image
Figure 5: An initial proof-of-concept exploit we developed which simply sent a ping-message over the websocket connection from evil.example.com targeting meshcentral.example.com. We then triggered the exploit payload as a user that was logged into the MeshCentral application as an administrator by browsing to evil.example.com with a valid session on meshcentral.example.com. We
observed a cross-site websocket connection to meshcentral.example.com with an origin header set to evil.example.com as it originated from the attacker domain (see Figure 6). The response indicated the connection was successful and we received the expected pong response to our ping message sent to the server.

image
Figure 6: We observed that when originating a websocket connection across origins the origin header was sent by the browser to the MeshCentral server indicating the origin which originated the cross-site websocket connection.

Demonstrating Impact

After confirming the vulnerability we then developed a more comprehensive exploit payload to demonstrate the impact of the vulnerability (see Figure 7). Our new payload sent the serverconfig, authcookie, and createLoginToken actions to the administrative component. The ability to issue a new login token then provided us with persistent access to the users account. The ability to read the serverconfig file allowed us to exfiltrate the session key used to sign sessions allowing the attacker to forge valid session tokens as arbitrary users on the system. Our payload then read the response from the server and exfiltrated the sensitive data exported from the system to an attacker-controlled system for storage purposes (see Figure 8).

image
Figure 7: A proof-of-concept exploit we developed for the cross-site websocket hijacking vulnerability resulting in complete compromise of the user’s account and persistent access to the MeshCentral application as the victim user.

image
Figure 8: We performed the attack using the exploit code shown in Figure AA to invoked the authcookie, serverconfig, and createLoginToken endpoints on the victim MeshCentral system leveraging the cross-site websocket hijacking vulnerability from evil.example.com.

After performing the attack successfully we used the issued login token to authenticate to MeshCental and access the console as the NT AUTHORITY\SYSTEM user for a windows agent which connected to the victim MeshCentral instance. This provided compromise of all the nodes within the impacted MeshCentral instance (see Figure 9 and Figure 10).

image
Figure 9: An attacker could leverage the login token created by the attacker to authenticate to MeshCentral and then leverage this access to compromise nodes managed by the impacted MeshCentral instance.

image
Figure 10: An attacker could leverage the cross-site websocket hijacking vulnerability to read the server configuration file of the MeshCentral system as an administrator to obtain the key used to encrypt sessions (sessionKey).

Remediation

To remediate this vulnerability we recommend inspecting the origin header when websocket connections are established to control.ashx and other websocket endpoints. Verify that the origin header sent to the server matches an allowlisted origin. This would prevent an attacker from originating a cross-site websocket connection from an untrusted site.

Permalink: https://github.com/advisories/GHSA-cp68-qrhr-g9h8
JSON: https://advisories.ecosyste.ms/api/v1/advisories/GSA_kwCzR0hTQS1jcDY4LXFyaHItZzloOM4AA5Zx
Source: GitHub Advisory Database
Origin: Unspecified
Severity: High
Classification: General
Published: 2 months ago
Updated: 2 months ago


CVSS Score: 8.3
CVSS vector: CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:H

Identifiers: GHSA-cp68-qrhr-g9h8, CVE-2024-26135
References: Repository: https://github.com/Ylianst/MeshCentral
Blast Radius: 0.0

Affected Packages

npm:meshcentral
Dependent packages: 4
Dependent repositories: 1
Downloads: 13,333 last month
Affected Version Ranges: < 1.1.21
Fixed in: 1.1.21
All affected versions: 0.0.4, 0.0.6, 0.5.2, 0.5.3, 0.5.4, 0.5.5, 0.5.6, 0.5.7, 0.5.8, 0.5.9, 0.5.10, 0.5.11, 0.5.12, 0.5.13, 0.5.14, 0.5.15, 0.5.16, 0.5.17, 0.5.18, 0.5.19, 0.5.20, 0.5.21, 0.5.22, 0.5.23, 0.5.24, 0.5.25, 0.5.26, 0.5.27, 0.5.28, 0.5.29, 0.5.30, 0.5.31, 0.5.32, 0.5.33, 0.5.34, 0.5.35, 0.5.36, 0.5.37, 0.5.38, 0.5.39, 0.5.40, 0.5.41, 0.5.42, 0.5.43, 0.5.44, 0.5.45, 0.5.46, 0.5.47, 0.5.48, 0.5.49, 0.5.50, 0.5.51, 0.5.52, 0.5.53, 0.5.54, 0.5.55, 0.5.56, 0.5.57, 0.5.58, 0.5.59, 0.5.60, 0.5.61, 0.5.62, 0.5.63, 0.5.64, 0.5.65, 0.5.66, 0.5.67, 0.5.68, 0.5.69, 0.5.70, 0.5.71, 0.5.72, 0.5.73, 0.5.74, 0.5.75, 0.5.76, 0.5.77, 0.5.78, 0.5.79, 0.5.80, 0.5.81, 0.5.82, 0.5.83, 0.5.84, 0.5.85, 0.5.86, 0.5.87, 0.5.88, 0.5.89, 0.5.90, 0.5.91, 0.5.92, 0.5.93, 0.5.94, 0.5.95, 0.5.96, 0.5.97, 0.5.98, 0.5.99, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.6.4, 0.6.5, 0.6.6, 0.6.7, 0.6.8, 0.6.9, 0.6.10, 0.6.11, 0.6.12, 0.6.13, 0.6.14, 0.6.15, 0.6.16, 0.6.17, 0.6.18, 0.6.19, 0.6.20, 0.6.21, 0.6.22, 0.6.23, 0.6.24, 0.6.25, 0.6.26, 0.6.27, 0.6.28, 0.6.29, 0.6.30, 0.6.31, 0.6.32, 0.6.33, 0.6.34, 0.6.35, 0.6.36, 0.6.37, 0.6.38, 0.6.39, 0.6.40, 0.6.41, 0.6.42, 0.6.43, 0.6.44, 0.6.45, 0.6.46, 0.6.47, 0.6.48, 0.6.49, 0.6.50, 0.6.51, 0.6.52, 0.6.53, 0.6.54, 0.6.55, 0.6.56, 0.6.57, 0.6.58, 0.6.59, 0.6.60, 0.6.61, 0.6.62, 0.6.63, 0.6.64, 0.6.65, 0.6.66, 0.6.67, 0.6.68, 0.6.69, 0.6.70, 0.6.71, 0.6.72, 0.6.73, 0.6.74, 0.6.75, 0.6.76, 0.6.77, 0.6.78, 0.6.79, 0.6.80, 0.6.81, 0.6.82, 0.6.83, 0.6.84, 0.6.85, 0.6.86, 0.6.87, 0.6.88, 0.6.89, 0.6.90, 0.6.91, 0.6.92, 0.6.93, 0.6.94, 0.6.95, 0.6.96, 0.6.97, 0.6.98, 0.6.99, 0.7.0, 0.7.1, 0.7.2, 0.7.3, 0.7.4, 0.7.5, 0.7.6, 0.7.7, 0.7.8, 0.7.9, 0.7.10, 0.7.11, 0.7.12, 0.7.13, 0.7.14, 0.7.15, 0.7.16, 0.7.17, 0.7.18, 0.7.19, 0.7.20, 0.7.21, 0.7.22, 0.7.23, 0.7.24, 0.7.25, 0.7.26, 0.7.27, 0.7.28, 0.7.29, 0.7.30, 0.7.31, 0.7.32, 0.7.33, 0.7.34, 0.7.35, 0.7.36, 0.7.37, 0.7.38, 0.7.39, 0.7.40, 0.7.41, 0.7.42, 0.7.43, 0.7.44, 0.7.45, 0.7.46, 0.7.47, 0.7.48, 0.7.49, 0.7.50, 0.7.51, 0.7.52, 0.7.53, 0.7.54, 0.7.55, 0.7.56, 0.7.57, 0.7.58, 0.7.59, 0.7.60, 0.7.61, 0.7.62, 0.7.63, 0.7.64, 0.7.65, 0.7.66, 0.7.67, 0.7.68, 0.7.69, 0.7.70, 0.7.71, 0.7.72, 0.7.73, 0.7.74, 0.7.75, 0.7.76, 0.7.77, 0.7.78, 0.7.79, 0.7.80, 0.7.81, 0.7.82, 0.7.83, 0.7.84, 0.7.85, 0.7.86, 0.7.87, 0.7.88, 0.7.89, 0.7.90, 0.7.91, 0.7.92, 0.7.93, 0.7.94, 0.7.95, 0.7.96, 0.7.97, 0.7.98, 0.7.99, 0.8.0, 0.8.1, 0.8.2, 0.8.3, 0.8.4, 0.8.5, 0.8.6, 0.8.7, 0.8.8, 0.8.9, 0.8.10, 0.8.11, 0.8.12, 0.8.13, 0.8.14, 0.8.15, 0.8.16, 0.8.17, 0.8.18, 0.8.19, 0.8.20, 0.8.21, 0.8.23, 0.8.24, 0.8.25, 0.8.26, 0.8.27, 0.8.28, 0.8.29, 0.8.30, 0.8.31, 0.8.32, 0.8.33, 0.8.34, 0.8.35, 0.8.36, 0.8.37, 0.8.38, 0.8.39, 0.8.40, 0.8.41, 0.8.42, 0.8.43, 0.8.44, 0.8.45, 0.8.46, 0.8.47, 0.8.48, 0.8.49, 0.8.50, 0.8.51, 0.8.52, 0.8.53, 0.8.54, 0.8.55, 0.8.56, 0.8.57, 0.8.58, 0.8.59, 0.8.60, 0.8.61, 0.8.62, 0.8.63, 0.8.64, 0.8.65, 0.8.66, 0.8.67, 0.8.68, 0.8.69, 0.8.70, 0.8.71, 0.8.72, 0.8.73, 0.8.74, 0.8.75, 0.8.76, 0.8.77, 0.8.78, 0.8.79, 0.8.80, 0.8.81, 0.8.82, 0.8.83, 0.8.84, 0.8.85, 0.8.86, 0.8.87, 0.8.88, 0.8.89, 0.8.90, 0.8.91, 0.8.92, 0.8.93, 0.8.94, 0.8.95, 0.8.96, 0.8.97, 0.8.98, 0.8.99, 0.9.0, 0.9.1, 0.9.2, 0.9.3, 0.9.4, 0.9.5, 0.9.6, 0.9.7, 0.9.8, 0.9.9, 0.9.10, 0.9.11, 0.9.12, 0.9.13, 0.9.14, 0.9.15, 0.9.16, 0.9.17, 0.9.18, 0.9.19, 0.9.20, 0.9.21, 0.9.22, 0.9.23, 0.9.24, 0.9.25, 0.9.26, 0.9.27, 0.9.28, 0.9.29, 0.9.30, 0.9.31, 0.9.32, 0.9.33, 0.9.34, 0.9.35, 0.9.36, 0.9.37, 0.9.38, 0.9.39, 0.9.40, 0.9.41, 0.9.42, 0.9.43, 0.9.44, 0.9.45, 0.9.46, 0.9.47, 0.9.48, 0.9.49, 0.9.50, 0.9.51, 0.9.52, 0.9.53, 0.9.54, 0.9.55, 0.9.56, 0.9.57, 0.9.58, 0.9.59, 0.9.60, 0.9.61, 0.9.62, 0.9.63, 0.9.64, 0.9.65, 0.9.66, 0.9.67, 0.9.68, 0.9.69, 0.9.70, 0.9.71, 0.9.72, 0.9.73, 0.9.74, 0.9.75, 0.9.76, 0.9.77, 0.9.78, 0.9.79, 0.9.80, 0.9.81, 0.9.82, 0.9.83, 0.9.84, 0.9.85, 0.9.86, 0.9.87, 0.9.88, 0.9.89, 0.9.90, 0.9.91, 0.9.92, 0.9.93, 0.9.94, 0.9.95, 0.9.96, 0.9.97, 0.9.98, 0.9.99, 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4, 1.0.5, 1.0.6, 1.0.7, 1.0.8, 1.0.9, 1.0.10, 1.0.11, 1.0.12, 1.0.13, 1.0.14, 1.0.15, 1.0.16, 1.0.17, 1.0.18, 1.0.19, 1.0.20, 1.0.21, 1.0.22, 1.0.23, 1.0.24, 1.0.25, 1.0.26, 1.0.27, 1.0.28, 1.0.29, 1.0.30, 1.0.31, 1.0.32, 1.0.33, 1.0.34, 1.0.36, 1.0.37, 1.0.38, 1.0.39, 1.0.40, 1.0.41, 1.0.42, 1.0.43, 1.0.44, 1.0.45, 1.0.46, 1.0.47, 1.0.48, 1.0.49, 1.0.50, 1.0.51, 1.0.52, 1.0.53, 1.0.54, 1.0.55, 1.0.56, 1.0.57, 1.0.58, 1.0.59, 1.0.60, 1.0.61, 1.0.62, 1.0.63, 1.0.64, 1.0.65, 1.0.66, 1.0.67, 1.0.68, 1.0.69, 1.0.70, 1.0.71, 1.0.72, 1.0.73, 1.0.74, 1.0.75, 1.0.76, 1.0.77, 1.0.78, 1.0.79, 1.0.80, 1.0.81, 1.0.82, 1.0.83, 1.0.84, 1.0.85, 1.0.86, 1.0.87, 1.0.88, 1.0.89, 1.0.90, 1.0.91, 1.0.92, 1.0.93, 1.0.95, 1.0.96, 1.0.97, 1.0.98, 1.0.99, 1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.1.7, 1.1.8, 1.1.9, 1.1.10, 1.1.11, 1.1.12, 1.1.13, 1.1.14, 1.1.15, 1.1.16, 1.1.17, 1.1.18, 1.1.19, 1.1.20
All unaffected versions: 1.1.21, 1.1.22