Before we dive in, I just want to say that as a blue teamer,
having a high‑level understanding of automation is crucial.
If security alerting is done correctly,
there's usually going to be automation involved.
For you to fully investigate alerts,
it is pivotal to understand the context in which they are generated.
We are going to continue our automation journey within the script.
I'm not going to rehash the summary because we just saw
it within the previous workflow file.
Much of the assumptions have already been covered,
but if needed, please pause the video and look over them again.
One important thing to highlight is that this script
expects the following path convention,
and this is shared with the previous docker‑scan script that
we saw to fuel the pull request process.
Now we see the inputs.
Docker tags are a way to version Docker images.
In this demo, we build Docker images with the "latest" tag,
and similar, the DOCKERHUB_USER.
In this demo, it's simply zachroofsec.
The functions, we'll come back to this a little bit later.
All right, the main logic.
First we do some miscellaneous Git setup.
Then we start to iterate through the Docker configurations.
This uses the path assumptions that we just went over.
First, we get the absolute path for the Docker configurations.
Then we get the Docker Registry repo name from our path convention.
Then we start generating some Docker image names.
We download the remote image within the Docker Registry
during the integrity checking process.
We'll explore this more in a little bit.
Here, we build the Docker image.
Let's do a high‑level overview of the tampering checks within this script.
If an attacker changes the registry's Docker image,
they subvert all preexisting controls.
This includes the Trivy scan, the pull request approval process,
pretty much everything.
We need to ensure that a malicious Docker image has not been placed
within the Docker Registry. For additional tampering checks, you should
use something called Docker Content Trust.
However, that's outside of the scope of this tutorial.
Let's start with our tampering check logic.
We first need to deduce, is this the first build of the Docker image?
If so, we won't check for image tampering because there
isn't an image in the remote registry.
So let's assume this is the first run. We use Google's
container‑diff tool to generate the Docker image signature. On
subsequent image builds, we'll validate that the remote Docker
image signature matches the signature.
This is an example of what the signature looks like.
Let's go to the function generate_signature_and_upload_image.
As we just stated, we generate the Docker image signature.
Then we tag the Docker image and push it to the registry.
Now, we need to commit the signature into the main branch.
Let's check out that code. We are just doing some very simple git
operations here. Obviously, this is the first time building this Docker
image, so we skip the integrity checks, and then we just continue on to
the next set of Docker configurations.
Remember, we are within a for loop that is iterating through all of
our Docker configurations and building those images.
This point in the execution path,
this is not the first time this Docker image has been built.
Thus, we need to check for image tampering.
First we download the remote version of the Docker image.
Then we get the signature of the remote Docker image. Then we get the
signature of the Docker image that was previously built.
Remember, we can get this within the Git repository.
The remote signature does not match the previous build signature.
Docker image tampering might be present within Docker Hub.
So after that we just try to do some analysis that
might help within an investigation.
First, we ensure that Trivy does not scan the cached image.
For simplicity, we're going to use our previous scan settings.
In other words,
we're going to copy the same severity values and the ignored unfixed flag.
We are doing this so the output isn't as verbose.
However, if you are doing this within a production environment,
my suggestion would be to remove these flags. For an
investigation, you would want to see all output and all
vulnerabilities that are within the image.
Next, we use Google's container‑diff tool to look at the differences
between the Docker images. More on this later.
At this point, we're not going to upload the new Docker image.
We're just going to keep everything the way it is, exit
out of this script, and alert our SIEM.
A forensic investigation really needs to occur.
If this portion of the script is executed,
then woo‑hoo! the signatures do match and no Docker image tampering is present.
At that point,
we simply generate the signature and upload the Docker image and
then commit everything into source control.