diff options
Diffstat (limited to 'examples/src/main/java/com')
-rw-r--r-- | examples/src/main/java/com/example/Log4jFuzzer.java | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/examples/src/main/java/com/example/Log4jFuzzer.java b/examples/src/main/java/com/example/Log4jFuzzer.java new file mode 100644 index 00000000..41870c9c --- /dev/null +++ b/examples/src/main/java/com/example/Log4jFuzzer.java @@ -0,0 +1,82 @@ +// Copyright 2021 Code Intelligence GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.example; + +import com.code_intelligence.jazzer.api.FuzzedDataProvider; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Core; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.appender.AbstractAppender; +import org.apache.logging.log4j.core.config.Configurator; +import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; +import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder; +import org.apache.logging.log4j.core.config.builder.impl.DefaultConfigurationBuilder; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginAttribute; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; +import org.apache.logging.log4j.core.layout.PatternLayout; +import org.apache.logging.log4j.status.StatusLogger; + +// This fuzzer reproduces the log4j RCE vulnerability CVE-2021-44228. +public class Log4jFuzzer { + private final static Logger log = LogManager.getLogger(Log4jFuzzer.class.getName()); + + public static void fuzzerTestOneInput(FuzzedDataProvider data) { + log.error(data.consumeRemainingAsString()); + } + + public static void fuzzerInitialize() { + // Install a logger that constructs the log message, but never prints it. + // This noticeably increases the fuzzing performance + DefaultConfigurationBuilder configBuilder = new DefaultConfigurationBuilder(); + configBuilder.setPackages(FuzzingAppender.class.getPackage().getName()); + AppenderComponentBuilder fuzzingAppender = + configBuilder.newAppender("nullAppender", "FuzzingAppender"); + configBuilder.add(fuzzingAppender); + RootLoggerComponentBuilder rootLogger = configBuilder.newRootLogger(); + rootLogger.add(configBuilder.newAppenderRef("nullAppender")); + configBuilder.add(rootLogger); + Configurator.reconfigure(configBuilder.build()); + + // Disable logging of exceptions caught in log4j itself. + StatusLogger.getLogger().reset(); + StatusLogger.getLogger().setLevel(Level.OFF); + } + + @Plugin( + name = "FuzzingAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE) + public static class FuzzingAppender extends AbstractAppender { + protected FuzzingAppender(String name) { + super(name, null, PatternLayout.createDefaultLayout(), true); + } + + @PluginFactory + public static FuzzingAppender createAppender(@PluginAttribute("name") String name) { + return new FuzzingAppender(name); + } + + @Override + public void append(LogEvent event) { + try { + getLayout().toByteArray(event); + } catch (Exception ignored) { + // Prevent exceptions from being logged to stderr. + } + } + } +} |