top of page
  • BlueDolphin

Docker Registry Enumeration

Register file structure

Let's quickly break down the layers of the Docker registry starting from the top and working all the way down to the configuration file known as the manifest.


1. Docker Registry

2. Catalog

3. Repository

4. Tags

5. Manifest


Commands used

Below are a list of the commands found in the below commands that are not specific to this registry, but generic terms.


v2 = to specify the API

_catalog = to call the catalog

GET = Makes a HTTP GET request

tags/list = list tags found within repository

manifests = lists known manifests


Scanning the registry with NMAP

When enumerating Docker Containers we can leverage a basic nmap scan with version checking that can detect the use of Docker on a target host should it be running.

We can observe the following as seen in the screenshot below:


Port 5000 and 7000

Service: HTTP

Version: Docker Registry API 2.0


Repository enumeration

Docker registries are not web based and therefore rely on JSON which means we cannot simply browse to the registry from our internet browser but instead have to leverage finished products such as Postman or Insomnia. However using the terminal or BurpSuite can work as well.


1. Sending a basic GET Query to a Docker Registry


The below GET request is the most basic type of request where we are querying the catalog with the V2 API, looking for what Repositories are available to us within this docker sever.


1. Basic catalog GET Query

GET http://docker-rodeo.thm:5000/v2/_catalog 

1. Basic catalog GET Response of available repositories

{"repositories":["cmnatic/myapp1","dive/challenge","dive/example"]}

2. Querying the repository for identification tags

Once we know the repository name, we will check what tags are available. Tags are like configuration setups for various images. A tag or label serves as a way to differentiate Docker images based on various settings and configurations, such as operating system, dependencies or application code. Quite often the tag will present itself as V1, V2, V3, or test, dev and prod, so on and so forth.

Docker pull mywebapp:v7.2 - Dev

This will download the application version 7.2 - Dev


Repository tags can be updated with

docker tag
docker push


2. GET Query for repository tags

GET http://docker-rodeo.thm:5000/v2/cmnatic/myapp1/tags/list 

2. GET response for repository tags

{
"name":"cmnatic/myapp1",
"tags":["notsecure","latest","secured"]
}

3. Look for a Manifest File

The Docker manifest file is a JSON file which outlines the content of a Docker image manifest which can be thought of as a meta data file that contains configurations and architecture information. You can find the architecture system, operating system, entry points, versions, environment paths. version history and much more.


3. GET request for repository manifest file

GET http://docker-rodeo.thm:5000/v2/cmnatic/myapp1/manifests/notsecure

3. GET response for repository manifest file


{

"schemaVersion": 1,

"name": "cmnatic/myapp1",

"tag": "notsecure",

"architecture": "amd64",

"fsLayers": [

{

"blobSum": "sha256:6e9b6055dfc50d2c85f1d56a61686f0f155632ed00eb484f2faae99fcdde9bee"

},

{

"blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"

},

{

"blobSum": "sha256:4429b8d1a27b563a13bea19a39dc9cda477b77bb94dcf95236b80bfaeaddd4b9"

}

],

"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\":[\"bash\"],\"ArgsEscaped\":true,\"Image\":\"sha256:bb3ff36f9b5eb9f8f32cf0584acac540428c04e7aa6fc20dbaca1b2380411d75\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":null},\"container\":\"52cf98d7eb6aa25be283eebcffbd897ed31b386258497bf1132f4fbeb5e033a1\",\"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\",\"echo \\\"thm{here_have_a_flag}\\\" \\u003e /root/root.txt\"],\"Image\":\"sha256:bb3ff36f9b5eb9f8f32cf0584acac540428c04e7aa6fc20dbaca1b2380411d75\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":null},\"created\":\"2020-10-24T19:32:51.335770476Z\",\"docker_version\":\"19.03.13\",\"id\":\"236e40b3b1f018782604f78df6557d6ad47ac3cb8ad36342ea9cac06225b5262\",\"os\":\"linux\",\"parent\":\"983e6c996aa7d6ff7492f8f57be975e997180bf809ec193b173dcea4f9f97cd6\"}"

},

