diff options
Diffstat (limited to 'examples/src/main/java/com')
8 files changed, 158 insertions, 22 deletions
diff --git a/examples/src/main/java/com/example/BatikTranscoderFuzzer.java b/examples/src/main/java/com/example/BatikTranscoderFuzzer.java new file mode 100644 index 00000000..cdd22163 --- /dev/null +++ b/examples/src/main/java/com/example/BatikTranscoderFuzzer.java @@ -0,0 +1,44 @@ +// Copyright 2023 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 java.io.*; +import org.apache.batik.transcoder.TranscoderException; +import org.apache.batik.transcoder.TranscoderInput; +import org.apache.batik.transcoder.TranscoderOutput; +import org.apache.batik.transcoder.image.JPEGTranscoder; + +public class BatikTranscoderFuzzer { + public static void fuzzerTestOneInput(FuzzedDataProvider data) throws IOException { + String host = data.consumeRemainingAsString(); + + byte[] svg = + ("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" >\n" + + "<image width=\"50\" height=\"50\" xlink:href=\"https://" + host + "/\"></image>\n" + + "</svg>") + .getBytes(); + + // Convert SVG to JPEG + try { + JPEGTranscoder transcoder = new JPEGTranscoder(); + TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(svg)); + TranscoderOutput output = new TranscoderOutput(new ByteArrayOutputStream()); + transcoder.transcode(input, output); + } catch (TranscoderException | IllegalArgumentException e) { + // Ignored + } + } +} diff --git a/examples/src/main/java/com/example/CommonsTextFuzzer.java b/examples/src/main/java/com/example/CommonsTextFuzzer.java new file mode 100644 index 00000000..32b309d5 --- /dev/null +++ b/examples/src/main/java/com/example/CommonsTextFuzzer.java @@ -0,0 +1,28 @@ +// Copyright 2023 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.commons.text.StringSubstitutor; + +public class CommonsTextFuzzer { + public static void fuzzerTestOneInput(FuzzedDataProvider data) { + try { + StringSubstitutor.createInterpolator().replace(data.consumeAsciiString(20)); + } catch ( + java.lang.IllegalArgumentException | java.lang.ArrayIndexOutOfBoundsException ignored) { + } + } +} diff --git a/examples/src/main/java/com/example/ExampleFuzzerWithNative.java b/examples/src/main/java/com/example/ExampleFuzzerWithNative.java index b9a13e24..90639deb 100644 --- a/examples/src/main/java/com/example/ExampleFuzzerWithNative.java +++ b/examples/src/main/java/com/example/ExampleFuzzerWithNative.java @@ -19,7 +19,7 @@ import com.github.fmeum.rules_jni.RulesJni; public class ExampleFuzzerWithNative { static { - String native_lib = System.getProperty("jazzer.native_lib"); + String native_lib = System.getenv("EXAMPLE_NATIVE_LIB"); RulesJni.loadLibrary(native_lib, ExampleFuzzerWithNative.class); } diff --git a/examples/src/main/java/com/example/ExampleKotlinFuzzer.kt b/examples/src/main/java/com/example/ExampleKotlinFuzzer.kt new file mode 100644 index 00000000..eb1aea8f --- /dev/null +++ b/examples/src/main/java/com/example/ExampleKotlinFuzzer.kt @@ -0,0 +1,38 @@ +// Copyright 2022 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 com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium + +object ExampleKotlinFuzzer { + + @JvmStatic + fun fuzzerTestOneInput(data: FuzzedDataProvider) { + exploreMe(data.consumeString(8), data.consumeInt(), data.consumeRemainingAsString()) + } + + private fun exploreMe(prefix: String, n: Int, suffix: String) { + if (prefix.findAnyOf(arrayListOf("Fuzz", "Test")) != null) { + if (n >= 2000000) { + if (suffix.startsWith("@")) { + if (suffix.substring(1) == "Jazzer") { + throw FuzzerSecurityIssueMedium("Jazzer resolved string comparisons in Kotlin") + } + } + } + } + } +} diff --git a/examples/src/main/java/com/example/ExampleKotlinValueProfileFuzzer.kt b/examples/src/main/java/com/example/ExampleKotlinValueProfileFuzzer.kt new file mode 100644 index 00000000..c86824e8 --- /dev/null +++ b/examples/src/main/java/com/example/ExampleKotlinValueProfileFuzzer.kt @@ -0,0 +1,37 @@ +// Copyright 2023 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 com.code_intelligence.jazzer.api.FuzzerSecurityIssueMedium + +object ExampleKotlinValueProfileFuzzer { + + @JvmStatic + fun fuzzerTestOneInput(data: FuzzedDataProvider) { + if (data.consumeInt().compareTo(0x11223344) != 0) { + return + } + if (encrypt(data.consumeLong()).compareTo(5788627691251634856) == 0 && + encrypt(data.consumeLong()).compareTo(6293579535917519017) == 0 + ) { + throw FuzzerSecurityIssueMedium("Jazzer can handle integral comparisons in Kotlin") + } + } + + private fun encrypt(n: Long): Long { + return n.xor(0x1122334455667788) + } +} diff --git a/examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java b/examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java index d704da39..494bff16 100644 --- a/examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java +++ b/examples/src/main/java/com/example/ExampleOutOfMemoryFuzzer.java @@ -14,15 +14,13 @@ package com.example; -import java.util.ArrayList; - public class ExampleOutOfMemoryFuzzer { + public static long[] leak; + public static void fuzzerTestOneInput(byte[] input) { - ArrayList<Byte> bytes = new ArrayList<>(); - int pos = 0; - while (pos >= 0 && pos < input.length) { - bytes.add(input[pos]); - pos += input[pos] + 1; + if (input.length == 0) { + return; } + leak = new long[Integer.MAX_VALUE]; } } diff --git a/examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java b/examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java index b027de5b..109db94e 100644 --- a/examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java +++ b/examples/src/main/java/com/example/ExamplePathTraversalFuzzerHooks.java @@ -24,6 +24,8 @@ import java.nio.file.Path; import java.nio.file.Paths; public class ExamplePathTraversalFuzzerHooks { + private static final String publicFilesRootPath = "/app/upload/"; + @MethodHook(type = HookType.BEFORE, targetClassName = "java.io.File", targetMethod = "<init>", targetMethodDescriptor = "(Ljava/lang/String;)V") public static void @@ -36,7 +38,7 @@ public class ExamplePathTraversalFuzzerHooks { // Invalid paths are correctly rejected by the application. return; } - if (!normalizedPath.startsWith(ExamplePathTraversalFuzzer.publicFilesRootPath)) { + if (!normalizedPath.startsWith(publicFilesRootPath)) { // Simply throwing an exception from here would not work as the calling code catches and // ignores all Throwables. Instead, use the Jazzer API to report a finding from a hook. Jazzer.reportFindingFromHook(new FuzzerSecurityIssueHigh( diff --git a/examples/src/main/java/com/example/MazeFuzzer.java b/examples/src/main/java/com/example/MazeFuzzer.java index 9d3448c7..beab610e 100644 --- a/examples/src/main/java/com/example/MazeFuzzer.java +++ b/examples/src/main/java/com/example/MazeFuzzer.java @@ -17,6 +17,7 @@ package com.example; import com.code_intelligence.jazzer.api.Consumer3; import com.code_intelligence.jazzer.api.Jazzer; import java.util.Arrays; +import java.util.Objects; import java.util.stream.Collectors; // A fuzz target that shows how manually informing the fuzzer about important state can make a fuzz @@ -60,7 +61,7 @@ public final class MazeFuzzer { // This is the key line that makes this fuzz target work: It instructs the fuzzer to track // every new combination of x and y as a new feature. Without it, the fuzzer would be // completely lost in the maze as guessing an escaping path by chance is close to impossible. - Jazzer.exploreState(hash(x, y), 0); + Jazzer.exploreState((byte) Objects.hash(x, y), 0); if (REACHED_FIELDS[y][x] == ' ') { // Fuzzer reached a new field in the maze, print its progress. REACHED_FIELDS[y][x] = '.'; @@ -69,18 +70,6 @@ public final class MazeFuzzer { }); } - // Hash function with good mixing properties published by Thomas Mueller - // under the terms of CC BY-SA 4.0 at - // https://stackoverflow.com/a/12996028 - // https://creativecommons.org/licenses/by-sa/4.0/ - private static byte hash(byte x, byte y) { - int h = (x << 8) | y; - h = ((h >> 16) ^ h) * 0x45d9f3b; - h = ((h >> 16) ^ h) * 0x45d9f3b; - h = (h >> 16) ^ h; - return (byte) h; - } - private static class TreasureFoundException extends RuntimeException { TreasureFoundException(byte[] commands) { super(renderPath(commands)); |