When run on a box, outputs a single row of JSON for every proc on the box that loads a jar
/war
that contains any files with 'log4j'
in them, including precisely what triggered the match. For example (pretty printed here for clarity; note that this one is happily a false positive):
{
"node": "HW0000001",
"time": 1632617610.3860812,
"pid": 78676,
"cmd": "/usr/local/opt/openjdk/libexec/openjdk.jdk/Contents/Home/bin/java",
"args": [
"-Xms128M",
"-Xmx4g",
"-Dawt.useSystemAAFontSettings=lcd",
"-Dswing.aatext=true",
"-XX:+UseG1GC",
"-classpath",
"/usr/local/Cellar/jadx/1.2.0/libexec/lib/jadx-gui-1.2.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jfontchooser-1.0.5.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jadx-cli-1.2.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jadx-core-1.2.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/android-29-clst.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/android-29-res.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/logback-classic-1.2.3.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jadx-smali-input-1.2.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jadx-java-convert-1.2.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/dx-1.16.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jadx-dex-input-1.2.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jadx-plugins-api-1.2.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/slf4j-api-1.7.30.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/baksmali-2.4.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/smali-2.4.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/util-2.4.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jcommander-1.80.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/rsyntaxtextarea-3.1.1.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/image-viewer-1.2.3.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/gson-2.8.6.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/commons-text-1.9.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/commons-lang3-3.11.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/rxjava2-swing-0.3.7.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/rxjava-2.2.19.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/apksig-4.0.1.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/logback-core-1.2.3.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/reactive-streams-1.0.3.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/dexlib2-2.4.0.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/guava-29.0-jre.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/asm-8.0.1.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/failureaccess-1.0.1.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/jsr305-3.0.2.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/checker-qual-2.11.1.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/error_prone_annotations-2.3.4.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/j2objc-annotations-1.3.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/antlr-runtime-3.5.2.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/stringtemplate-3.2.1.jar:/usr/local/Cellar/jadx/1.2.0/libexec/lib/antlr-2.7.7.jar",
"jadx.gui.JadxGUI",
"/usr/local/Cellar/jadx/1.2.0/libexec/lib/logback-classic-1.2.3.jar"
],
"pkgs": {
"/usr/local/Cellar/jadx/1.2.0/libexec/lib/logback-classic-1.2.3.jar": {
"hash": "fb53f8539e7fcb8f093a56e138112056ec1dc809ebb020b59d8a36a5ebac37e0",
"manifest": "[elided for readme]",
"matches": {
"ch/qos/logback/classic/log4j/XMLLayout.class": [
[21, "properties�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�(Lch/qos/logback/classic/log4j/XMLLayout;�start�setLocationInfo�(Z)V�flag�getLocationInfo�()Z�\rsetProperties�\rgetProperties�doLayout�>(Lch/qos/logback/classic/spi/ILoggingEvent;)Ljava/lang/String;�step�3Lch/qos/logback/classic/spi/StackTraceElementProxy;�arr$�4[Lch/qos/logback/classic/spi/StackTraceElementProxy;�len$�i$�stepArray�immediateCallerData�Ljava/lang/StackTraceElement;�callerDataArray�[Ljava/lang/StackTraceElement;�entry�Entry�InnerClasses�Ljava/util/Map$Entry;�Ljava/util/Iterator;�entrySet�Ljava/util/Set;�propertyMap�Ljava/util/Map;�event�*Lch/qos/logback/classic/spi/ILoggingEvent;�tp�,Lch/qos/logback/classic/spi/IThrowableProxy;�LocalVariableTypeTable�;Ljava/util/Map$Entry<Ljava/lang/String;Ljava/lang/String;>;�LLjava/util/Set<Ljava/util/Map$Entry<Ljava/lang/String;Ljava/lang/String;>;>;�5Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;�\rStackMapTable�h�getContentType�()Ljava/lang/String;�&(Ljava/lang/Object;)Ljava/lang/String;�Signature�LLch/qos/logback/core/LayoutBase<Lch/qos/logback/classic/spi/ILoggingEvent;>;�\n"],
[22, "SourceFile�XMLLayout.java�T�U�I�J�M�J�java/lang/StringBuilder�T�O�P�Q�R�S�R�[�U�<log4j:event logger=\"�\"\r\n"],
[25, "� <log4j:message>�</log4j:message>\r\n"],
[26, "� <log4j:throwable><![CDATA[�\r\n"],
[27, "�]]></log4j:throwable>\r\n"],
[28, "� <log4j:locationInfo class=\"� method=\"�\" file=\"�\" line=\"�\"/>\r\n"],
[29, "�b�`�u� <log4j:properties>�`�\n"],
[31, " <log4j:data� name='�java/lang/String�'� value='�\r� />�\r\n"],
[32, " </log4j:properties>�\r\n"],
[33, "</log4j:event>\r\n"],
[35, "�text/xml�(ch/qos/logback/classic/spi/ILoggingEvent�c�d�&ch/qos/logback/classic/log4j/XMLLayout�ch/qos/logback/core/LayoutBase�*ch/qos/logback/classic/spi/IThrowableProxy�\rjava/util/Map�\rjava/util/Set�java/util/Iterator�(I)V�capacity�()I�setLength�append�-(Ljava/lang/String;)Ljava/lang/StringBuilder;�\rgetLoggerName�%ch/qos/logback/core/helpers/Transform�\n"]
],
"ch/qos/logback/classic/spi/CallerData.class": [
[13, "SourceFile�CallerData.java�&�'�q�t�u�v�w�D�E�$�%�java/lang/StackTraceElement�x�y�org.apache.log4j.Category�org.slf4j.Logger�z�{�H�I�r�|�}�s�~�java/lang/String�?�&�java/lang/StringBuilder�?#?:?�w�#�%ch/qos/logback/classic/spi/CallerData�java/lang/Object�java/lang/Throwable�java/util/List�java/util/Iterator�\rgetStackTrace� ()[Ljava/lang/StackTraceElement;�getClassName�()Ljava/lang/String;�equals�(Ljava/lang/Object;)Z�\n"]
],
"META-INF/maven/ch.qos.logback/logback-classic/pom.xml": [
[53, " <artifactId>log4j-over-slf4j</artifactId>\r\n"],
[63, " <!-- Must be after log4j-over-slf4j:\r\n"],
[64, " * we want to use the classes from log4j-over-slf4j (so it must come first);\r\n"],
[65, " * we want to use log4j.dtd from log4j. -->\r\n"],
[67, " <groupId>log4j</groupId>\r\n"],
[68, " <artifactId>log4j</artifactId>\r\n"]
]
}
}
}
}
Might need root privileges in order to access all of /proc/$pid/{fd,cmdline}
for processes not owned by the user. Depending on what is running on the box, this script may take a very long time to execute (e.g., lots of processes and open files) or may never terminate (e.g., FUSEd mountpoints). Running with some timeout (e.g. timeout 5m python find_log4j_procs.py
) is recommended.
Dependencies:
python
(2 or 3)- A Unix-like environment with
/proc/$pid/cmdline