Aqua’s Team Nautilus detected an impressive campaign that set out to hijack resources to enable cryptocurrency mining. This operation focused on several SaaS software development environments, including Docker Hub, GitHub, Travis CI, and Circle CI, by abusing their automated build processes.
Fortunately, our research efforts occasionally include scanning images on Docker Hub using Aqua Dynamic Threat Analysis (DTA) and we were able to detect and investigate this campaign within hours of its initial launch. The affected service providers were then notified by our research team with details of this attack.
An Orchestrated “Blitz” Campaign
The infrastructure of this campaign consisted of 11 GitHub users who created 51 GitHub projects that were masquerading as popular software projects (such as nginx, okular, openssh, openvpn, seahorse, nautilus, zookeeper etc.). The adversary similarly created 56 Docker Hub accounts also using the names of popular software. All of this happened over the course of only a few hours. During the build process, these container images proceeded to download a cryptominer from a single GitHub repository. All 56 Docker Hub images were detected within a couple of hours after they were created. Based on these findings, a Team Nautilus researcher connected the dots to uncover the entire attack kill chain.
All the images were set to download the same binary file. This file — GCC — is marked as malicious by VirusTotal.
The adversary has named the binary “GCC” in order to disguise the PUA to a compiler system (The GNU Compiler Collection – GCC – is a compiler system that is a key component for most projects related to Linux, including the Linux kernel).
A New Modus Operandi for Cryptocurrency Attacks
Interestingly, the adversaries are abusing a fundamental service of GitHub, Docker Hub, Travis CI, and Circle CI. We’ve seen other container supply chain attacks that leverage public images in hopes of abusing the container runtime environment – but in this new campaign, the infrastructure of the build process itself is being abused.
The images are built on these service providers’ environments and then hijack their resources in order to mine cryptocurrency. The sophisticated build mechanism in the Dockerfile is as follows:
- Ubuntu base image is set.
/workdir
is defined as working directory.- CURL installation is verified.
- Using CURL, the binary GCC file (PUA) is downloaded from GitHub as well as a configuration file.
- The file
Docker.sh
is copied into the working directory and executed. This is what the fileDocker.sh
is doing:
- The binary GCC (the Cryptominer) is executed with the configuration file.
- While the miner is running the GitHub, the repository is cloned.
- Two files are randomly selected, and their content is replaced.
- A random commit message is submitted.
- The repository is pushed back to GitHub.
- PUA files are deleted.
- The file
git
is set in CMD.
When pulling and running the image it fails, since the CMD is instructing to run a JSON file with bash command.
Since these projects and container images were created, they each have committed thousands of code changes. Each commit is executing a build process by all of the above-mentioned services, and on each build, a cryptominer is executed. For three days, this campaign amassed over 23.3K commits in GitHub and 5.8K builds in Docker Hub, translating into ~30K Monero mining sessions. Currently, Docker Hub limits automated builds to a two-hour duration, which leaves the attackers plenty of time to abuse this feature.
It could be that the adversaries are trying to abuse this feature as much as they can. This campaign can easily be modified to attack innocent end-users (such as Developers, DevOps). If the adversaries change the CMD to execute the miner, this campaign can target anyone who downloads these images.
In Summary
This attack represents yet another example of the evolving creativity of adversaries. They are persistent in their pursuit of abusable cloud compute resources wherever they can get them. This is also a reminder that developer environments in the cloud are just as susceptible to attack as production environments, and sometimes more so because they are not getting the same level of security attention.
As always, we recommend that such environments have strict access controls, authentication, and least-privilege enforcement, but also continuous monitoring and restrictions on outbound network connections to prevent both data theft and resource abuse.
Indications of Compromise (IOCs)
11 Github Users | |||
https[:]//github[.]com/alisa-smirnova | |||
https[:]//github[.]com/amelia-popa | |||
https[:]//github[.]com/evgeny-vinogradov | |||
https[:]//github[.]com/matias-garcia-projectmanager | |||
https[:]//github[.]com/olafur-berndsen | |||
https[:]//github[.]com/oliver-ward | |||
https[:]//github[.]com/rawiri-martin | |||
https[:]//github[.]com/sophie-zhang-accountant | |||
https[:]//github[.]com/tom-muller | |||
https[:]//github[.]com/william-jonsson | |||
https[:]//github[.]com/markel-sanz | |||
56 Docker Hub accounts | |||
hub.docker.com/r/digitaltelegramdesktopi/telegram-desktop/builds | |||
hub.docker.com/r/gnatlinki/gnat/builds | |||
hub.docker.com/r/nginxclearr/nginx/builds | |||
hub.docker.com/r/waylandfreex/wayland/builds | |||
hub.docker.com/r/majawozniakx/babl/builds | |||
hub.docker.com/r/dovecotbugfixb/dovecot/builds | |||
hub.docker.com/r/okularrustz/okular/builds | |||
hub.docker.com/r/zookeeperprimaryr/zookeeper/builds | |||
hub.docker.com/r/kristiandimitrovz/mc/builds | |||
hub.docker.com/r/bugfixxena/xen/builds | |||
hub.docker.com/r/fontforgeshv/fontforge/builds | |||
hub.docker.com/r/ameliapopaf/mosquitto/builds | |||
hub.docker.com/r/x64stracea/strace/builds | |||
hub.docker.com/r/cupsforka/cups/builds | |||
hub.docker.com/r/oliverwardi/ghc/builds | |||
hub.docker.com/r/advsqlitebrowserz/sqlitebrowser/builds | |||
hub.docker.com/r/sqlitemuxv/sqlite/builds | |||
hub.docker.com/r/lincgdbr/cgdb/builds | |||
hub.docker.com/r/gegltrued/gegl/builds | |||
hub.docker.com/r/packseahorseb/seahorse/builds | |||
hub.docker.com/r/comgitta/git/builds | |||
hub.docker.com/r/bugfixedpostgresqlcommx/postgresql-common/builds | |||
hub.docker.com/r/jetgnatz/gnat/builds | |||
hub.docker.com/r/vimsilveri/vim/builds | |||
hub.docker.com/r/geglrusti/gegl/builds | |||
hub.docker.com/r/licbashf/bash/builds | |||
hub.docker.com/r/shellpopplerf/poppler/builds | |||
hub.docker.com/r/sqlitebrowseradvf/sqlitebrowser/builds | |||
hub.docker.com/r/evinceprimer/evince/builds | |||
hub.docker.com/r/x86binwalkr/binwalk/builds | |||
hub.docker.com/r/advancedgnomecolormanb/gnome-color-manager/builds | |||
hub.docker.com/r/evgenyvinogradovb/systemd/builds | |||
hub.docker.com/r/musladvancedr/musl/builds | |||
hub.docker.com/r/okularprimaryr/okular/builds | |||
hub.docker.com/r/olafurberndsenr/openssh/builds | |||
hub.docker.com/r/rawirimartinv/evince/builds | |||
hub.docker.com/r/portablepulseaudioa/pulseaudio/builds | |||
hub.docker.com/r/tommullern/libjpeg-turbo/builds | |||
hub.docker.com/r/forkedcupsn/cups/builds | |||
hub.docker.com/r/freemusln/musl/builds | |||
hub.docker.com/r/largemcn/mc/builds | |||
hub.docker.com/r/shsyslogngn/syslog-ng/builds | |||
hub.docker.com/r/muxsyslogngb/syslog-ng/builds | |||
hub.docker.com/r/binwalkforkedf/binwalk/builds | |||
hub.docker.com/r/flosscairov/cairo/builds | |||
hub.docker.com/r/rcnautilusa/nautilus/builds | |||
hub.docker.com/r/zookeeperx64b/zookeeper/builds | |||
hub.docker.com/r/cmpeogp/eog/builds | |||
hub.docker.com/r/fontforgecommonr/fontforge/builds | |||
hub.docker.com/r/matiasgarciab/seahorse/builds | |||
hub.docker.com/r/sophiezhanga/cairo/builds | |||
hub.docker.com/r/openvpnlinkp/openvpn/builds | |||
hub.docker.com/r/bablx8664l/babl/builds | |||
hub.docker.com/r/cmddbusl/dbus/builds | |||
hub.docker.com/r/ffmpeglicl/ffmpeg/builds | |||
hub.docker.com/r/licgittl/git/builds | |||
51 GitHub Repositories | |||
https://github.com/goldendict-lib/goldendict | |||
https://github.com/int-mpv/mpv | |||
https://github.com/large-mc/mc | |||
https://github.com/lic-bash/bash | |||
https://github.com/lin-cgdb/cgdb | |||
https://github.com/musl-advanced/musl | |||
https://github.com/mux-syslog-ng/syslog-ng | |||
https://github.com/nginx-beautiful/nginx | |||
https://github.com/nginx-clear/nginx | |||
https://github.com/okular-primary/okular | |||
https://github.com/openvpn-link/openvpn | |||
https://github.com/openvpn-link/openvpn | |||
https://github.com/pack-seahorse/seahorse | |||
https://github.com/portable-pulseaudio/pulseaudio | |||
https://github.com/rc-nautilus/nautilus | |||
https://github.com/sh-syslog-ng/syslog-ng | |||
https://github.com/shell-poppler/poppler | |||
https://github.com/sqlite-mux/sqlite | |||
https://github.com/sqlitebrowser-adv/sqlitebrowser | |||
https://github.com/sqlitebrowser-adv/sqlitebrowser | |||
https://github.com/vim-silver/vim | |||
https://github.com/wayland-adv/wayland | |||
https://github.com/x86-binwalk/binwalk | |||
https://github.com/zookeeper-x64/zookeeper | |||
https://github.com/licgitt/git | |||
https://github.com/alisa-smirnova/cgdb | |||
https://github.com/amelia-popa/mosquitto | |||
https://github.com/evgeny-vinogradov/systemd | |||
https://github.com/matias-garcia-projectmanager/seahorse | |||
https://github.com/olafur-berndsen/openssh | |||
https://github.com/oliver-ward/ghc | |||
https://github.com/rawiri-martin/evince | |||
https://github.com/william-jonsson/eog |