Skip to content

Commit

Permalink
Added reload4j md5 hashes for accurate safe version detection
Browse files Browse the repository at this point in the history
  • Loading branch information
xeraph committed Feb 13, 2022
1 parent 2c0a238 commit c10955b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 21 deletions.
33 changes: 14 additions & 19 deletions src/main/java/com/logpresso/scanner/Detector.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,6 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List<String> p
boolean foundJmsSink = false;
boolean foundChainsaw = false;

// log4j1 md5
String log4j1CategoryMd5 = null;
String log4j1MdcMd5 = null;
String log4j1NdcMd5 = null;

// logback class
boolean foundJndiUtil = false;
boolean foundEnvUtil = false;
Expand All @@ -250,6 +245,10 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List<String> p
List<String> log4j2Md5Targets = VersionClassifier.getLog4j2Md5Entries();
Map<String, String> log4j2Md5Map = new HashMap<String, String>();

// for log4j1 md5 detection
List<String> log4j1Md5Targets = VersionClassifier.getLog4j1Md5Entries();
Map<String, String> log4j1Md5Map = new HashMap<String, String>();

try {
while (true) {
ZipEntry entry = it.getNextEntry();
Expand All @@ -258,9 +257,9 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List<String> p

InputStream is = it.getNextInputStream();

String md5EntryName = getMd5EntryName(log4j2Md5Targets, entry.getName());
if (md5EntryName != null)
log4j2Md5Map.put(md5EntryName, VersionClassifier.md5(is));
String log4j2Md5EntryName = getMd5EntryName(log4j2Md5Targets, entry.getName());
if (log4j2Md5EntryName != null)
log4j2Md5Map.put(log4j2Md5EntryName, VersionClassifier.md5(is));

if (entry.getName().equals(LOG4J_CORE_POM_PROPS))
log4j2Version = loadLog4j2Version(is);
Expand All @@ -272,6 +271,10 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List<String> p
shadedJndiLookupPaths.add(entry.getName());

if (config.isScanForLog4j1()) {
String log4j1Md5EntryName = getMd5EntryName(log4j1Md5Targets, entry.getName());
if (log4j1Md5EntryName != null)
log4j1Md5Map.put(log4j1Md5EntryName, VersionClassifier.md5(is));

if (entry.getName().equals(LOG4J_12_CORE_POM_PROPS) || entry.getName().equals(RELOAD4J_POM_PROS))
log4j1Version = loadLog4j1Version(is);

Expand All @@ -295,14 +298,6 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List<String> p

if (entry.getName().endsWith(LOG4J_12_JDBC_APPENDER))
foundJdbcAppender = true;

if (entry.getName().endsWith("/log4j/Category.class")) {
log4j1CategoryMd5 = VersionClassifier.md5(is);
} else if (entry.getName().endsWith("/log4j/MDC.class")) {
log4j1MdcMd5 = VersionClassifier.md5(is);
} else if (entry.getName().endsWith("/log4j/NDC.class")) {
log4j1NdcMd5 = VersionClassifier.md5(is);
}
}

if (config.isScanForLogback()) {
Expand Down Expand Up @@ -359,7 +354,7 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List<String> p

if (log4j1Found) {
if (log4j1Version == null)
log4j1Version = VersionClassifier.classifyLog4j1Version(log4j1CategoryMd5, log4j1MdcMd5, log4j1NdcMd5);
log4j1Version = VersionClassifier.classifyLog4j1Version(log4j1Md5Map);

boolean vulnerable = true;
if (log4j1Version != null) {
Expand Down Expand Up @@ -409,8 +404,8 @@ private DetectResult scanStream(File jarFile, ZipFileIterator it, List<String> p
}
}

private String getMd5EntryName(List<String> log4j2Md5Targets, String entryName) {
for (String s : log4j2Md5Targets) {
private String getMd5EntryName(List<String> md5Targets, String entryName) {
for (String s : md5Targets) {
if (entryName.endsWith(s)) {
int p = entryName.lastIndexOf('/');
if (p > 0)
Expand Down
35 changes: 33 additions & 2 deletions src/main/java/com/logpresso/scanner/VersionClassifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public class VersionClassifier {
log4j1Digests.put("6bac921015bb8300d36df01d0bf1ceb4", "1.2.12");
log4j1Digests.put("ff67193faa9007c0afc57dbc04c983bb", "1.2.15");
log4j1Digests.put("bd5186a7747acdd133105873fbfefdb1", "1.2.16");
log4j1Digests.put("1bd049612eaddf4fe8a8bc3cb2179dbf", "1.2.17");
log4j1Digests.put("e8dedc13853f852f1af6900d2d9c73b3", "1.2.17");
log4j1Digests.put("1bd049612eaddf4fe8a8bc3cb2179dbf", "1.2.17"); // with generics

log4j2RollingFileManagerDigests = new HashMap<String, String>();
log4j2RollingFileManagerDigests.put("66c1b131a623bd368e6d8bebbe16ff0c", "2.0-alpha1");
Expand Down Expand Up @@ -113,6 +114,11 @@ public class VersionClassifier {
jndiManagerDigests.put("e2c6b2691738bb653f1ff6dc4b967a42", "2.17.1");
}

public static List<String> getLog4j1Md5Entries() {
return Arrays.asList("/log4j/Category.class", "/log4j/MDC.class", "/log4j/NDC.class", "/log4j/net/JMSSink.class",
"/log4j/helpers/PatternParser.class", "/log4j/net/SMTPAppender.class");
}

public static List<String> getLog4j2Md5Entries() {
return Arrays.asList("/log4j/core/appender/rolling/RollingFileManager.class", "/log4j/core/config/LoggerConfig.class",
"/log4j/core/appender/AsyncAppender.class", "/log4j/core/lookup/Interpolator.class",
Expand Down Expand Up @@ -151,7 +157,14 @@ private static String detectLog4j2Version(String classFileName, Map<String, Stri
return digests.get(md5);
}

public static String classifyLog4j1Version(String categoryMd5, String mdcMd5, String ndcMd5) {
public static String classifyLog4j1Version(Map<String, String> entryMd5Map) {
String categoryMd5 = entryMd5Map.get("Category.class");
String ndcMd5 = entryMd5Map.get("NDC.class");
String mdcMd5 = entryMd5Map.get("MDC.class");
String jmsSinkMd5 = entryMd5Map.get("JMSSink.class");
String patternParserMd5 = entryMd5Map.get("PatternParser.class");
String smtpAppenderMd5 = entryMd5Map.get("SMTPAppender.class");

if (categoryMd5 == null)
return null;

Expand All @@ -175,6 +188,24 @@ else if (ndcMd5.equals("b5223239f2810943933b54d8ea681763"))
return "1.2.7";
}
} else {
if (jmsSinkMd5 != null && jmsSinkMd5.equals("016dbb16c0d5509c13dad7b483b4e648")) {
return "1.2.18.0";
} else if (smtpAppenderMd5 != null && smtpAppenderMd5.equals("3bff44742e88190fa9f200826af64d9c")) {
return "1.2.18.3";
} else if (smtpAppenderMd5 != null && smtpAppenderMd5.equals("7f938ce7dc9df0389d38d3ca40296015")) {
return "1.2.18.4";
} else if (mdcMd5 != null && mdcMd5.equals("8da7e55001d400655635bbbbc3381ba5")) {
if (patternParserMd5 != null && patternParserMd5.equals("619e0839a36f541a49016e42c99db710")) {
return "1.2.18.1";
} else if (patternParserMd5 != null && patternParserMd5.equals("4848724cd715a2e855d1413a1e15c7c3")) {
return "1.2.18.2";
} else {
return log4j1Digests.get(categoryMd5);
}
} else if (mdcMd5 != null && mdcMd5.equals("4bb635421ade486060d68134de4ac74e")) {
return "1.2.19";
}

return log4j1Digests.get(categoryMd5);
}

Expand Down

0 comments on commit c10955b

Please sign in to comment.