1. CVE-2020-25094: Command Injection
Initial interaction between the client’s browser and the Web Console such as logging in and viewing site data is performed via HTTPS, however it was noted that certain activities, including the execution of SmartResponse requests, was performed by a WebSocket connection that was initiated between the client browser and the Web Console.
By intercepting and manipulating SmartResponse WebSocket traffic, it was determined that the commands being forwarded by the Web Console to the back-end agents, were being performed by Windows PowerShell commands that were being sent inside the WebSocket. By manipulating the WebSocket request, it was relatively simple to rewrite the PowerShell command sent to the back-end agent to any arbitrary payload.
This is a fairly common “Command Injection” vulnerability. While the impact of these vulnerabilities is high, allowing for arbitrary Remote Code Execution (RCE), the commands can only be injected by a user-account that is already relatively highly privileged (i.e., they already have the ability to run SmartResponse commands on the remote servers). This changes “Remote Code Execution” (as intended) to “Arbitrary Remote Code Execution”.
1.5 (No CVE): The agent runs as WHAT?!?
Of course, the first thing you do when you have arbitrary RCE is to ask: What account context are my commands running in? If the RCE is running in an extremely locked-down sandbox, it may not be so bad.
OK, in this case it is bad.
The LogRhythm Smart Response agent installer gives users the ability to specify an account that the agent should run as, but the default behaviour is to run as “NT AUTHORITY\SYSTEM”. This account is a built-in Windows account that is the most highly privileged account on the system, equivalent to “root” on Unix/Linux.
2. CVE-2020-25096 Incorrect Access Control
When further analysing WebSocket traffic being sent by the client, another strange condition was noted. While the HTTP traffic between the client and the Web Console was authenticated using HTTP Cookies, no equivalent token was present when the protocol switched to WebSockets.
Remember back several paragraphs ago when I said “Users within LogRhythm have fine-grained access controls applied to them. Depending on their role membership, they may have access to some data and functionality, but not others. This includes being able to access the data of and interact with some back-end hosts, but not others” ?
This access-control model was simply not being enforced on WebSocket traffic. In fact, the WebSocket requests that sent Smart Response PowerShell commands contained very little in the way of unique information. Which back-end agent the Smart Response command was sent to was determined by a simple 4-digit parameter. If the parameter was altered to correspond to an agent that the current user should not be able to interact with, the command was still successfully sent through and executed on that agent. As the parameter is only 4 digits, it would be feasible for an attacker to brute-force all possible digits, resulting in code execution on any connected system with an agent installed without any regard for the user’s intended access rights.
The combination of CVEs 2020-25094 and 2020-25096 mean that even the most lowly-privileged Web Console user could execute arbitrary code with System privileges on all connected agent hosts. This is obviously an extremely high-impact scenario, but still relies on the initial compromise of a legitimate Web Console user account (or a rogue insider) to kick off the kill-chain.
The particular customer environment being pentested also had one further security control up its sleeve – the entire LogRhythm deployment, including the Web Console, was only accessible from a network segment that required Multi-Factor Authentication to access. As the Web Console could not be accessed from the Internet, these vulnerabilities could not be exploited due to the “Defence in depth” security architecture employed by the customer… or could it?
3. CVE 2020-25095 Cross Site WebSocket Hijacking (CSWH)
The HTTP part of the Web Console relied on a traditional cookie-based authentication control. Cookies are a well-understood and widely adopted approach to authentication of HTTP sessions, however they can suffer from a vulnerability known as Cross-Site Request Forgery (CSRF).
CSRF is an attack whereby a user, who is logged in to a vulnerable web application, subsequently opens another browser tab and unknowingly visits a malicious third-party site.
Without the user’s knowledge, the malicious third-party site sends requests to perform actions on the vulnerable web application using the user’s existing session. This is made possible by the victim’s browser helpfully attaching their session cookie to the cross-domain request made from the malicious site to the vulnerable web application. Due to a browser security control (Same-origin policy) that is applied to cross-domain requests, the malicious third-party site can’t see the response to these cross-domain requests, and so the exploitation of CSRF is normally only useful to an attacker if the cross-domain request can be used to make a change in the vulnerable site (a classic example being updating the victim user’s password to a value the attacker knows).
CSRF attacks can occur when the vulnerable web application does not adequately validate incoming requests to ensure they come from a trusted source.
If CSRF, normally a high-impact vulnerability by itself, can be combined with the request issued by the client to change protocols from HTTP to WebSockets, the impact can be significantly higher.
Unlike normal cross-domain requests, WebSockets are not restricted by Same-origin policy. This means that if a malicious site can send a cross-domain request to initiate a WebSocket connection to a webserver that is vulnerable to CSRF, a WebSocket will be created that allows unrestricted, bi-directional communication between the malicious site and the vulnerable site. This dangerous sub-type of CSRF is known as Cross-Site WebSocket Hijacking (CSWH).
The Web Console was noted to not be validating the “Origin” header in cross-domain WebSocket initiation requests, nor did it implement any other controls designed to prevent CSRF attacks such as unique CSRF tokens, leaving it vulnerable to CSWH.