WEBVTT

00:00:01.040 --> 00:00:03.860
We are back in the pull request view within the GitHub UI,

00:00:04.240 --> 00:00:06.640
I'm going to go ahead and merge this pull request so

00:00:06.640 --> 00:00:08.490
we can see the workflow in action.

00:00:08.490 --> 00:00:10.000
Because I'm an administrator,

00:00:10.000 --> 00:00:12.730
we don't have to go through the whole approval process.

00:00:12.740 --> 00:00:14.260
I can just go ahead and merge this.

00:00:14.640 --> 00:00:15.050
Nice!

00:00:15.050 --> 00:00:17.610
It looks like everything worked out correctly.

00:00:17.610 --> 00:00:20.550
At this point, let's see if the workflow was triggered.

00:00:24.540 --> 00:00:25.860
We see it going.

00:00:25.860 --> 00:00:26.360
Perfect!

00:00:28.040 --> 00:00:28.850
I'm going to click on it.

00:00:30.040 --> 00:00:32.140
I'm going to wait until the workflow finishes.

00:00:32.170 --> 00:00:36.160
Remember, this was triggered because we merged code into the main branch.

00:00:36.840 --> 00:00:37.160
Nice!

00:00:37.160 --> 00:00:40.540
We see the green checkmark, so the script successfully executed.

00:00:40.790 --> 00:00:42.860
Let's click on this and drill in a little bit more.

00:00:44.340 --> 00:00:46.750
We see the Trivy installation was successful.

00:00:46.750 --> 00:00:49.070
We went ahead and logged into Docker Hub.

00:00:49.740 --> 00:00:52.350
Let's drill into Docker Registry Interactions.

00:00:53.240 --> 00:00:55.950
We see that this was the first time building this Docker image,

00:00:55.950 --> 00:00:58.830
thus we are skipping the integrity checks.

00:00:58.830 --> 00:01:01.480
Up here, we also see the push to Docker Hub.

00:01:01.790 --> 00:01:04.959
This is uploading the Docker image to the Docker registry.

00:01:05.640 --> 00:01:07.860
Let's go back into the main repo view.

00:01:12.740 --> 00:01:13.440
Oh, nice!

00:01:13.440 --> 00:01:16.570
We see the Security Bot updating Docker image signature.

00:01:16.880 --> 00:01:17.660
Let's check that out.

00:01:19.940 --> 00:01:22.770
This is the signature that is committed into the repo

00:01:22.780 --> 00:01:24.710
and is used for tampering checks.

00:01:24.900 --> 00:01:25.380
Nice!

00:01:25.390 --> 00:01:27.620
It looks like everything is working as we expected.

00:01:27.620 --> 00:01:28.630
At this point,

00:01:28.630 --> 00:01:32.060
we are going to go ahead and simulate Docker image tampering and

00:01:32.060 --> 00:01:34.660
see if our script picks up the malicious actions.

00:01:34.670 --> 00:01:37.880
Okay, let's go back to our main Docker file.

00:01:37.880 --> 00:01:41.490
Let's assume we are the attacker and we are trying to

00:01:41.500 --> 00:01:43.760
introduce a vulnerable Docker image.

00:01:44.540 --> 00:01:47.260
This version of Bash is vulnerable to shellshock.

00:01:47.640 --> 00:01:51.350
Shellshock is a critical vulnerability in Bash that could allow a

00:01:51.350 --> 00:01:54.970
remote attacker to execute arbitrary shell commands.

00:01:55.100 --> 00:01:58.110
I'm going to go ahead and un‑comment this vulnerability.

00:01:58.110 --> 00:01:58.650
Also,

00:01:58.650 --> 00:02:01.570
we're going to introduce a regular expression

00:02:01.570 --> 00:02:04.860
denial‑of‑service vulnerability through a Python package.

00:02:05.640 --> 00:02:07.350
Okay, we un‑comment that as well.

00:02:07.840 --> 00:02:10.919
Remember, the attacker can introduce any type of vulnerability,

00:02:10.919 --> 00:02:12.720
for example, a cryptominer.

00:02:12.720 --> 00:02:14.170
And just think about it.

00:02:14.180 --> 00:02:17.770
If thousands of servers download a Docker image that has a cryptominer,

00:02:17.990 --> 00:02:21.080
you can imagine how lucrative this would be for an attacker.

00:02:21.130 --> 00:02:23.460
Okay, I'm going to go ahead and save my changes.

00:02:24.440 --> 00:02:26.370
We buil tthe Docker image ourselves.

00:02:26.590 --> 00:02:29.990
In other words, we don't want to commit our changes into Git.

00:02:29.990 --> 00:02:34.100
This will probably get us caught by all the process we just implemented.

00:02:34.100 --> 00:02:37.750
Here we see that we give the Docker image the appropriate tag.

00:02:37.760 --> 00:02:40.050
This will allow us to upload our image to the

00:02:40.050 --> 00:02:42.260
appropriate repo within Docker Hub.

00:02:42.840 --> 00:02:46.050
So zachroofsec is the Docker Hub user,

00:02:46.050 --> 00:02:49.670
and trivy‑tutorial is the Docker Hub repo we are uploading to.

00:02:49.670 --> 00:02:51.640
Let's kick off this build.

00:02:51.640 --> 00:02:55.610
Before we upload this malicious image to the Docker registry,

00:02:55.610 --> 00:02:58.160
we need the Docker registry credentials.

00:02:58.640 --> 00:03:02.360
As an aside, the attacker can steal these credentials in many ways.

