Update 12/20 @ 9 AM ET: Updated to reflect our recommendation to update to Log4j 2.17.0 due to vulnerabilities in prior versions.
Previously, we understood that the impact of Log4j was limited to vulnerable servers. This newly-discovered attack vector means that anyone with a vulnerable Log4j version on their machine or local private network can browse a website and potentially trigger the vulnerability. At this point, there is no proof of active exploitation.
This vector significantly expands the attack surface and can impact services even running as localhost which were not exposed to any network.
The client itself generally has no direct control over these WebSocket connections, which can silently initiate when a webpage loads. WebSocket connections within the host can be difficult to gain deep visibility into, which increases the complexity of detection for this attack.
WebSockets have been a part of most common browsers over the last 10 years and are used for a number of tasks as users browse. Commonly used for applications like chat and alerts on websites, WebSockets are great at passing timely information back to the browser and allowing the browser to quickly send data back and forth.
However WebSockets are accompanied by security risks that are largely unseen. WebSockets are not restricted by same-origin policies like a normal cross-domain HTTP request and they expect the server itself to validate the Origin of the request. While they are useful, they also introduce a fair amount of risk as they do not include many security controls to limit their utilization.
Previously we saw vulnerabilities associated with cable modems that leveraged WebSockets to send a malicious request to the modem. Similarly, this attack makes malicious requests to potentially vulnerable localhost or local network servers that were not exposed to the internet itself via WebSocket. These days WebSockets are also used for host-fingerprinting and port scanning by measuring the response rates to determine what ports are open; they inherently introduce a variety of risks to the environment.
In our testing we utilized one of the many JNDI Exploit kits that leverage existing bypasses for simplified RCE exploitation, but it does depend on the host itself. Our local application contained SpringFramework with Log4j 2.13 and would log out all requests to the server.
We saw the most success utilizing the Target environment (Build in JDK – (BYPASS WITH EL by @welk1n) whose trustURLCodebase is false and have Tomcat 8+ or SpringBoot 1.2.x+ in classpath). However, it’s a simple effort to spin up a large subset of known-good JNDI bypass exploit methods and have the WebSockets try each of these exploit methods per IP and Port.
Step 2: As the page loads, it will initiate a local WebSocket connection, hit the vulnerable listening server, and connect out over the identified type of connection based on the JNDI connection string. We saw the most success utilizing RMI (default port 1099), although we are often seeing custom ports used. However, iterating through all available listeners was the easiest path to successful RCE as noted previously. Specific patterns should not be expected as it is easy to trigger traffic passively in the background.
This technique is similar to WebSocket localhost port scanning used for fingerprinting hosts.
Step 3: Once the victim’s host hits an open port to a local service or a service accessible to the host itself, it can then drop the JNDI exploit string in path or parameters as seen in the example above. When this happens, the vulnerable host calls out to the exploit server, loads the attacker’s class, and executes it with java.exe as the parent process. In the example below, you can see java.exe spawning cmd.exe and executing calc.exe within the user context of the vulnerable Java application.
- JNDI Exploit Kit (PoC confirmed with https://github.com/pimps/JNDI-Exploit-Kit)
- Java (JRE8) application with SpringFramework
- Log4j2 2.13
Attacker Watering Hole: Apache2 server hosting html file. This could be any server realistically, it just needs to initiate WebSocket connection
Victim: 2019 Server with Google Chrome (Version 96.0.4664.110) and localhost:8080 log4j vulnerable application (no egress filtering)
Attacker 2nd Stage: Ubuntu server running JNDI Exploit Kit
To mitigate the risk, we strongly advise organizations to update all local development efforts, internal applications and internet-facing environments to
Log4j 2.16 Log4j 2.17.0 as soon as possible, before threat actors can weaponize this exploit further. This means that you should move any custom applications being utilized across your environment in their dependency manifests to 2.17 as soon as possible to avoid incidental exploitation.
This is also a good time to evaluate egress filtering, which can restrict the callback required for the actual exploit to land. Significantly limiting the egress traffic of your endpoints will reduce risk for this attack as you patch applications in the environment. Ensure that only certain machines go out over 53, 389, 636, and 1099 (RMI); all others should be dropped. Attacks that weaponize Log4j often attempt to go out over random high ports. In most situations there is no reason a machine should go out over the internet at 12345, for example.
If you have egress filtering while the machine is on a VPN, it does not mean that this could be incidentally triggered by a developer who left a vulnerable service running while browsing the internet.
The identification of vulnerable internal development, applications, and vendors as well as patching to Log4j 2.16 is paramount in resolving this issue.
- Update all local development efforts as well as internet-facing environments to Log4j 2.17.0
- Review and update or implement egress filtering to ensure that callbacks are not successful in many cases
- Detect when .*/java.exe is the parent process for cmd.exe/powershell.exe – this is potentially very noisy.
- Ensure that your host detection for exploitation of Cobalt Strike, Trickbot, and related common attacker tools are functioning as intended and that you have the needed visibility to do so.
- Identify where Log4j is used within your environments. No scanning script is perfect, but there are a number out there that will help at least identify the libraries used locally:
- Move all local development to https, certs will likely fail for local development so wss:// should also fail unless the browser also trusts them.
Matthew Warner, CTO and Co-Founder, will explain how he discovered this attack vector and answer any questions in a recorded livestream. To watch on demand, go here.