{

"v1Compatibility": "{\"id\":\"983e6c996aa7d6ff7492f8f57be975e997180bf809ec193b173dcea4f9f97cd6\",\"parent\":\"63555f783d1f8c6b12ed383963261c7d9693ceef04580944c103167117503219\",\"created\":\"2020-10-13T01:40:01.167771798Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) CMD [\\\"bash\\\"]\"]},\"throwaway\":true}"

},

{

"v1Compatibility": "{\"id\":\"63555f783d1f8c6b12ed383963261c7d9693ceef04580944c103167117503219\",\"created\":\"2020-10-13T01:40:00.890033494Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:ce4857398d963428cc93cbf7215159279fc5be5f51713a4637fb734be1c438b4 in / \"]}}"

}

],

"signatures": [

{

"header": {

"jwk": {

"crv": "P-256",

"kid": "GOC6:GBKI:JMPJ:GA43:TONO:2Q6G:RUBX:MUT7:XZJI:LSBE:3MQN:VIYP",

"kty": "EC",

"x": "ujTZznca2jlNVFaawsjJG5aakJkLSM-MnCoIVw7A97c",

"y": "jjfjdoi8QIezcf-v6R-pv1AubI-sc_LiGCXaClLaS98"

},

"alg": "ES256"

},

"signature": "_b4gqw5ZZwkTzzN6AKk2v2E3vvCS2MQvI31pJkKJmtopEY85iGptjAFFOHsSkWCPr8nA1uMPHVtRhJnxz463dg",

"protected": "eyJmb3JtYXRMZW5ndGgiOjI1NzAsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAyMy0wNS0wN1QxOTo1OToyOVoifQ"

}

]



Doing some Try Hack Me Challenge Questions

First, a quick visual of the Docker architecture layers always helps me when dealing with docker. Let us also do some quick enumeration on the second docker repository, before we dive into the questions.


1. Docker Registry = docker-rodeo.thm:7000

2. Catalog = _catalog

3. Repository = securesolutions/webserver

4. Repo Tags = production

5. Manifest =


Query the catalog

GET http://docker-rodeo.thm:7000/v2/_catalog 

{"repositories":["securesolutions/webserver"]}

Query the tags list

GET http://docker-rodeo.thm:7000/v2/securesolutions/webserver/tags/list
{"name":"securesolutions/webserver","tags":["production"]}


Query the manifests

GET http://docker-rodeo.thm:7000/v2/securesolutions/webserver/manifests/production

{

"schemaVersion": 1,

"name": "securesolutions/webserver",

"tag": "production",

"architecture": "amd64",

"fsLayers": [

{

"blobSum": "sha256:7a668bba7a1a84d9db8a2fb2826f777e64233780a110041db8d42b797515cf57"

},

{

"blobSum": "sha256:bc4544ab6267aaf520480ea4cc98e3169d252eab631801ef199b1ded807f306d"

},

{

"blobSum": "sha256:07813898d5e66ad253cf5bb594a47c6963a75412ee3562d212d3bc1e896ad62f"

},

{

"blobSum": "sha256:fdbb44f75d5b29f06c779f6eec33e886d165053275497583a150c9c2b444f3af"

},

{

"blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"

},

{

"blobSum": "sha256:bb79b6b2107fea8e8a47133a660b78e3a546998fcf0427be39ac9a0af4a97e90"

}

],

"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\":[\"bash\"],\"ArgsEscaped\":true,\"Image\":\"sha256:1e4a2d11384ed8ac500f2762825c3f3d134ad5d78813a5d044357b66d4c91800\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":null},\"container\":\"72913ee3dc1d3bf6af92d8412b87a5803f04f7088ba7a8a4d8baf2de9078300d\",\"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\",\"printf \\\"Username: admin\\\\nPassword: production_admin\\\\n\\\" \\u003e /var/www/html/database.config\"],\"Image\":\"sha256:1e4a2d11384ed8ac500f2762825c3f3d134ad5d78813a5d044357b66d4c91800\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"OnBuild\":null,\"Labels\":null},\"created\":\"2020-10-24T19:48:37.160476683Z\",\"docker_version\":\"19.03.13\",\"id\":\"7b05b529c51e9322588fe7ef7e9be250681641b9f207900c035a26abc2b7eac2\",\"os\":\"linux\",\"parent\":\"a3531d00ed14133152959cb0bc77cb214a65638bb5e295f0a57262049f56add3\"}"

},