00:03:02.940 --> 00:03:04.730
For a sophisticated example,

00:03:04.760 --> 00:03:07.520
please see my Container Infrastructure Analysis with

00:03:07.520 --> 00:03:09.560
Kube‑hunter course here on Pluralsight.

00:03:10.040 --> 00:03:11.450
The link is in the course notes.

00:03:12.440 --> 00:03:14.560
Okay, we're going to proceed with the login.

00:03:15.440 --> 00:03:16.070
Perfect.

00:03:16.080 --> 00:03:17.360
Let's push it up to Docker Hub.

00:03:21.140 --> 00:03:21.860
Nice!

00:03:21.870 --> 00:03:23.630
It looks like the push was successful.

00:03:23.640 --> 00:03:26.860
Let's see if our automation will catch the Docker image tampering.

00:03:27.640 --> 00:03:30.660
I'm going to go ahead and re‑trigger the GitHub action.

00:03:30.660 --> 00:03:34.900
For the purposes of this demo, we'll manually re‑trigger our workflow.

00:03:34.950 --> 00:03:35.630
Remember,

00:03:35.640 --> 00:03:38.440
this can be triggered on a schedule by un‑commenting the

00:03:38.440 --> 00:03:40.760
schedule block within the workflow file.

00:03:44.940 --> 00:03:45.630
Oh wow!

00:03:45.640 --> 00:03:48.150
It looks like our script found the tampering.

00:03:48.460 --> 00:03:50.060
Let's dive in a little bit deeper.

00:03:52.440 --> 00:03:55.450
Okay, we see the 'investigation needs to occur' message.

00:03:55.450 --> 00:03:57.150
Obviously tampering was present.

00:04:00.340 --> 00:04:03.990
If you recall from our script logic, when tampering is present,

00:04:04.000 --> 00:04:07.050
we go ahead and run Trivy on the tampered image.

00:04:07.940 --> 00:04:11.260
Here we see that Trivy successfully found the regular expression

00:04:11.260 --> 00:04:14.470
denial‑of‑service that was added into the image,

00:04:14.480 --> 00:04:19.459
but notice that the shellshock vulnerability was not found.

00:04:19.839 --> 00:04:21.959
Let's quickly go back to our Docker file.

00:04:22.340 --> 00:04:25.470
Okay, at this point, we're going to go back to our original Docker file.

00:04:25.470 --> 00:04:28.760
Here we see the introduction of the shellshock vulnerability,

00:04:29.240 --> 00:04:30.390
but notice something.

00:04:30.480 --> 00:04:33.670
We are not installing this through a package manager.

00:04:33.770 --> 00:04:38.620
This is simply a make installation, and this leads us to a very important point.

00:04:38.630 --> 00:04:41.450
Trivy can only find vulnerable packages that are

00:04:41.450 --> 00:04:43.660
installed via a package manager.

00:04:44.140 --> 00:04:47.950
This is why we need at least one human to approve the pull request.

00:04:48.540 --> 00:04:49.200
In other words,

00:04:49.200 --> 00:04:53.170
an engineer might introduce a vulnerability that can't be scanned by Trivy.

00:04:53.940 --> 00:04:56.700
Let's go back to the output of the GitHub workflow.

00:04:56.730 --> 00:04:57.270
Okay,

00:04:57.280 --> 00:05:01.330
so we previously saw how Trivy found the Python vulnerability and how Trivy

00:05:01.330 --> 00:05:04.650
did not report on the Bash vulnerability or shellshock.

00:05:05.340 --> 00:05:09.360
How do we get a hint as to what the attacker installed in the new image?

00:05:10.140 --> 00:05:13.260
We can get a hint through Google's container‑diff tool.

00:05:13.640 --> 00:05:17.190
Google's container‑diff tool looks for differences between Docker

00:05:17.190 --> 00:05:20.810
images. Examples include file system changes,

00:05:20.960 --> 00:05:23.170
image size changes, etc.

00:05:23.240 --> 00:05:26.780
Take note that a very determined attacker could hide parts of

00:05:26.780 --> 00:05:28.960
their changes from the container‑diff tool.

00:05:29.440 --> 00:05:33.440
We'll see an example of this later on in the course. In general,

00:05:33.490 --> 00:05:36.900
no cybersecurity tool can monitor for all attacks.

00:05:37.020 --> 00:05:39.740
This includes Trivy and the container‑diff tool.

00:05:39.780 --> 00:05:44.960
However, this combination of tooling might give you hints as to what has changed.

00:05:45.540 --> 00:05:47.360
Let's go to the container‑diff output.

00:05:48.640 --> 00:05:51.810
In particular, we see changes related to Bash.

00:05:51.940 --> 00:05:54.880
This would be very helpful within an investigation.

00:05:55.010 --> 00:05:59.760
Remember, the shellshock vulnerability was predicated on this Bash change.

00:06:00.240 --> 00:06:02.550
Let's do a recap of what we've learned.

00:06:02.940 --> 00:06:07.050
We used GitHub Actions to upload a Docker image to the Docker registry.

00:06:08.140 --> 00:06:11.290
We also witnessed how Docker images can be rebuilt on a

00:06:11.290 --> 00:06:13.450
schedule to reduce vulnerabilities.

00:06:13.840 --> 00:06:17.380
Then we used GitHub Actions to expose Docker registry

00:06:17.380 --> 00:06:22.350
tampering, and then we analyzed the tampered Docker image with

00:06:22.350 --> 00:06:25.350
Trivy and Google's container‑diff tool.
