What is docker machine?

Docker machine was a cool project started in 2014 by Docker which allowed managing remote virtual machines on different providers like AWS, Rackspace and also using drivers like openstack to support managing virtual machines on self-hosted deployments. The primary feature was to automatically install docker on remote hosts and configure docker client to connect to them using docker api (it automagically managed tls certificates, authentication etc.).

It creates servers, installs Docker on them, then configures the Docker client to talk to them. (from project’s readme)

You can read more on this in another post I wrote about autoscaling and docker-machine.

So what is wrong with docker-machine?

It has been deprecated and is sort-of maintained by Gitlab alone to support existing autoscaling workloads.

A concrete weakness that I found out is reliance of docker-machine on worker nodes (virtual machines it manages) to provide it with information like docker version running on that virtual machine.

e.g.

$ docker-machine ls
NAME                       ACTIVE   DRIVER      STATE     URL                     SWARM   DOCKER    ERRORS
worker-node-id             -        virtualbox  Running   tcp://10.1.0.128:2376           v24.0.2

Meet escape sequences

Escape sequences are special sequences of characters which are used for things like cursor styling, font colors etc. in terminals.

It is possible to inject such sequences in the docker version information by the worker nodes. docker-machine happily renders these into the terminal.

Here is an example of malicious docker daemon which would respond with a benign escape sequence to the query of docker-machine: vin01/bad-moby

There is no better reference to analysis of such attacks than the one by HD Moore. Quite a few attack vectors are still valid today and easy to exploit. I intend to write more on this in a different post.

Attack vectors

Utilization of docker-machine for isolation of CI/CD jobs in Gitlab or any other provider.

Since docker-machine is still the tool of choice for achieving autoscaling using Gitlab, relying on it to run CI/CD jobs in isolated worker virtual machines is a natural approach. With untrustworthy output, a malicious worker node can trick the administrator or automation tool into doing something they would otherwise not do.

PoC escape sequence injection

Denial of service

It is possible to inject not just escape sequences but any arbitrary data which could also include an infinite stream of bytes. Result: a crashed docker-machine bastion node + worker nodes.

Note: Gitlab is aware of it but the use-case of isolation (as one would expect from a virtual machine management tool) is not really the core feature of docker-machine by design and also they intend to move away from it, so for now, there is no plan to patch it.