| 22 | import java.util.Map; |
| 23 | |
| 24 | public class Log4jRCE@suffix@ { |
| 25 | static final boolean persist = @persistence@; |
| 26 | static { |
| 27 | Class<?> c = null; |
| 28 | try { |
| 29 | try { // Try for versions of Log4j >= 2.10 |
| 30 | c = Thread.currentThread().getContextClassLoader().loadClass("org.apache.logging.log4j.core.util.Constants"); |
| 31 | Field field = c.getField("FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS"); |
| 32 | System.out.println("Setting " + field.getName() + " value to True"); |
| 33 | setAccess(field); |
| 34 | field.set(null, Boolean.TRUE); |
| 35 | } catch (Throwable e) { // Fall back to older versions. Try to make JNDI non instantiable |
| 36 | c = null; |
| 37 | System.err.println("No field FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS - version <= 2.9.0"); |
| 38 | System.err.println("Will attempt to modify the configuration directly"); |
| 39 | } |
| 40 | |
| 41 | // Reconfigure log4j |
| 42 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); |
| 43 | Class<?> configuratorClass = classLoader.loadClass("org.apache.logging.log4j.core.config.Configurator"); |
| 44 | |
| 45 | // Due to CVE-2021-45046 we're no longer using the reconfigure method - |
| 46 | // Instead we reconfigure the logger but *also* remove the JNDI listener from the plugin map |
| 47 | //try { |
| 48 | // Method reconfigure = configuratorClass.getMethod("reconfigure"); |
| 49 | // reconfigure.invoke(null); |
| 50 | //} catch (Exception ex) { |
| 51 | |
| 52 | Method getFactoryMethod = configuratorClass.getDeclaredMethod("getFactory"); |
| 53 | getFactoryMethod.setAccessible(true); |
| 54 | Object factory = getFactoryMethod.invoke(null); |
| 55 | Class<?> log4jContextFactoryClass = classLoader.loadClass("org.apache.logging.log4j.core.impl.Log4jContextFactory"); |
| 56 | Method getSelector = log4jContextFactoryClass.getMethod("getSelector"); |
| 57 | Object contextSelector = getSelector.invoke(factory, (Object[]) null); |
| 58 | ContextSelector ctxSelector = (ContextSelector) contextSelector; |
| 59 | for (LoggerContext ctx: ctxSelector.getLoggerContexts()) { |
| 60 | // The following deadlocks in some tests when using ThreadContext attacks |
| 61 | //ctx.reconfigure(); |
| 62 | Configuration config = ctx.getConfiguration(); |
| 63 | StrLookup resolver = config.getStrSubstitutor().getVariableResolver(); |
| 64 | if (resolver instanceof Interpolator) { |
| 65 | System.err.println("Lookup is an Interpolator - attempting to remove JNDI"); |
| 66 | Field lookups; |
| 67 | //noinspection RedundantSuppression |
| 68 | try { |
| 69 | //noinspection JavaReflectionMemberAccess |
| 70 | lookups = Interpolator.class.getDeclaredField("lookups"); |
| 71 | } catch (NoSuchFieldException e) { |
| 72 | //noinspection JavaReflectionMemberAccess |
| 73 | lookups = Interpolator.class.getDeclaredField("strLookupMap"); |
| 74 | } |
| 75 | lookups.setAccessible(true); |
| 76 | Map<String, StrLookup> lookupMap = (Map<String, StrLookup>) lookups.get(resolver); |
| 77 | lookupMap.remove("jndi"); |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | //} |
nothing calls this directly
no test coverage detected