advanced
Base-Executable Java Targets¶
Need to test an uninstrumented or base-executable Java target? We'll walk you through how to test base-executable Java targets using Mayhem!
Estimated Time: 15 minutes
By the end of this lesson, you will be able to:
- Build and fuzz a base-executable Java target with an uncaught exception defect.
- Build and fuzz a base-executable Java target with an index out-of-bounds-defect.
Run through the lesson:
See prerequisites before beginning.
-
Download the java-base-executable.tgz and build the
java-base-executable
Docker image, and push it to the specified Docker registry:docker build -f Dockerfile -t <DOCKERHUB_USERNAME>/java-base-executable . docker push <DOCKERHUB_USERNAME>/java-base-executable
docker build -f Dockerfile -t $MAYHEM_DOCKER_REGISTRY/forallsecure/java-base-executable . docker push $MAYHEM_DOCKER_REGISTRY/forallsecure/java-base-executable
-
Execute a Mayhem run on the
java-base-executable
Docker image using either the Mayhem UI or Mayhem CLI with the following Mayhemfile:1 2 3 4 5 6 7 8
image: <DOCKERHUB_USERNAME>/java-base-executable:latest duration: 120 project: mayhem-examples target: java-base-executable cmds: - cmd: /usr/bin/MayhemIt.jar @@ env: MFUZZ_JAVA: '1'
1 2 3 4 5 6 7 8
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/java-base-executable:latest duration: 120 project: mayhem-examples target: java-base-executable cmds: - cmd: /usr/bin/MayhemIt.jar @@ env: MFUZZ_JAVA: '1'
You will need the following:
- Docker installed.
- A valid Internet connection (for pulling Docker Hub base images)
One Click Testing¶
Click on the button below to start testing a base-executable Java target! Click Next until you reach the final confirmation page and then hit Start Run!
You should see a Run page similar to the following:
Now that you've seen Mayhem testing a base-executable Java target, let's walk through end-to-end how the base-executable Java target was built!
Testing a Standalone Java Target¶
File: java-base-executable.tgz
Download and extract the above java-base-executable.tgz
and take a look at the following bugged MayhemIt.java
program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Here we see that various java libraries have been imported to support the file handling in the main
function, and if the input test case reads as "bug", the program crashes due to an uncaught exception defect.
Let's now take a look at how the java-base-executable
target will be built. Looking at the associated Dockerfile
we can see the following build process:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
- Line 1: The
amazoncorretto:8
base image is imported to gather the necessary java dependencies. - Line 2: The
MayhemIt.java
source file is copied over into the Docker container. - Lines 5-11: The
MayhemIt.jar
file is compiled using thejavac
compiler. - Line 14: The executable
/usr/bin/MayhemIt.jar
is set as the default executable for the resulting Docker image.
Note
We should clarify that in order to execute the MayhemIt.jar
in the container, we need to run java -jar /usr/bin/MayhemIt.jar
to execute the jar file in a JVM; however, when executing a Mayhem run for the MayhemIt.jar
file, we enable the MFUZZ_JAVA
environment variable by setting the value to 1
, which instructs Mayhem to execute the the jar file in Mayhem's JVM during the run. Therefore, it is not necessary to specify java -jar
in the CMD
invocation for a Mayhemfile.
Next, we need to build and push the resulting Docker image to the Docker Hub registry using the docker build
and docker push
commands.
Next, we need to build and push the resulting Docker image to the Mayhem server using the docker build
and docker push
commands, where $MAYHEM_DOCKER_REGISTRY
represents the URL of the private Mayhem Docker registry.
docker build -f Dockerfile -t <DOCKERHUB_USERNAME>/java-base-executable .
docker push <DOCKERHUB_USERNAME>/java-base-executable
docker build -f Dockerfile -t $MAYHEM_DOCKER_REGISTRY/forallsecure/java-base-executable .
docker push $MAYHEM_DOCKER_REGISTRY/forallsecure/java-base-executable
Info
You can use the mayhem login
command to find your internal Mayhem Docker Registry URL and run the following command to set the DOCKER_REGISTRY
environment variable, like so:
export DOCKER_REGISTRY=tutorial.forallsecure.com:5000
DOCKER_REGISTRY
environment variable for your specific Mayhem Docker Registry URL.
Upon successfully pushing the newly created Docker image to the public Docker Hub registry, create a new run via the Mayhem UI and search for the <DOCKERHUB_USERNAME>/java-base-executable
Docker image. Confirm that your Mayhemfile
looks similar to the following:
Upon successfully pushing the newly created Docker image to the private Mayhem Docker Registry, create a new run via the Mayhem UI and search for the forallsecure/java-base-executable
Docker image. Confirm that your Mayhemfile
looks similar to the following:
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 6 7 8 |
|
Now just click Next until you reach the final confirmation page of the create new run flow and hit Start Run to execute your Mayhem run! You should see a Run page similar to the following:
Congratulations! You just fuzzed a base-executable Java target with Mayhem!
⚡ Real World Exercise: Building and Testing the mayhemit-out-of-bounds
Base-Executable Java Target¶
Now that you know how to build and test a Java target with an uncaught exception defect, let's see if you can modify the source code to use an index out-of-bounds defect instead.
Files: mayhemit-out-of-bounds-unsolved.zip
Instructions:
-
Modify the
MayhemIt.java
source code to set a max length constraint and implement the corresponding index out-of-bounds defect:1 2 3 4 5 6 7 8 9
if (input.length() >= 3 && input.length() < 5) { if (input.charAt(0) == 'b') { if (input.charAt(1) == 'u') { if (input.charAt(2) == 'g') { char x = input.charAt(10); } } } }
-
Rebuild the
Dockerfile
using thedocker build
command and tag the resulting Docker image as<DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds
. - Push the
<DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds
Docker image to the public Docker Hub registry using thedocker tag
anddocker push
commands. - Fuzz the
<DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds
Docker image using either the Mayhem UI or Mayhem CLI. Make sure to set the associatedMayhemfile
accordingly.
- Rebuild the
Dockerfile
using thedocker build
command and tag the resulting Docker image as$MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds
. - Push the
$MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds
Docker image to the private Mayhem Docker registry using thedocker tag
anddocker push
commands. - Test the
$MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds
Docker image using either the Mayhem UI or Mayhem CLI. Make sure to set the associatedMayhemfile
accordingly.
🔍 Review It! Building and Testing the mayhemit-out-of-bounds
Base-Executable Java Target¶
Solution
Solution: mayhemit-out-of-bounds-solved.zip
First things first, you needed to add the max length constraint input.length() < 5
and the erroneous call for input.charAt(10)
to the main
function so that when the main
function is fuzzed, the input test case "bug" will trigger the corresponding index out-of-bounds error.
Note
We set the condition input.length() >= 3 && input.length() < 5
in order to ensure that no additional out-of-bounds defects would arise. For example, if the condition was just set to input.length() < 5
, then lines 23, 24, and 25 could also result in additional index out-of-bounds errors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Then, you needed to run the docker build
command in the same directory as the Dockerfile
and proceed to tag the resulting Docker image as <DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds
:
Then, you needed to run the docker build
command in the same directory as the Dockerfile
and proceed to tag the resulting Docker image as $MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds
:
docker build -f Dockerfile -t <DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds .
docker build -f Dockerfile -t $MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds .
Next, you had to push the <DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds
Docker image to the public Docker Hub registry:
Next, you had to push the $MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds
Docker image to the private Mayhem Docker registry:
docker push <DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds
docker push $MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds
Alternatively, you could have also used the included Makefile
to easily build and push the resulting Docker image by setting a MAYHEM_DOCKER_REGISTRY
environment variable and running the following commands:
make build
make push
Lastly, you could have executed a Mayhem run on the uploaded <DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds
Docker image using either the Mayhem UI or Mayhem CLI. As long as your Mayhemfile looked similar to the following:
Lastly, you could have executed a Mayhem run on the uploaded $MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds
Docker image using either the Mayhem UI or Mayhem CLI. As long as your Mayhemfile looked similar to the following:
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 6 7 8 |
|
Your final Run page should have looked like the following:
Congratulations! Mayhem found the array out-of-bounds defect that you added! You just built a base-executable Java target from scratch and used Mayhem to detect the vulnerability that you added!
✏️ Summary and Recap¶
In this lesson, you learned how to fuzz base-executable Java targets with Mayhem!
I learned how to...
1. Build and test a base-executable Java target with an uncaught exception defect.
-
The source code should contain the following defect:
1 2 3 4 5 6 7 8
if (input.length() >= 3) { if (input.charAt(0) == 'b') { if (input.charAt(1) == 'u') { if (input.charAt(2) == 'g') { throw new RuntimeException("Made it to the bug!"); } } }
-
Then, to fuzz the base-executable Java target, use the following
Dockerfile
andMayhemfile
to build the Docker image containing the Java program and fuzz it in Mayhem:1 2 3 4 5 6 7 8 9 10 11 12 13 14
FROM fuzzers/jazzer:0.9.1-openjdk11 COPY MayhemIt.java . # Build MayhemIt.jar RUN mkdir -p build && \ javac -d build MayhemIt.java && \ cd build && \ jar cvf MayhemIt.jar * && \ mv MayhemIt.jar /usr/bin/MayhemIt.jar && \ rm -rf build # Set to fuzz! ENTRYPOINT [] CMD [ "/usr/bin/jazzer_driver", "--cp=/usr/bin/MayhemIt.jar", "--target_class=mayhemit.MayhemIt" ]
1 2 3 4 5 6 7 8
image: <DOCKERHUB_USERNAME>/java-base-executable:latest duration: 120 project: mayhem-examples target: java-base-executable cmds: - cmd: /usr/bin/MayhemIt.jar @@ env: MFUZZ_JAVA: '1'
1 2 3 4 5 6 7 8
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/java-base-executable:latest duration: 120 project: mayhem-examples target: java-base-executable cmds: - cmd: /usr/bin/MayhemIt.jar @@ env: MFUZZ_JAVA: '1'
2. Build and fuzz a base-executable Java target with an out-of-bounds-defect.
-
The source code should contain the following defect:
1 2 3 4 5 6 7 8 9
if (input.length() > 3 && input.length() < 5) { if (input.charAt(0) == 'b') { if (input.charAt(1) == 'u') { if (input.charAt(2) == 'g') { char x = input.charAt(10); } } } }
-
Then, to fuzz the base-executable Java target, use the following
Dockerfile
andMayhemfile
to build the Docker image containing the Java program and fuzz it in Mayhem:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
FROM amazoncorretto:8 COPY MayhemIt.java . # Build MayhemIt.jar RUN mkdir -p build && \ javac -d build MayhemIt.java && \ cd build && \ jar --create --file MayhemIt.jar --main-class mayhemit.MayhemIt * && \ chmod u+x MayhemIt.jar && \ mv MayhemIt.jar /usr/bin/MayhemIt.jar && \ rm -rf build # Set to fuzz! ENTRYPOINT [] CMD [ "/usr/bin/MayhemIt.jar", "@@" ]
1 2 3 4 5 6 7 8
image: <DOCKERHUB_USERNAME>/java-base-executable-mayhemit-out-of-bounds:latest duration: 120 project: mayhem-examples target: mayhemit-out-of-bounds cmds: - cmd: /usr/bin/MayhemIt.jar @@ env: MFUZZ_JAVA: '1'
1 2 3 4 5 6 7 8
image: $MAYHEM_DOCKER_REGISTRY/java-base-executable-mayhemit-out-of-bounds:latest duration: 120 project: mayhem-examples target: mayhemit-out-of-bounds cmds: - cmd: /usr/bin/MayhemIt.jar @@ env: MFUZZ_JAVA: '1'