OK here's my question:
- how to output the full dependency tree of your service/application, and find out if somewhere in the corner, log4j is used? Considering that
mvn dependency:tree
does not allow you to traverse to the bottom of bottom. Check this: when I domvn dependency:tree
on my pom.xml, it gives something like this:
[INFO] | | - io.quarkus:quarkus-core:jar:2.4.1.Final:compile
[INFO] | | | - jakarta.enterprise:jakarta.enterprise.cdi-api:jar:2.0.2:compile
[INFO] | | | | \- jakarta.el:jakarta.el-api:jar:3.0.3:compile
[INFO] | | | - jakarta.inject:jakarta.inject-api:jar:1.0:compile
[INFO] | | | - io.quarkus:quarkus-ide-launcher:jar:2.4.1.Final:compile
[INFO] | | | - io.quarkus:quarkus-development-mode-spi:jar:2.4.1.Final:compile
[INFO] | | | - org.jboss.logging:jboss-logging:jar:3.4.2.Final:compile
[INFO] | | | - org.jboss.logmanager:jboss-logmanager-embedded:jar:1.0.9:compile
[INFO] | | | - org.jboss.logging:jboss-logging-annotations:jar:2.2.1.Final:compile
[INFO] | | | - org.jboss.threads:jboss-threads:jar:3.4.2.Final:compile
[INFO] | | | - org.jboss.slf4j:slf4j-jboss-logmanager:jar:1.1.0.Final:compile
[INFO] | | | - org.graalvm.sdk:graal-sdk:jar:21.2.0:compile
Now I get it, that -
and \-
are used to replace ├
and └
somehow(but till 5 min ago I found it confusing), so they are not "not expanded". But, if the pom of some dependencies uses log4j, am I safe without doing anything? For example, when I check org.jboss.logging:jboss-logging:jar:3.4.2.Final:compile
in https://search.maven.org/artifact/org.jboss.logging/jboss-logging/3.4.2.Final/jar, I see org.apache.logging.log4j:log4j-core:2.11
is used, but then it's excluded later. So I understand that Quarkus is safe. But, do I have to check the pom of each and every jar I find in the dependency tree to find out what is used and what is not?
- if I am using a base image from somewhere, how do I do this process in step 1? How can I know that my base image is vulnerable because it uses, in some corner of the dependency tree, log4j2 < 2.15?
Some background here: https://nvd.nist.gov/vuln/detail/CVE-2021-44228
EDIT: Now I think maybe setting the env var is better, so it will solve it once and for all.
CodePudding user response:
Well the case we are facing, is that we are building an app, foo
, based on Red Hat JBoss AMQ 6. With jib maven plugin, our code would be built into an uber jar and put under /opt/xxx
to execute, and the base image would put other jars into the image under /opt/amq/lib
.
Step 1
For our code, we do:
mvn dependency:tree | grep log4j
And we found some dep from other teams which brings transitive log4j 1.17 or so. The other team would handle it; before that, as a workaround, we would remove JMSAppender.class
and SocketServer.class
from the jar manually in our internal artifactory, so that every jar downloaded from there would lack the class file.
Step 2
To find other libs in the base image containing log4j is more complicated. I have to first find out what are in the image. I first docker save
the official amq63 for Openshift image into a tarball; then, I extract the jar and search the jar with grep
.
docker save <image-name> -o amq63.tar
Extract the tar, enter folder of each layer, and use this script:
#!/bin/bash
for f in $(find . -name "*.jar"); do
echo $f
jar -tvf $f | grep -E "(*JMSAppender*.class|*SocketServer.class|*log4j*.class)"
if [[ $? -eq 0 ]]; then
# only uncomment these lines after confirmation!
#echo Removing class file from $f
#zip -d $f "*JMSAppender.class" "*SocketServer.class" "*SimpleSocketServer.class"
fi
done
Checking some jars found, they may also be affected by the vulnerability. Maybe JMSAppender.class
should be removed from there, too. I find that jib maven plugin can load images from local tar
files like tar://path/to/file.tar
, so we can modify the image tar amq63.tar
and build again. So, if it's in target
, put it like tar://target/amq63.tar
. If it's an absolute path, will be: tar:///home/me/amq63.tar
.
Also, we should change the access of config files too, so that it will be read-only.
EDIT: And, if you want to edit the jar from a running pod, it will not work, because you need to restart to load the class files again, but pods cannot be restarted; they are meant to be immutable; config map changes will persist, but state in the pod will not.
CodePudding user response:
Remember to always check for the latest information from the resources listed below
Answering the question directly:
Checking Log4J dependencies in code:
- I think WesternGun's answer is fine... but personally I think the easiest thing to do is probably to just build your app (if you haven't already) and then recursively search the built application's directory structure for JAR files matching the REGEX
log4j-core-2.([0-9] \.){1,2}jar
(will detect versions vulnerable to CVE-2021-45046 ... CVE-2021-44228 ... CVE-2021-45105). If you want to detect older versions as well (which have their own critical severity CVEs and also need to be upgraded) then the REGEX would just belog4j
and you'd have to manually figure out which specific jars are the vulnerable ones.- it may actually be able to be refined further... but i'm not sure of the specific jar file is the problem for these other CVEs: CVE-2019-17571 and CVE-2021-4104
- Reddit thread: log4j_0day_being_exploited cntl f for
.class and .jar recursive hunter
will give you some tools to help with this recursive search
Detecting Log4J use on running applcation (in container or not doesn't matter):
- Go to Reddit thread: log4j_0day_being_exploited and cntl f for
Vendor Advisories
. Search the lists there for any software/plugins you are running. If you are running something in the list and there is an update available, update. - Then go to the same website and cntl f for
Vulnerability Detection
. Use the tools there. If you detect the vulnerability, remediate. - Then go to the same website and cntl f for
Exploitation Detection
. Use the tools there. These will detect if you have already been attacked. If you detect that you have, then remediate and respond to that attack as necessary.
More resources
- https://www.reddit.com/r/blueteamsec/comments/rd38z9/log4j_0day_being_exploited/
- This one has TONS of useful info including detectors, even more resource links, very easy to understand remediation steps, and more
- https://www.cisa.gov/uscert/apache-log4j-vulnerability-guidance
- https://github.com/cisagov/log4j-affected-db
- https://logging.apache.org/log4j/2.x/security.html
Remediation:
CVE-2021-45046 ... CVE-2021-44228 ... CVE-2021-45105
While most people that need to know probably already know enough to do what they need to do, I thought I would still put this just in case...
- Follow the guidance in those resources... it may change, but
As of 2021-12-18
It's basically
- Remove log4j-core JAR files if possible
- From both running machines for immediate fix AND
- in your source code / source code management files to prevent future builds / releases / deployments from overwriting the change
- If that is not possible (due to a dependency), upgrade them
- If you are running Java8, then you can upgrade to log4j 2.17.0
- If you are running an earlier version of Java, then you can upgrade to log4j 2.12.3
- If you are running an older version of Java, then you need to upgrade to the newest version of Java, and then use the newest version of Log4J
- Again, these changes have to happen both on running machine and in code
- If neither of those are possible for some reason... then there is the NON-remediation stop gap of removing the JndiLookup.class file from the log4j-core JARs.
- There is a one-liner for the stop gap option on Linux using the
zip
command that comes packaged with most Linux distros by default.zip -q -d "$LOG4J_JAR_PATH" org/apache/logging/log4j/core/lookup/JndiLookup.class
- At time of writing, most of the guides online for the stop gap option on Windows say to do the following (again... assuming you can't do one of the remove JAR or upgrade options above):
- Install something like 7-zip
- Locate all of your log4j-core JAR files and for each one do the following...
- Rename the JAR to change the extension to
.zip
- Use 7-zip to unzip the JAR (which now has a
.zip
extension) - Locate and remove the JndiLookup.class file from the unzipped folder
- The path is
\\path\\to\\unzippedFolder\\org\\apache\\logging\\log4j\\core\\lookup\\JndiLookup.class
- The path is
- Delete the old JAR file (which now has an extension of .zip)
- Use 7-zip to RE-zip the folder
- Rename the new .zip folder to change the extension to
.jar
- There are also some options to use Power Shell
- Reddit thread: log4j_0day_being_exploited
- ctrl f for "PowerShell"
- There is a one-liner for the stop gap option on Linux using the
This is fine if you only have 1 or 2 JAR files to deal with and you don't mind installing 7-zip or you have PowerShell available to do it. However, if you have lots of JAR files, or if you don't want to install 7-zip and don't have access to Power Shell, I created an open-source VBS script that will do it for you without needing to install any additional software. https://github.com/CrazyKidJack/Windowslog4jClassRemover
Read the README and the Release Notes https://github.com/CrazyKidJack/Windowslog4jClassRemover/releases/latest