Hunting for Insecure Docker Registries

Developer teams love and use Docker and container’s stuff. So there are a lot of tools and projects about efficiently using it.

So, meet with Docker Registry!

If you used Docker someday, with the big possibility you used Registry. Good known Docker Registry is Docker Hub. It is used by many open-source projects. Why use it?

Here you can find official documentation. It says:

You should use the Registry if you want to:
- tightly control where your images are being stored
- fully own your images distribution pipeline
- integrate image storage and distribution tightly into your in-house development workflow

Therefore, it’s a storage of Docker images. If you used Docker, you know that the image contains your application. In other words — your code (first of all, I’m talking about web applications — Docker is used for PHP, Java, Python web apps). So, if you have access to images from Registry — you have access to the source code.

What is wrong?

Okay, someone deployed Registry for private usage and stored his images. Where is the problem?

Here you can know what protocol is used by the registry. It’s HTTP API.

Here you can find information about deploying Registries. Do you see the topic of security deploying? First, we see something about TLS. Okay, it’s important, but what about authentication in Registry? Below is the documentation, we see a topic “Restricting access”. But this topic is almost the last😨 Do you understand my mind?

If the administrator didn’t read the documentation properly — Docker Registry will be deployed without authentication. Everyone who knows about your Registry can access your images and code. It’s a good attack vector with a good impact — disclosing source code.

Let’s start hunting!

I wanted to find Docker Registries on the Internet and check its authentication mechanism. But how do it?

Searching for 5000 port is not efficient. Someone deploy it on other ports. Let’s deploy our instance for searching fingerprints.

Example of connection to a local instance

Docker Registry’s fingerprint is Docker-Distribution-Api-Version header. I used this fingerprint for an initial search with Shodan. I have a Developer account in Shodan and I used Shodan API.

Shodan results

The second phase is checking — does registry have authentication or not? Let’s look at the documentation about Docker registry API. For checking I used this path:

Registry HTTP API method description

Okay, it’s time to write a simple script that will do those things:

  1. Create a query to Shodan API to find header: Docker-Distribution-API-Version
  2. Parse results
  3. Try to connect to hosts from the results
  4. Try to connect to Registry API endpoint: /v2/_catalog
  5. Save results for each host

Finds

I scanned hosts from the Shodan query’s result and got something. If you want some statistics (even if you don’t want😀) there is:

We found 94 open Docker Registries. The next step is researching what repositories of Registries contain.

Many of that contain not interesting for me repositories:

Useless finds

But something was interesting… 🤔

Give me more source code of apps!
Give me more source code of apps!

Now we can download something’s images with applications and get the code:

curl https://registry.example.com/v2/<image_name>/tags/list
docker pull https://registry.example.com:443/<image_name>:<tag>

Now we have an image and can inspect it. Let’s run it and inspect filesystem:

Manifest of one of the app

I have notified owners of Registries about my finds. Someone paid a bounty, others were ignoring me, but have closed the Registries without any thanks🤨

Bounty earned

So, Registry hunting was a good time spending😉 Thanks for reading!