Creating Small Containers for Penetration Testing
Smaller is better for scalability!
Introduction
Docker containers can be a burden when the image gets too large.
By default, the Golang Docker container at its smallest is 123 MB. While seemingly small, this can result in annoying latency and slowness when deploying new tooling at scale.
In this article I show you how to create small containers that use up to date tools. I'll use the tool waybackurls from tomnomnom as an example.
Traditional Dockerfile Creation
Typically, we would create a Dockerfile that looks like the following for our desired Golang tool.
# This is our base container
FROM golang:1-alpine
# Installing git and waybackurls within the container
RUN apk update && \
apk add git && \
go get github.com/tomnomnom/waybackurls
# Setting our entrypoint so we can easily use the new tool
ENTRYPOINT ["waybackurls"]
While this works perfectly, our resulting Docker image is 130 MB. We need to explore other features of Docker to create a smaller container.
Dockerfile as builder
One of the most challenging things about building images is keeping the image size down. Each instruction in the Dockerfile adds a layer to the image, and you need to remember to clean up any artifacts you don’t need before moving on to the next layer.
In Docker version 17.05 and later, we now use the as builder
feature in our Dockerfile to keep the image small. This feature is often referred to as multi-stage builds. It allows us to use an intermediary container to build an up to date version of our Golang tool and then move it into a much smaller container.
An example of a multi-stage Dockerfile:
# Using the golang alpine container as an build enviornment
FROM golang:1.13-alpine3.10 as builder
# Adding git and installing our tool from source
RUN apk --no-cache add git
RUN go get github.com/tomnomnom/waybackurls; exit 0
WORKDIR /go/src/github.com/tomnomnom/waybackurls
RUN go install ./...
#Spinning up a new container that is much smaller
FROM alpine:latest
RUN apk --no-cache add ca-certificates
# Moving our previously built tool into the new container
COPY --from=builder /go/bin/waybackurls /bin/waybackurls
The resulting container is now only 13.5 MB in size. That is big improvement!
Conclusion
You'll find that this is extremely useful when creating containers used for every day penetration testing work. Small containers help us scale our operations and continuously engage with new tooling.
References
This feature of Docker has quite a lot more to it that wasn't mentioned here.
Learn more: Docker multi-stage builds
Become a ninja: Advanced multi-stage builds
Continuous Human & Automated Security
The Expert-Driven Offensive
Security Platform
Continuously monitor your attack surface with advanced change detection. Upon change, testers and systems perform security testing. You are alerted and assisted in remediation efforts all contained in a single security application, the Sprocket Platform.
Expert-Driven Offensive Security Platform
- Attack Surface Management
- Continuous Penetration Testing
- Adversary Simulations