69

I have read about security vulnerabilities related to Log4j.

How do I check if Log4j is installed on my server? My specific servers use Ubuntu 18.04.6 LTS.

I have installed many third-party packages and maybe some of them contain it.

Is there a command to run on my server to check if Log4j is installed?

2
  • 7
    Note that this is a Java library, so if you are not running any Java application (and by extension, if you don’t have Java installed), you are safe.
    – Didier L
    Dec 12, 2021 at 20:48
  • 15
    Not true - applications can come with their own JRE, you don't have to have installed Java on your system to be running Java applications.
    – mfinni
    Dec 13, 2021 at 17:58

11 Answers 11

48

Try this script to get a hint:

echo "checking for log4j vulnerability..."
OUTPUT="$(locate log4j|grep -v log4js)"
if [ "$OUTPUT" ]; then
  echo "[WARNING] maybe vulnerable, those files contain the name:"
  echo "$OUTPUT"
fi
OUTPUT="$(dpkg -l|grep log4j|grep -v log4js)"
if [ "$OUTPUT" ]; then
  echo "[WARNING] maybe vulnerable, dpkg installed packages:"
  echo "$OUTPUT"
fi
if [ "$(command -v java)" ]; then
  echo "java is installed, so note that Java applications often bundle their libraries inside jar/war/ear files, so there still could be log4j in such applications."
fi
echo "If you see no output above this line, you are safe. Otherwise check the listed files and packages."

Make sure your locate database is up to date with updatedb.

Or better check and run the enhanced script from GitHub which also searches inside packed Java files. Run in one line with

wget https://raw.githubusercontent.com/rubo77/log4j_checker_beta/main/log4j_checker_beta.sh -q -O - | bash   

I am not sure if there could be compiled Java Programs running on the server without java being installed though?

Or even compiled versions where the source files aren't even found inside packed archives any more?


There is also a lot development on GitHub, where you find attacks and countermeasures.


This takes to much time for me. I am looking for someone I can transfer the ownership of the repository on GitHub

12
  • 4
    This has the same caveats as the answer provided by Tero Kilkanen. And just because Java is not on the path that doesn't ensure that it's not installed. Dec 13, 2021 at 5:53
  • 3
    @Uri Chances are very, very high that you have installed an application which uses log4j. Log4j is very, very common in the Java world and Java is a very, very common language. Dec 13, 2021 at 14:50
  • 65
    It amuses me to search for instances of a vulnerability that allows the execution of random remote scripts with a line of bash that runs a random remote script.
    – Oliver
    Dec 13, 2021 at 16:01
  • 4
    Lunasec has excellent info. They have also published hashes of vulnerable log4j binary classes so that you can scan .jar and .war files for them. lunasec.io/docs/blog/log4j-zero-day-mitigation-guide
    – Gerrit
    Dec 14, 2021 at 14:22
  • 2
    locate could be using outdated data, you should execute updatedb first Dec 15, 2021 at 5:11
26

There is no command that will surely tell you that. Some applications ship the libraries they use directly as a jar file, some will contain them in an archive.

And even then you don't know which version is shipped and how it is used. The only way to be sure you mitigate the CVE is to read the security announcements and release notes of your applications and follow their advisories.

10

Try this Commands:

  • dpkg -l | grep liblog4j

  • dpkg -l | grep log4

  • find / -name log4j-core-*.jar

  • locate log4j | grep -v log4js

5
  • is that log4js in the last line a typo?
    – jaskij
    Dec 14, 2021 at 6:58
  • Should I do find / -name log4j-core-*.jar 2>/dev/null or use sudo/root?
    – grofte
    Dec 14, 2021 at 9:43
  • 5
    @JanDorniak I don't think it is. Their idea is to find all log4j mentions, but exclude log4js. Dec 14, 2021 at 9:44
  • @GrzegorzOledzki lack of sleep.... I missed -v
    – jaskij
    Dec 14, 2021 at 10:17
  • I did this find / -name *log4j* and I used composer as a control: find / -name *composer* and it found every single file with that name in it.
    – dustbuster
    Dec 14, 2021 at 15:54
5

I wrote this Python script to find vulnerable Log4j2 versions on your system: https://github.com/fox-it/log4j-finder

It works by by scanning the disk and inside Java Archive files recursively and looking for known bad files.

3
  • Personally recommend this. Easily inspectable code and works recursive on archives.
    – Gerrit
    Dec 15, 2021 at 12:22
  • While it is nice, it runs forever on my machine. Don't know if it is normal
    – maxisam
    Dec 15, 2021 at 20:58
  • Did you try running if with -v and/or a limited directory tree? If you have some network drive attached, it might cause problems.
    – Gerrit
    Dec 16, 2021 at 8:52
4

log4jscanner

Published by Google under the Apache-2.0 License, log4jscanner is a log4j vulnerability filesystem scanner and Go package for analyzing JAR files.

3

Apologizing for the referencing of outside material, I hope this will be tolerable in the present circumstance.

The information Lunasec.io has put out about hashes of vulnerable binary Java .class files:

https://github.com/lunasec-io/lunasec/blob/master/tools/log4shell/constants/vulnerablehashes.go

Also see their blog: https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide/

Should you have ordered hashes (one per line) of suspected classes in a file hashes and have a jar file subject.jar and have the unzip, find and sha256sum commands, then you can do a compare against the known hashes with:

JARFILE=subject.jar; DIROUT=$(mktemp -d); unzip -qq -DD "$JARFILE" '*.class' -d "$DIROUT" && find "$DIROUT" -type f -not -name "*"$'\n'"*" -name '*.class' -exec sha256sum "{}" \; | cut -d" " -f1 | sort | uniq > "$JARFILE"-hashes; rm -rf -- "$DIROUT"

comm -12 hashes subject.jar-hashes

If comm has output, then there is a matching hash.

5
3

Try syft. It creates a software bill of materials (SBOM), which you can then search for old log4j versions (even works with docker images).

Something like syft dir:/opt/foo-application | grep log4j searches in conventional deployments. syft dir:/ | grep log4j should work for your whole server.

Passing your docker images also works:

# syft -q jacobalberty/unifi:5.13.29 | grep log4j
log4j-api                                 2.12.1                               java-archive
log4j-core                                2.12.1                               java-archive
log4j-slf4j-impl                          2.12.1                               java-archive
tomcat-embed-logging-log4j                8.5.2                                java-archive

Creating a script to pass all your docker images to syft should not be too hard, but you might find some inspiration in those scripts of mine: https://github.com/debuglevel/syft-grype-utils

1
  • 1
    Have a look also at Grype -- github.com/anchore/grype -- by the same people. It embeds Syft and lists known vulnerabilities by CVE, so will directly tell you if your system is vulnerable.
    – caelyx
    Jan 10 at 11:55
2

John Hammond published with some others a hosted LDAP redirect service so you can skip all the shenanigans. https://log4shell.huntress.com/

Directions are simple - It generates a client ID for you (it's in the URL, as well as part of the injection string) which you can post to any Form/request/or derivative of web request.

Generally, if you are running anything that "doesn't work with this because it's local access" then you're fine anyway as there is no means for forwarding through your java-based application.

Of note - I believe the majority of concern should be placed at L2/L3 network management hardware; Especially if you're dealing with an ISP or your content is served via a Hosting service.

2
  • 1
    Don't even get me started on the delayed ransomware injection from a pwnd hosting service just serving embedded malware in the requested content. Dec 14, 2021 at 5:26
  • 1
    The source is available here. Run the whole service on your own machine: github.com/huntresslabs/log4shell-tester Dec 15, 2021 at 4:54
1

Checking for installed packages is not sufficient, as log4j can be manually installed by some other applications.

For Linux servers I am using the following: find / -iname "*log4j*.jar"

For Windows servers one can use something similar to that: dir C:\*log4j*.jar /s (changing C: to D: and so on for other disks).

Filenames will generally show the library version, but to double-check you can open the manifest file and read the version/implementation fields.

Please note that the above is not sufficient to catch embedded log4j (eg: in other jar files). For these one has to grep the relevant string, but this is quite time and resource intensive so I suggest going with file search as a first (but incomplete) step.

3
  • Is there something missing in the script from github.com/rubo77/log4j_checker_beta in the accepted answer?
    – rubo77
    Dec 15, 2021 at 8:25
  • 1
    @rubo77 no, but not everyone what to run a random github script on a mission critical server.
    – shodanshok
    Dec 15, 2021 at 8:27
  • 2
    it is not random, look at it it is not much happening in the script and it is easy to understand
    – rubo77
    Dec 15, 2021 at 8:52
1

All the attempts here to address the vulnerabilities in log4j fall short. You cannot rely on the locate command since it only looks in a set of configured paths (/etc/updatedb.conf on Debian).

Software can install itself in locations not configured in updatedb.conf and be completely missed by the cron job which updates the locate database.

Also, it is being discovered that software vendors (like Elastic) have repackaged the vulnerable JndiLookup.class (eg: elasticsearch-sql-cli-7.16.1.jar) in places that were not previously known which leaves solutions incomplete which are built around known file hashes, names or paths.

@shodanshok is on the right path here but rather than searching for log4j explicitly, a look in every '.jar' on the system is what's needed.

This is more complete, requires the zip package. and an extension of shodanshok's answer. This will merely show locations where the JndiLookup.class code is found. Another line could be added to remove these vulnerabilities but I would rather leave that up to admin discretion. The Elastic link above shows how:

for jar in $(find / -name '*.jar'); do
   unzip -l "$jar" | grep 'JndiLookup.class' &>/dev/null && echo "Found vulnerability in $jar"
done

Example:

# for jar in $(find / -name '*.jar'); do
>    unzip -l "$jar" | grep 'JndiLookup.class' &>/dev/null && echo "Found vulnerability in $jar"
> done
Found vulnerability in /usr/lib/unifi/lib/log4j-core-2.13.3.jar
Found vulnerability in /home/minecraft/.m2/repository/org/spigotmc/minecraft-server/1.15.2-SNAPSHOT/minecraft-server-1.15.2-SNAPSHOT.jar
Found vulnerability in /home/minecraft/.m2/repository/org/spigotmc/minecraft-server/1.15.1-SNAPSHOT/minecraft-server-1.15.1-SNAPSHOT.jar
...

Be wary when running this on a system with mounted network filesystems as performance may be affected. In those instances, you need to run the commands on the file server itself.

0

lsof checks open files, posted by Florian Roth on twitter:

ps aux | egrep '[l]og4j'
lsof | grep log4j

two others commands also, but these are the resident, in-memory search commands

Not the answer you're looking for? Browse other questions tagged or ask your own question.