{

"v1Compatibility": "{\"id\":\"a3531d00ed14133152959cb0bc77cb214a65638bb5e295f0a57262049f56add3\",\"parent\":\"a64c6dae778e931d83b59934a5b58f97b85e09c743ed1b18cb053ca0ecd2c58a\",\"created\":\"2020-10-24T19:48:36.298388069Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) COPY file:2c21f1c2caced37ec7c49be85e912509576e3aa6c68101bc90d3f56ae682b19c in /var/www/html/database.config \"]}}"

},

{

"v1Compatibility": "{\"id\":\"a64c6dae778e931d83b59934a5b58f97b85e09c743ed1b18cb053ca0ecd2c58a\",\"parent\":\"2f585dc1662c7b0b99f93dfea45dd83e4b2bebdbf3e470c01e0569b941cb2cea\",\"created\":\"2020-10-24T19:48:36.007380392Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c mkdir -p /var/www/html/\"]}}"

},

{

"v1Compatibility": "{\"id\":\"2f585dc1662c7b0b99f93dfea45dd83e4b2bebdbf3e470c01e0569b941cb2cea\",\"parent\":\"3a41447eea9358b0bfca1df658a78a9fcfe2f8281da222f9bea7a70e2dc0a03c\",\"created\":\"2020-10-24T19:46:44.83701677Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c apt-get update -y\"]}}"

},

{

"v1Compatibility": "{\"id\":\"3a41447eea9358b0bfca1df658a78a9fcfe2f8281da222f9bea7a70e2dc0a03c\",\"parent\":\"5bd584b8f9464a6553e557ab0eceb484a63e77ab1b552c05eab75eeedde7c6d0\",\"created\":\"2020-10-13T01:39:05.467867564Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) CMD [\\\"bash\\\"]\"]},\"throwaway\":true}"

},

{

"v1Compatibility": "{\"id\":\"5bd584b8f9464a6553e557ab0eceb484a63e77ab1b552c05eab75eeedde7c6d0\",\"created\":\"2020-10-13T01:39:05.233816802Z\",\"container_config\":{\"Cmd\":[\"/bin/sh -c #(nop) ADD file:0dc53e7886c35bc21ae6c4f6cedda54d56ae9c9e9cd367678f1a72e68b3c43d4 in / \"]}}"

}

],

"signatures": [

{

"header": {

"jwk": {

"crv": "P-256",

"kid": "ZBXR:VPVY:IQXJ:LRWV:BV2J:JWOW:IEJ7:J7PI:37SX:MNWV:FRPI:F7FA",

"kty": "EC",

"x": "n86f6YdC2bwUfa3eqCwA4BYuhcH_lZomSX4QwhyyXwc",

"y": "D8P2sbNgtDzTBVbpeL2u-TIKR6rEXPnam7CFHx04bMM"

},

"alg": "ES256"

},

"signature": "7scGL5Cf9wc5yoBtnTJ9l4fFBLUP6if1pKEH7KM_8vDzVyzhtI9JgbYNt2LWe_dFH3HiUx6Ud2hffQ2yY6gEtg",

"protected": "eyJmb3JtYXRMZW5ndGgiOjQwMTksImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAyMy0wNS0wN1QyMDozNzoyOVoifQ"

}

]


What is the port number of the 2nd Docker registry?

7000


What is the name of the repository within this registry

securesolutions/webserver


What is the name of the tag that has been published?

production


What is the username in the database configuration?

admin


What is the password in the database configuration

production_admin




142 views0 comments

Recent Posts

See All

Comentários


bottom of page