advanced
Base-Executable Go Targets¶
Got an uninstrumented or base-executable Go target? In this lesson, we'll walk through how to compile base-executable Go targets and fuzz them in Mayhem!
Estimated Time: 15 minutes
By the end of this lesson, you will be able to:
- Compile and fuzz a base-executable Go target with a reachable assertion defect.
- Compile and fuzz a base-executable Go target with an index-out-of-bounds defect.
Run through the lesson:
See prerequisites before beginning.
-
Download the go-base-executable.tgz and build the
go-base-executable
Docker image, and push it to the specified Docker registry:docker build -f Dockerfile -t <DOCKERHUB_USERNAME>/go-base-executable . docker push <DOCKERHUB_USERNAME>/go-base-executable
docker build -f Dockerfile -t $MAYHEM_DOCKER_REGISTRY/forallsecure/go-base-executable . docker push $MAYHEM_DOCKER_REGISTRY/forallsecure/go-base-executable
-
Execute a Mayhem run on the
go-base-executable
Docker image using either the Mayhem UI or Mayhem CLI with the following Mayhemfile:1 2 3 4 5 6
image: <DOCKERHUB_USERNAME>/go-base-executable:latest duration: 90 project: mayhem-examples target: go-base-executable cmds: - cmd: /go/mayhemit @@
1 2 3 4 5 6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/go-base-executable:latest duration: 90 project: mayhem-examples target: go-base-executable cmds: - cmd: /go/mayhemit @@
You will need the following:
- Docker installed.
- A valid Internet connection (for pulling Docker Hub base images)
One Click Testing¶
Click on the following button and hit Start Run at the end of the Create New Run flow to get a quick start on testing a base-executable Go target! No need to configure anything, as the underlying Mayhemfile
has already been configured for you!
Once the Mayhem run initiates, you should see a Run page similar to the following:
Awesome! Now that you've seen Mayhem testing a base-executable Go target, let's now walk through how to compile and fuzz the go-base-executable
target that you just executed a Mayhem run for!
Building and Testing a Base-Executable Go Target¶
File: go-base-executable.tgz
Download and extract the above go-base-executable.tgz
and take a look at the following bugged mayhemit.go
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 34 |
|
Here we see that there are two functions of interest: main
and mayhemit
. The main
function handles the file input to the program and invokes the mayhemit
function on line 33 to check if the input test case reads "bug". If so, the program crashes via a reachable assertion error caused by the panic()
function on line 16.
Let's now take a look at how this program will ultimately be compiled. The associated Dockerfile
for the go-base-executable
target shows the following:
1 2 3 4 5 6 7 |
|
- Line 1: The
golang:1.13.3-buster
base image is imported to provide the necessary go dependencies. - Line 2: The
mayhemit.go
source code is copied over into the Docker container. - Line 3: The
go build
command is used to compile themayhemit.go
source files to themayhemit
executable. - Line 7: The
/go/mayhemit @@
executable is set as the default executable for the resulting Docker container.
Then, make sure you're within the go-base-executable
folder and use the following docker
commands to build the resulting <DOCKERHUB_USERNAME>/go-base-executable
Docker image and push it to the Docker Hub registry:
Then, make sure you're within the go-base-executable
folder and use the following docker
commands to build the resulting forallsecure/go-base-executable
Docker image and push it to the Mayhem Docker Registry:
docker build -f Dockerfile -t <DOCKERHUB_USERNAME>/go-base-executable .
docker push <DOCKERHUB_USERNAME>/go-base-executable
docker build -f Dockerfile -t $MAYHEM_DOCKER_REGISTRY/forallsecure/go-base-executable .
docker push $MAYHEM_DOCKER_REGISTRY/forallsecure/go-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.
Next, go to the Mayhem UI and search for the <DOCKERHUB_USERNAME>/go-base-executable
Docker image. Confirm that your Mayhemfile
looks similar to the following:
Next, go to the Mayhem UI and search for the forallsecure/go-base-executable
Docker image. Confirm that your Mayhemfile
looks similar to the following:
1 2 3 4 5 6 |
|
1 2 3 4 5 6 |
|
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:
You should now see that Mayhem was able to find the underlying reachable assertion defect! Congratulations on compiling and testing your base-executable Go target!
⚡ Real World Exercise: Building and Testing the mayhemit-out-of-bounds
Base-Executable Go Target¶
Now that you know how to build and test an base-executable Go target, let's see if you can modify the source code to use an index out-of-bounds error instead of a reachable assertion defect!
Files: mayhemit-out-of-bounds-unsolved.zip
Instructions:
-
Modify the
mayhemit.go
source code and add the following max length constraint and corresponding index out-of-bounds defect:1 2 3 4 5 6 7 8 9 10 11 12 13 14
func mayhemit(bytes []byte) int { content := string(bytes) if len(content) >= 3 && len(content) < 5 { if string(content[0]) == "b" { if string(content[1]) == "u" { if string(content[2]) == "g" { var x = content[10] fmt.Println(x) } } } } return 0 }
-
Rebuild the Dockerfile using the
docker build
command and tag the resulting Docker image as<DOCKERHUB_USERNAME>/go-base-executable-mayhemit-out-of-bounds
. - Push the
<DOCKERHUB_USERNAME>/go-base-executable-mayhemit-out-of-bounds
Docker image to the internal Mayhem Docker registry using thedocker push
command. - Fuzz the
<DOCKERHUB_USERNAME>/go-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 the
docker build
command and tag the resulting Docker image asgo-base-executable-mayhemit-out-of-bounds
. - Push the
go-base-executable-mayhemit-out-of-bounds
Docker image to the internal Mayhem Docker registry using thedocker push
command. - Test the
go-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 Go Target¶
Solution
Solution: mayhemit-out-of-bounds-solved.zip
First things first, you needed to add the max length constraint len(content) < 5
and the erroneous call for content[10]
so that when the mayhemit
function is fuzzed, the input test case "bug" will trigger the index out-of-bounds error.
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 34 35 36 37 38 39 40 |
|
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>/go-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/go-base-executable-mayhemit-out-of-bounds
:
docker build -f Dockerfile -t <DOCKERHUB_USERNAME>/go-base-executable-mayhemit-out-of-bounds .
docker build -f Dockerfile -t $MAYHEM_DOCKER_REGISTRY/go-base-executable-mayhemit-out-of-bounds .
Next, you had to tag and push the <DOCKERHUB_USERNAME>/go-base-executable-mayhemit-out-of-bounds
Docker image to the public Docker Hub registry.
Next, you had to tag and push the $MAYHEM_DOCKER_REGISTRY/go-base-executable-mayhemit-out-of-bounds
Docker image to the private Mayhem Docker registry.
docker push <DOCKERHUB_USERNAME>/go-base-executable-mayhemit-out-of-bounds
docker push $MAYHEM_DOCKER_REGISTRY/go-base-executable-mayhemit-out-of-bounds
Note
Here we uploaded the go-base-executable-mayhemit-out-of-bounds
Docker image to our tutorial.forallsecure.com
Mayhem deployment, specifically at the private Mayhem Docker registry located at port 5000
. For your Docker image to have successfully uploaded, you would have had to adjust the URL for your Mayhem deployment Docker registry accordingly.
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>/go-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 go-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 |
|
1 2 3 4 5 6 |
|
Your final Run page should have looked like the following:
Congratulations! Mayhem found the index out-of-bounds defect that you added! You just built an base-executable Go target from scratch and added a bug that was detected in Mayhem!
✏️ Summary and Recap¶
In this lesson, you learned how to compile base-executable Go targets and fuzz them in Mayhem!
I learned how to...
1. Compile and test a base-executable Go target with a reachable assertion defect.
-
The source code should contain the following defect:
1 2 3 4 5 6 7 8 9 10 11 12 13
func mayhemit(bytes []byte) int { content := string(bytes) if len(content) >= 3 { if string(content[0]) == "b" { if string(content[1]) == "u" { if string(content[2]) == "g" { panic("found a bug!") } } } } return 0 }
-
Then, to fuzz the base-executable Go target, use the following
Dockerfile
andMayhemfile
to build the Docker image containing the Go executable and fuzz it in Mayhem, respectively:1 2 3 4 5 6 7
FROM golang:1.13.3-buster as go-target COPY mayhemit.go . RUN go build -o mayhemit -a mayhemit.go # Set to fuzz! ENTRYPOINT [] CMD /go/mayhemit @@
1 2 3 4 5 6
image: <DOCKERHUB_USERNAME>/go-base-executable:latest duration: 90 project: mayhem-examples target: go-base-executable cmds: - cmd: /go/mayhemit @@
1 2 3 4 5 6
image: $MAYHEM_DOCKER_REGISTRY/forallsecure/go-base-executable:latest duration: 90 project: mayhem-examples target: go-base-executable cmds: - cmd: /go/mayhemit @@
2. Compile and fuzz a base-executable Go target with an index-out-of-bounds defect.
-
The source code should contain the following defect:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
func mayhemit(bytes []byte) int { content := string(bytes) if len(content) >= 3 && len(content) < 5 { if string(content[0]) == "b" { if string(content[1]) == "u" { if string(content[2]) == "g" { var x = content[10] fmt.Println(x) } } } } return 0 }
-
Then, to compile and fuzz the base-executable Go target, use the following
Dockerfile
andMayhemfile
to build the Docker image containing the Go executable and fuzz it in Mayhem, respectively:1 2 3 4 5 6 7
FROM golang:1.13.3-buster as go-target COPY mayhemit.go . RUN go build -o mayhemit -a mayhemit.go # Set to fuzz! ENTRYPOINT [] CMD /go/mayhemit @@
1 2 3 4 5 6
image: <DOCKERHUB_USERNAME>/go-base-executable-mayhemit-out-of-bounds:latest duration: 90 project: mayhem-examples target: go-base-executable-mayhemit-out-of-bounds cmds: - cmd: /go/mayhemit @@
1 2 3 4 5 6
image: $MAYHEM_DOCKER_REGISTRY/go-base-executable-mayhemit-out-of-bounds:latest duration: 90 project: mayhem-examples target: go-base-executable-mayhemit-out-of-bounds cmds: - cmd: /go/mayhemit @@